Merge "Throw errors on failures to set system properties."
diff --git a/api/current.xml b/api/current.xml
index 422522e..eaa750e 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -28643,6 +28643,17 @@
visibility="public"
>
</method>
+<method name="dismissAllowingStateLoss"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getDialog"
return="android.app.Dialog"
abstract="false"
@@ -28850,7 +28861,7 @@
deprecated="not deprecated"
visibility="public"
>
-<method name="completedDownload"
+<method name="addCompletedDownload"
return="long"
abstract="false"
native="false"
@@ -94415,6 +94426,17 @@
visibility="public"
>
</method>
+<method name="getDescription"
+ return="java.lang.String"
+ 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"
@@ -94437,7 +94459,7 @@
visibility="public"
>
</method>
-<method name="getType"
+<method name="getUri"
return="java.lang.String"
abstract="false"
native="false"
@@ -94869,82 +94891,12 @@
extends="java.lang.Object"
abstract="false"
static="false"
- final="true"
+ final="false"
deprecated="not deprecated"
visibility="public"
>
<implements name="android.os.Parcelable">
</implements>
-<method name="bulkTransfer"
- return="int"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="endpoint" type="android.hardware.usb.UsbEndpoint">
-</parameter>
-<parameter name="buffer" type="byte[]">
-</parameter>
-<parameter name="length" type="int">
-</parameter>
-<parameter name="timeout" type="int">
-</parameter>
-</method>
-<method name="claimInterface"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="intf" type="android.hardware.usb.UsbInterface">
-</parameter>
-<parameter name="force" type="boolean">
-</parameter>
-</method>
-<method name="close"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="controlTransfer"
- return="int"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="requestType" type="int">
-</parameter>
-<parameter name="request" type="int">
-</parameter>
-<parameter name="value" type="int">
-</parameter>
-<parameter name="index" type="int">
-</parameter>
-<parameter name="buffer" type="byte[]">
-</parameter>
-<parameter name="length" type="int">
-</parameter>
-<parameter name="timeout" type="int">
-</parameter>
-</method>
<method name="describeContents"
return="int"
abstract="false"
@@ -95037,17 +94989,6 @@
visibility="public"
>
</method>
-<method name="getFileDescriptor"
- return="int"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
<method name="getInterface"
return="android.hardware.usb.UsbInterface"
abstract="false"
@@ -95083,17 +95024,6 @@
visibility="public"
>
</method>
-<method name="getSerial"
- return="java.lang.String"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
<method name="getVendorId"
return="int"
abstract="false"
@@ -95105,30 +95035,6 @@
visibility="public"
>
</method>
-<method name="releaseInterface"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="intf" type="android.hardware.usb.UsbInterface">
-</parameter>
-</method>
-<method name="requestWait"
- return="android.hardware.usb.UsbRequest"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
<method name="writeToParcel"
return="void"
abstract="false"
@@ -95155,11 +95061,136 @@
>
</field>
</class>
+<class name="UsbDeviceConnection"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="bulkTransfer"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="endpoint" type="android.hardware.usb.UsbEndpoint">
+</parameter>
+<parameter name="buffer" type="byte[]">
+</parameter>
+<parameter name="length" type="int">
+</parameter>
+<parameter name="timeout" type="int">
+</parameter>
+</method>
+<method name="claimInterface"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="intf" type="android.hardware.usb.UsbInterface">
+</parameter>
+<parameter name="force" type="boolean">
+</parameter>
+</method>
+<method name="close"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="controlTransfer"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="requestType" type="int">
+</parameter>
+<parameter name="request" type="int">
+</parameter>
+<parameter name="value" type="int">
+</parameter>
+<parameter name="index" type="int">
+</parameter>
+<parameter name="buffer" type="byte[]">
+</parameter>
+<parameter name="length" type="int">
+</parameter>
+<parameter name="timeout" type="int">
+</parameter>
+</method>
+<method name="getFileDescriptor"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSerial"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="releaseInterface"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="intf" type="android.hardware.usb.UsbInterface">
+</parameter>
+</method>
+<method name="requestWait"
+ return="android.hardware.usb.UsbRequest"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+</class>
<class name="UsbEndpoint"
extends="java.lang.Object"
abstract="false"
static="false"
- final="true"
+ final="false"
deprecated="not deprecated"
visibility="public"
>
@@ -95198,17 +95229,6 @@
visibility="public"
>
</method>
-<method name="getDevice"
- return="android.hardware.usb.UsbDevice"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
<method name="getDirection"
return="int"
abstract="false"
@@ -95231,17 +95251,6 @@
visibility="public"
>
</method>
-<method name="getInterface"
- return="android.hardware.usb.UsbInterface"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
<method name="getInterval"
return="int"
abstract="false"
@@ -95322,17 +95331,6 @@
visibility="public"
>
</method>
-<method name="getDevice"
- return="android.hardware.usb.UsbDevice"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
<method name="getEndpoint"
return="android.hardware.usb.UsbEndpoint"
abstract="false"
@@ -95457,30 +95455,30 @@
visibility="public"
>
</method>
-<method name="isFunctionEnabled"
+<method name="hasPermission"
return="boolean"
abstract="false"
native="false"
synchronized="false"
- static="true"
+ static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
-<parameter name="function" type="java.lang.String">
+<parameter name="device" type="android.hardware.usb.UsbDevice">
</parameter>
</method>
-<method name="isFunctionSupported"
+<method name="hasPermission"
return="boolean"
abstract="false"
native="false"
synchronized="false"
- static="true"
+ static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
-<parameter name="function" type="java.lang.String">
+<parameter name="accessory" type="android.hardware.usb.UsbAccessory">
</parameter>
</method>
<method name="openAccessory"
@@ -95497,7 +95495,7 @@
</parameter>
</method>
<method name="openDevice"
- return="boolean"
+ return="android.hardware.usb.UsbDeviceConnection"
abstract="false"
native="false"
synchronized="false"
@@ -95509,6 +95507,36 @@
<parameter name="device" type="android.hardware.usb.UsbDevice">
</parameter>
</method>
+<method name="requestPermission"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="device" type="android.hardware.usb.UsbDevice">
+</parameter>
+<parameter name="pi" type="android.app.PendingIntent">
+</parameter>
+</method>
+<method name="requestPermission"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="accessory" type="android.hardware.usb.UsbAccessory">
+</parameter>
+<parameter name="pi" type="android.app.PendingIntent">
+</parameter>
+</method>
<field name="ACTION_USB_ACCESSORY_ATTACHED"
type="java.lang.String"
transient="false"
@@ -95553,17 +95581,6 @@
visibility="public"
>
</field>
-<field name="ACTION_USB_STATE"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value=""android.hardware.usb.action.USB_STATE""
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="EXTRA_ACCESSORY"
type="java.lang.String"
transient="false"
@@ -95586,99 +95603,11 @@
visibility="public"
>
</field>
-<field name="USB_CONFIGURATION"
+<field name="EXTRA_PERMISSION_GRANTED"
type="java.lang.String"
transient="false"
volatile="false"
- value=""configuration""
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="USB_CONNECTED"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value=""connected""
- static="true"
- final="true"
- deprecated="not deprecated"
- 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"
- volatile="false"
- value=""adb""
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="USB_FUNCTION_DISABLED"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value=""disabled""
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="USB_FUNCTION_ENABLED"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value=""enabled""
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="USB_FUNCTION_MASS_STORAGE"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value=""mass_storage""
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="USB_FUNCTION_MTP"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value=""mtp""
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="USB_FUNCTION_RNDIS"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value=""rndis""
+ value=""permission""
static="true"
final="true"
deprecated="not deprecated"
@@ -95756,6 +95685,8 @@
deprecated="not deprecated"
visibility="public"
>
+<parameter name="connection" type="android.hardware.usb.UsbDeviceConnection">
+</parameter>
<parameter name="endpoint" type="android.hardware.usb.UsbEndpoint">
</parameter>
</method>
@@ -105768,6 +105699,17 @@
visibility="public"
>
</field>
+<field name="METADATA_KEY_BITRATE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="20"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="METADATA_KEY_CD_TRACK_NUMBER"
type="int"
transient="false"
@@ -105845,6 +105787,28 @@
visibility="public"
>
</field>
+<field name="METADATA_KEY_HAS_AUDIO"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="METADATA_KEY_HAS_VIDEO"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="17"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="METADATA_KEY_MIMETYPE"
type="int"
transient="false"
@@ -105878,6 +105842,28 @@
visibility="public"
>
</field>
+<field name="METADATA_KEY_VIDEO_HEIGHT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="19"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="METADATA_KEY_VIDEO_WIDTH"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="18"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="METADATA_KEY_WRITER"
type="int"
transient="false"
@@ -112529,255 +112515,6 @@
</package>
<package name="android.mtp"
>
-<class name="MtpClient"
- extends="java.lang.Object"
- abstract="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<constructor name="MtpClient"
- type="android.mtp.MtpClient"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="context" type="android.content.Context">
-</parameter>
-</constructor>
-<method name="addListener"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="listener" type="android.mtp.MtpClient.Listener">
-</parameter>
-</method>
-<method name="close"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="deleteObject"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="deviceName" type="java.lang.String">
-</parameter>
-<parameter name="objectHandle" type="int">
-</parameter>
-</method>
-<method name="getDevice"
- return="android.mtp.MtpDevice"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="deviceName" type="java.lang.String">
-</parameter>
-</method>
-<method name="getDevice"
- return="android.mtp.MtpDevice"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="id" type="int">
-</parameter>
-</method>
-<method name="getDeviceList"
- return="java.util.List<android.mtp.MtpDevice>"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getObject"
- return="byte[]"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="deviceName" type="java.lang.String">
-</parameter>
-<parameter name="objectHandle" type="int">
-</parameter>
-<parameter name="objectSize" type="int">
-</parameter>
-</method>
-<method name="getObjectInfo"
- return="android.mtp.MtpObjectInfo"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="deviceName" type="java.lang.String">
-</parameter>
-<parameter name="objectHandle" type="int">
-</parameter>
-</method>
-<method name="getObjectList"
- return="java.util.List<android.mtp.MtpObjectInfo>"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="deviceName" type="java.lang.String">
-</parameter>
-<parameter name="storageId" type="int">
-</parameter>
-<parameter name="objectHandle" type="int">
-</parameter>
-</method>
-<method name="getStorageList"
- return="java.util.List<android.mtp.MtpStorageInfo>"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="deviceName" type="java.lang.String">
-</parameter>
-</method>
-<method name="getThumbnail"
- return="byte[]"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="deviceName" type="java.lang.String">
-</parameter>
-<parameter name="objectHandle" type="int">
-</parameter>
-</method>
-<method name="importFile"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="deviceName" type="java.lang.String">
-</parameter>
-<parameter name="objectHandle" type="int">
-</parameter>
-<parameter name="destPath" type="java.lang.String">
-</parameter>
-</method>
-<method name="isCamera"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="device" type="android.hardware.usb.UsbDevice">
-</parameter>
-</method>
-<method name="removeListener"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="listener" type="android.mtp.MtpClient.Listener">
-</parameter>
-</method>
-</class>
-<interface name="MtpClient.Listener"
- abstract="true"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<method name="deviceAdded"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="device" type="android.mtp.MtpDevice">
-</parameter>
-</method>
-<method name="deviceRemoved"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="device" type="android.mtp.MtpDevice">
-</parameter>
-</method>
-</interface>
<class name="MtpConstants"
extends="java.lang.Object"
abstract="false"
@@ -113612,7 +113349,7 @@
<parameter name="objectHandle" type="int">
</parameter>
</method>
-<method name="getStorageID"
+<method name="getStorageId"
return="long"
abstract="false"
native="false"
@@ -113687,7 +113424,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="manager" type="android.hardware.usb.UsbManager">
+<parameter name="connection" type="android.hardware.usb.UsbDeviceConnection">
</parameter>
</method>
</class>
@@ -118085,6 +117822,497 @@
</field>
</class>
</package>
+<package name="android.net.rtp"
+>
+<class name="AudioCodec"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="getCodec"
+ return="android.net.rtp.AudioCodec"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="type" type="int">
+</parameter>
+<parameter name="rtpmap" type="java.lang.String">
+</parameter>
+<parameter name="fmtp" type="java.lang.String">
+</parameter>
+</method>
+<method name="getCodecs"
+ return="android.net.rtp.AudioCodec[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<field name="AMR"
+ type="android.net.rtp.AudioCodec"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="GSM"
+ type="android.net.rtp.AudioCodec"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="GSM_EFR"
+ type="android.net.rtp.AudioCodec"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="PCMA"
+ type="android.net.rtp.AudioCodec"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="PCMU"
+ type="android.net.rtp.AudioCodec"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="fmtp"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="rtpmap"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="type"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="AudioGroup"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="AudioGroup"
+ type="android.net.rtp.AudioGroup"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<method name="clear"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getMode"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getStreams"
+ return="android.net.rtp.AudioStream[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="sendDtmf"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="event" type="int">
+</parameter>
+</method>
+<method name="setMode"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="mode" type="int">
+</parameter>
+</method>
+<field name="MODE_ECHO_SUPPRESSION"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="MODE_MUTED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="MODE_NORMAL"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="MODE_ON_HOLD"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="AudioStream"
+ extends="android.net.rtp.RtpStream"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="AudioStream"
+ type="android.net.rtp.AudioStream"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="address" type="java.net.InetAddress">
+</parameter>
+<exception name="SocketException" type="java.net.SocketException">
+</exception>
+</constructor>
+<method name="getCodec"
+ return="android.net.rtp.AudioCodec"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getDtmfType"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getGroup"
+ return="android.net.rtp.AudioGroup"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isBusy"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="join"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="group" type="android.net.rtp.AudioGroup">
+</parameter>
+</method>
+<method name="setCodec"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="codec" type="android.net.rtp.AudioCodec">
+</parameter>
+</method>
+<method name="setDtmfType"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="type" type="int">
+</parameter>
+</method>
+</class>
+<class name="RtpStream"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="associate"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="address" type="java.net.InetAddress">
+</parameter>
+<parameter name="port" type="int">
+</parameter>
+</method>
+<method name="getLocalAddress"
+ return="java.net.InetAddress"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getLocalPort"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getMode"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getRemoteAddress"
+ return="java.net.InetAddress"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getRemotePort"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isBusy"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="release"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="setMode"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="mode" type="int">
+</parameter>
+</method>
+<field name="MODE_NORMAL"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="MODE_RECEIVE_ONLY"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="MODE_SEND_ONLY"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+</package>
<package name="android.net.sip"
>
<class name="SipAudioCall"
@@ -206685,21 +206913,6 @@
visibility="public"
>
</method>
-<method name="entryEvicted"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="deprecated"
- visibility="protected"
->
-<parameter name="key" type="K">
-</parameter>
-<parameter name="value" type="V">
-</parameter>
-</method>
<method name="entryRemoved"
return="void"
abstract="false"
@@ -210832,8 +211045,8 @@
visibility="public"
>
</method>
-<method name="getMotionAxes"
- return="int[]"
+<method name="getMotionRange"
+ return="android.view.InputDevice.MotionRange"
abstract="false"
native="false"
synchronized="false"
@@ -210842,6 +211055,8 @@
deprecated="not deprecated"
visibility="public"
>
+<parameter name="axis" type="int">
+</parameter>
</method>
<method name="getMotionRange"
return="android.view.InputDevice.MotionRange"
@@ -210855,6 +211070,19 @@
>
<parameter name="axis" type="int">
</parameter>
+<parameter name="source" type="int">
+</parameter>
+</method>
+<method name="getMotionRanges"
+ return="java.util.List<android.view.InputDevice.MotionRange>"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
</method>
<method name="getName"
return="java.lang.String"
@@ -211220,6 +211448,17 @@
deprecated="not deprecated"
visibility="public"
>
+<method name="getAxis"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getFlat"
return="float"
abstract="false"
@@ -211275,6 +211514,17 @@
visibility="public"
>
</method>
+<method name="getSource"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
</class>
<class name="InputEvent"
extends="java.lang.Object"
@@ -218115,6 +218365,28 @@
visibility="public"
>
</field>
+<field name="AXIS_BRAKE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="23"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GAS"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="22"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="AXIS_GENERIC_1"
type="int"
transient="false"
@@ -218368,6 +218640,17 @@
visibility="public"
>
</field>
+<field name="AXIS_RUDDER"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="20"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="AXIS_RX"
type="int"
transient="false"
@@ -218412,6 +218695,17 @@
visibility="public"
>
</field>
+<field name="AXIS_THROTTLE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="19"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="AXIS_TOOL_MAJOR"
type="int"
transient="false"
@@ -218467,6 +218761,17 @@
visibility="public"
>
</field>
+<field name="AXIS_WHEEL"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="21"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="AXIS_X"
type="int"
transient="false"
@@ -244325,6 +244630,25 @@
<parameter name="realm" type="java.lang.String">
</parameter>
</method>
+<method name="onReceivedLoginRequest"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="view" type="android.webkit.WebView">
+</parameter>
+<parameter name="realm" type="java.lang.String">
+</parameter>
+<parameter name="account" type="java.lang.String">
+</parameter>
+<parameter name="args" type="java.lang.String">
+</parameter>
+</method>
<method name="onReceivedSslError"
return="void"
abstract="false"
@@ -263999,9 +264323,9 @@
</parameter>
<parameter name="start" type="int">
</parameter>
-<parameter name="before" type="int">
+<parameter name="lengthBefore" type="int">
</parameter>
-<parameter name="after" type="int">
+<parameter name="lengthAfter" type="int">
</parameter>
</method>
<method name="onTextContextMenuItem"
@@ -266773,7 +267097,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="t" type="T">
+<parameter name="arg0" type="T">
</parameter>
</method>
</interface>
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 930c6b0..b6581e9 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -74,7 +74,7 @@
static public int staticGetMemoryClass() {
// Really brain dead right now -- just take this from the configured
// vm heap size, and assume it is in megabytes and thus ends with "m".
- String vmHeapSize = SystemProperties.get("dalvik.vm.growthlimit", "");
+ String vmHeapSize = SystemProperties.get("dalvik.vm.heapgrowthlimit", "");
if (vmHeapSize != null && !"".equals(vmHeapSize)) {
return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length()-1));
}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 539e946..cc1f81c 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -401,10 +401,10 @@
return new UiModeManager();
}});
- registerService(USB_SERVICE, new StaticServiceFetcher() {
- public Object createStaticService() {
+ registerService(USB_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(USB_SERVICE);
- return new UsbManager(IUsbManager.Stub.asInterface(b));
+ return new UsbManager(ctx, IUsbManager.Stub.asInterface(b));
}});
registerService(VIBRATOR_SERVICE, new ServiceFetcher() {
diff --git a/core/java/android/app/DialogFragment.java b/core/java/android/app/DialogFragment.java
index dee1ef3..cce7cd6 100644
--- a/core/java/android/app/DialogFragment.java
+++ b/core/java/android/app/DialogFragment.java
@@ -258,6 +258,16 @@
dismissInternal(false);
}
+ /**
+ * Version of {@link #dismiss()} that uses
+ * {@link FragmentTransaction#commitAllowingStateLoss()
+ * FragmentTransaction.commitAllowingStateLoss()}. See linked
+ * documentation for further details.
+ */
+ public void dismissAllowingStateLoss() {
+ dismissInternal(true);
+ }
+
void dismissInternal(boolean allowStateLoss) {
if (mDismissed) {
return;
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index d04fa57..b88e5cf 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -376,8 +376,8 @@
/**
* This download shows in the notifications after completion ONLY.
* It is usuable only with
- * {@link DownloadManager#completedDownload(String, String, boolean, String,
- * String, long, boolean)}.
+ * {@link DownloadManager#addCompletedDownload(String, String,
+ * boolean, String, String, long, boolean)}.
*/
public static final int VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION = 3;
@@ -1111,7 +1111,7 @@
* @return an ID for the download entry added to the downloads app, unique across the system
* This ID is used to make future calls related to this download.
*/
- public long completedDownload(String title, String description,
+ public long addCompletedDownload(String title, String description,
boolean isMediaScannerScannable, String mimeType, String path, long length,
boolean showNotification) {
// make sure the input args are non-null/non-zero
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 440cb54..efe2633 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1150,8 +1150,12 @@
* fail (most commonly returning {@link #ENCRYPTION_STATUS_ACTIVE}).
*
* <p>This policy controls encryption of the secure (application data) storage area. Data
- * written to other areas (e.g. the directory returned by
- * {@link android.os.Environment#getExternalStorageDirectory()} may or may not be encrypted.
+ * written to other storage areas may or may not be encrypted, and this policy does not require
+ * or control the encryption of any other storage areas.
+ * There is one exception: If {@link android.os.Environment#isExternalStorageEmulated()} is
+ * {@code true}, then the directory returned by
+ * {@link android.os.Environment#getExternalStorageDirectory()} must be written to disk
+ * within the encrypted storage area.
*
* <p>Important Note: On some devices, it is possible to encrypt storage without requiring
* the user to create a device PIN or Password. In this case, the storage is encrypted, but
diff --git a/core/java/android/app/backup/WallpaperBackupHelper.java b/core/java/android/app/backup/WallpaperBackupHelper.java
index 6539711..55368d6 100644
--- a/core/java/android/app/backup/WallpaperBackupHelper.java
+++ b/core/java/android/app/backup/WallpaperBackupHelper.java
@@ -110,11 +110,16 @@
if (DEBUG) Slog.d(TAG, "Restoring wallpaper image w=" + options.outWidth
+ " h=" + options.outHeight);
- // how much does the image differ from our preference?
+ // How much does the image differ from our preference? The threshold
+ // here is set to accept any image larger than our target, because
+ // scaling down is acceptable; but to reject images that are deemed
+ // "too small" to scale up attractively. The value 1.33 is just barely
+ // too low to pass Nexus 1 or Droid wallpapers for use on a Xoom, but
+ // will pass anything relatively larger.
double widthRatio = mDesiredMinWidth / options.outWidth;
double heightRatio = mDesiredMinHeight / options.outHeight;
- if (widthRatio > 0.8 && widthRatio < 1.25
- && heightRatio > 0.8 && heightRatio < 1.25) {
+ if (widthRatio > 0 && widthRatio < 1.33
+ && heightRatio > 0 && heightRatio < 1.33) {
// sufficiently close to our resolution; go ahead and use it
if (DEBUG) Slog.d(TAG, "wallpaper dimension match; using");
f.renameTo(new File(WALLPAPER_IMAGE));
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index dd4096b..2111cce 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -2051,8 +2051,8 @@
if (rv.length == 4) {
Q[0] = rv[3];
} else {
- //In this case, the w component of the quaternion is known to be a positive number
- Q[0] = (float)Math.sqrt(1 - rv[0]*rv[0] - rv[1]*rv[1] - rv[2]*rv[2]);
+ Q[0] = 1 - rv[0]*rv[0] - rv[1]*rv[1] - rv[2]*rv[2];
+ Q[0] = (Q[0] > 0) ? (float)Math.sqrt(Q[0]) : 0;
}
Q[1] = rv[0];
Q[2] = rv[1];
diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl
index be65bdb..5df2343 100644
--- a/core/java/android/hardware/usb/IUsbManager.aidl
+++ b/core/java/android/hardware/usb/IUsbManager.aidl
@@ -16,6 +16,7 @@
package android.hardware.usb;
+import android.app.PendingIntent;
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbDevice;
import android.os.Bundle;
@@ -43,13 +44,32 @@
/* Sets the default package for a USB device
* (or clears it if the package name is null)
*/
- oneway void setDevicePackage(in UsbDevice device, String packageName);
+ void setDevicePackage(in UsbDevice device, String packageName);
- /* Sets the default package for a USB device
+ /* Sets the default package for a USB accessory
* (or clears it if the package name is null)
*/
void setAccessoryPackage(in UsbAccessory accessory, String packageName);
+ /* Returns true if the caller has permission to access the device. */
+ boolean hasDevicePermission(in UsbDevice device);
+
+ /* Returns true if the caller has permission to access the accessory. */
+ boolean hasAccessoryPermission(in UsbAccessory accessory);
+
+ /* Requests permission for the given package to access the device.
+ * Will display a system dialog to query the user if permission
+ * had not already been given.
+ */
+ void requestDevicePermission(in UsbDevice device, String packageName, in PendingIntent pi);
+
+ /* Requests permission for the given package to access the accessory.
+ * Will display a system dialog to query the user if permission
+ * had not already been given. Result is returned via pi.
+ */
+ void requestAccessoryPermission(in UsbAccessory accessory, String packageName,
+ in PendingIntent pi);
+
/* Grants permission for the given UID to access the device */
void grantDevicePermission(in UsbDevice device, int uid);
@@ -57,8 +77,8 @@
void grantAccessoryPermission(in UsbAccessory accessory, int uid);
/* Returns true if the USB manager has default preferences or permissions for the package */
- boolean hasDefaults(String packageName, int uid);
+ boolean hasDefaults(String packageName);
/* Clears default preferences and permissions for the package */
- oneway void clearDefaults(String packageName, int uid);
+ void clearDefaults(String packageName);
}
diff --git a/core/java/android/hardware/usb/UsbAccessory.java b/core/java/android/hardware/usb/UsbAccessory.java
index 6cd9178..cc174d4 100644
--- a/core/java/android/hardware/usb/UsbAccessory.java
+++ b/core/java/android/hardware/usb/UsbAccessory.java
@@ -30,18 +30,21 @@
private final String mManufacturer;
private final String mModel;
- private final String mType;
+ private final String mDescription;
private final String mVersion;
+ private final String mUri;
/**
* UsbAccessory should only be instantiated by UsbService implementation
* @hide
*/
- public UsbAccessory(String manufacturer, String model, String type, String version) {
+ public UsbAccessory(String manufacturer, String model, String description,
+ String version, String uri) {
mManufacturer = manufacturer;
mModel = model;
- mType = type;
+ mDescription = description;
mVersion = version;
+ mUri = uri;
}
/**
@@ -51,8 +54,9 @@
public UsbAccessory(String[] strings) {
mManufacturer = strings[0];
mModel = strings[1];
- mType = strings[2];
+ mDescription = strings[2];
mVersion = strings[3];
+ mUri = strings[4];
}
/**
@@ -74,12 +78,12 @@
}
/**
- * Returns the type of the accessory.
+ * Returns a user visible description of the accessory.
*
- * @return the accessory type
+ * @return the accessory description
*/
- public String getType() {
- return mType;
+ public String getDescription() {
+ return mDescription;
}
/**
@@ -91,6 +95,17 @@
return mVersion;
}
+ /**
+ * Returns the URI for the accessory.
+ * This is an optional URI that might show information about the accessory
+ * or provide the option to download an application for the accessory
+ *
+ * @return the accessory URI
+ */
+ public String getUri() {
+ return mUri;
+ }
+
private static boolean compare(String s1, String s2) {
if (s1 == null) return (s2 == null);
return s1.equals(s2);
@@ -102,18 +117,29 @@
UsbAccessory accessory = (UsbAccessory)obj;
return (compare(mManufacturer, accessory.getManufacturer()) &&
compare(mModel, accessory.getModel()) &&
- compare(mType, accessory.getType()) &&
- compare(mVersion, accessory.getVersion()));
+ compare(mDescription, accessory.getDescription()) &&
+ compare(mVersion, accessory.getVersion()) &&
+ compare(mUri, accessory.getUri()));
}
return false;
}
@Override
+ public int hashCode() {
+ return ((mManufacturer == null ? 0 : mManufacturer.hashCode()) ^
+ (mModel == null ? 0 : mModel.hashCode()) ^
+ (mDescription == null ? 0 : mDescription.hashCode()) ^
+ (mVersion == null ? 0 : mVersion.hashCode()) ^
+ (mUri == null ? 0 : mUri.hashCode()));
+ }
+
+ @Override
public String toString() {
return "UsbAccessory[mManufacturer=" + mManufacturer +
", mModel=" + mModel +
- ", mType=" + mType +
- ", mVersion=" + mVersion + "]";
+ ", mDescription=" + mDescription +
+ ", mVersion=" + mVersion +
+ ", mUri=" + mUri + "]";
}
public static final Parcelable.Creator<UsbAccessory> CREATOR =
@@ -121,9 +147,10 @@
public UsbAccessory createFromParcel(Parcel in) {
String manufacturer = in.readString();
String model = in.readString();
- String type = in.readString();
+ String description = in.readString();
String version = in.readString();
- return new UsbAccessory(manufacturer, model, type, version);
+ String uri = in.readString();
+ return new UsbAccessory(manufacturer, model, description, version, uri);
}
public UsbAccessory[] newArray(int size) {
@@ -138,7 +165,8 @@
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeString(mManufacturer);
parcel.writeString(mModel);
- parcel.writeString(mType);
+ parcel.writeString(mDescription);
parcel.writeString(mVersion);
+ parcel.writeString(mUri);
}
}
diff --git a/core/java/android/hardware/usb/UsbDevice.java b/core/java/android/hardware/usb/UsbDevice.java
index 37bd82b..9e536a7 100644
--- a/core/java/android/hardware/usb/UsbDevice.java
+++ b/core/java/android/hardware/usb/UsbDevice.java
@@ -19,33 +19,24 @@
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
-import android.os.ParcelFileDescriptor;
import android.util.Log;
import java.io.FileDescriptor;
-
/**
* A class representing a USB device.
*/
-public final class UsbDevice implements Parcelable {
+public class UsbDevice implements Parcelable {
private static final String TAG = "UsbDevice";
- private String mName;
- private int mVendorId;
- private int mProductId;
- private int mClass;
- private int mSubclass;
- private int mProtocol;
- private Parcelable[] mInterfaces;
-
- // used by the JNI code
- private int mNativeContext;
-
- private UsbDevice() {
- }
-
+ private final String mName;
+ private final int mVendorId;
+ private final int mProductId;
+ private final int mClass;
+ private final int mSubclass;
+ private final int mProtocol;
+ private final Parcelable[] mInterfaces;
/**
* UsbDevice should only be instantiated by UsbService implementation
@@ -150,114 +141,6 @@
return (UsbInterface)mInterfaces[index];
}
- /* package */ boolean open(ParcelFileDescriptor pfd) {
- return native_open(mName, pfd.getFileDescriptor());
- }
-
- /**
- * Releases all system resources related to the device.
- */
- public void close() {
- native_close();
- }
-
- /**
- * Returns an integer file descriptor for the device, or
- * -1 if the device is not opened.
- * This is intended for passing to native code to access the device
- */
- public int getFileDescriptor() {
- return native_get_fd();
- }
-
- /**
- * Claims exclusive access to a {@link android.hardware.usb.UsbInterface}.
- * This must be done before sending or receiving data on any
- * {@link android.hardware.usb.UsbEndpoint}s belonging to the interface
- * @param intf the interface to claim
- * @param force true to disconnect kernel driver if necessary
- * @return true if the interface was successfully claimed
- */
- public boolean claimInterface(UsbInterface intf, boolean force) {
- return native_claim_interface(intf.getId(), force);
- }
-
- /**
- * Releases exclusive access to a {@link android.hardware.usb.UsbInterface}.
- *
- * @return true if the interface was successfully released
- */
- public boolean releaseInterface(UsbInterface intf) {
- return native_release_interface(intf.getId());
- }
-
- /**
- * Performs a control transaction on endpoint zero for this device.
- * The direction of the transfer is determined by the request type.
- * If requestType & {@link UsbConstants#USB_ENDPOINT_DIR_MASK} is
- * {@link UsbConstants#USB_DIR_OUT}, then the transfer is a write,
- * and if it is {@link UsbConstants#USB_DIR_IN}, then the transfer
- * is a read.
- *
- * @param requestType request type for this transaction
- * @param request request ID for this transaction
- * @param value value field for this transaction
- * @param index index field for this transaction
- * @param buffer buffer for data portion of transaction,
- * or null if no data needs to be sent or received
- * @param length the length of the data to send or receive
- * @param timeout in milliseconds
- * @return length of data transferred (or zero) for success,
- * or negative value for failure
- */
- public int controlTransfer(int requestType, int request, int value,
- int index, byte[] buffer, int length, int timeout) {
- return native_control_request(requestType, request, value, index, buffer, length, timeout);
- }
-
- /**
- * Performs a bulk transaction on the given endpoint.
- * The direction of the transfer is determined by the direction of the endpoint
- *
- * @param endpoint the endpoint for this transaction
- * @param buffer buffer for data to send or receive,
- * @param length the length of the data to send or receive
- * @param timeout in milliseconds
- * @return length of data transferred (or zero) for success,
- * or negative value for failure
- */
- public int bulkTransfer(UsbEndpoint endpoint, byte[] buffer, int length, int timeout) {
- return native_bulk_request(endpoint.getAddress(), buffer, length, timeout);
- }
-
- /**
- * Waits for the result of a {@link android.hardware.usb.UsbRequest#queue} operation
- * Note that this may return requests queued on multiple
- * {@link android.hardware.usb.UsbEndpoint}s.
- * When multiple endpoints are in use, {@link android.hardware.usb.UsbRequest#getEndpoint} and
- * {@link android.hardware.usb.UsbRequest#getClientData} can be useful in determining
- * how to process the result of this function.
- *
- * @return a completed USB request, or null if an error occurred
- */
- public UsbRequest requestWait() {
- UsbRequest request = native_request_wait();
- if (request != null) {
- request.dequeue();
- }
- return request;
- }
-
- /**
- * Returns the serial number for the device.
- * This will return null if the device has not been opened.
- *
- * @return the device serial number
- */
- public String getSerial() {
- return native_get_serial();
- }
-
@Override
public boolean equals(Object o) {
if (o instanceof UsbDevice) {
@@ -270,6 +153,11 @@
}
@Override
+ public int hashCode() {
+ return mName.hashCode();
+ }
+
+ @Override
public String toString() {
return "UsbDevice[mName=" + mName + ",mVendorId=" + mVendorId +
",mProductId=" + mProductId + ",mClass=" + mClass +
@@ -287,11 +175,7 @@
int subClass = in.readInt();
int protocol = in.readInt();
Parcelable[] interfaces = in.readParcelableArray(UsbInterface.class.getClassLoader());
- UsbDevice result = new UsbDevice(name, vendorId, productId, clasz, subClass, protocol, interfaces);
- for (int i = 0; i < interfaces.length; i++) {
- ((UsbInterface)interfaces[i]).setDevice(result);
- }
- return result;
+ return new UsbDevice(name, vendorId, productId, clasz, subClass, protocol, interfaces);
}
public UsbDevice[] newArray(int size) {
@@ -321,17 +205,6 @@
return native_get_device_name(id);
}
- private native boolean native_open(String deviceName, FileDescriptor pfd);
- private native void native_close();
- private native int native_get_fd();
- private native boolean native_claim_interface(int interfaceID, boolean force);
- private native boolean native_release_interface(int interfaceID);
- private native int native_control_request(int requestType, int request, int value,
- int index, byte[] buffer, int length, int timeout);
- private native int native_bulk_request(int endpoint, byte[] buffer, int length, int timeout);
- private native UsbRequest native_request_wait();
- private native String native_get_serial();
-
private static native int native_get_device_id(String name);
private static native String native_get_device_name(int id);
}
diff --git a/core/java/android/hardware/usb/UsbDeviceConnection.java b/core/java/android/hardware/usb/UsbDeviceConnection.java
new file mode 100644
index 0000000..876287c
--- /dev/null
+++ b/core/java/android/hardware/usb/UsbDeviceConnection.java
@@ -0,0 +1,163 @@
+/*
+ * 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.usb;
+
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+
+import java.io.FileDescriptor;
+
+
+/**
+ * A class representing a USB device.
+ */
+public class UsbDeviceConnection {
+
+ private static final String TAG = "UsbDeviceConnection";
+
+ private final UsbDevice mDevice;
+
+ // used by the JNI code
+ private int mNativeContext;
+
+ /**
+ * UsbDevice should only be instantiated by UsbService implementation
+ * @hide
+ */
+ public UsbDeviceConnection(UsbDevice device) {
+ mDevice = device;
+ }
+
+ /* package */ boolean open(String name, ParcelFileDescriptor pfd) {
+ return native_open(name, pfd.getFileDescriptor());
+ }
+
+ /**
+ * Releases all system resources related to the device.
+ */
+ public void close() {
+ native_close();
+ }
+
+ /**
+ * Returns an integer file descriptor for the device, or
+ * -1 if the device is not opened.
+ * This is intended for passing to native code to access the device
+ */
+ public int getFileDescriptor() {
+ return native_get_fd();
+ }
+
+ /**
+ * Claims exclusive access to a {@link android.hardware.usb.UsbInterface}.
+ * This must be done before sending or receiving data on any
+ * {@link android.hardware.usb.UsbEndpoint}s belonging to the interface
+ * @param intf the interface to claim
+ * @param force true to disconnect kernel driver if necessary
+ * @return true if the interface was successfully claimed
+ */
+ public boolean claimInterface(UsbInterface intf, boolean force) {
+ return native_claim_interface(intf.getId(), force);
+ }
+
+ /**
+ * Releases exclusive access to a {@link android.hardware.usb.UsbInterface}.
+ *
+ * @return true if the interface was successfully released
+ */
+ public boolean releaseInterface(UsbInterface intf) {
+ return native_release_interface(intf.getId());
+ }
+
+ /**
+ * Performs a control transaction on endpoint zero for this device.
+ * The direction of the transfer is determined by the request type.
+ * If requestType & {@link UsbConstants#USB_ENDPOINT_DIR_MASK} is
+ * {@link UsbConstants#USB_DIR_OUT}, then the transfer is a write,
+ * and if it is {@link UsbConstants#USB_DIR_IN}, then the transfer
+ * is a read.
+ *
+ * @param requestType request type for this transaction
+ * @param request request ID for this transaction
+ * @param value value field for this transaction
+ * @param index index field for this transaction
+ * @param buffer buffer for data portion of transaction,
+ * or null if no data needs to be sent or received
+ * @param length the length of the data to send or receive
+ * @param timeout in milliseconds
+ * @return length of data transferred (or zero) for success,
+ * or negative value for failure
+ */
+ public int controlTransfer(int requestType, int request, int value,
+ int index, byte[] buffer, int length, int timeout) {
+ return native_control_request(requestType, request, value, index, buffer, length, timeout);
+ }
+
+ /**
+ * Performs a bulk transaction on the given endpoint.
+ * The direction of the transfer is determined by the direction of the endpoint
+ *
+ * @param endpoint the endpoint for this transaction
+ * @param buffer buffer for data to send or receive,
+ * @param length the length of the data to send or receive
+ * @param timeout in milliseconds
+ * @return length of data transferred (or zero) for success,
+ * or negative value for failure
+ */
+ public int bulkTransfer(UsbEndpoint endpoint, byte[] buffer, int length, int timeout) {
+ return native_bulk_request(endpoint.getAddress(), buffer, length, timeout);
+ }
+
+ /**
+ * Waits for the result of a {@link android.hardware.usb.UsbRequest#queue} operation
+ * Note that this may return requests queued on multiple
+ * {@link android.hardware.usb.UsbEndpoint}s.
+ * When multiple endpoints are in use, {@link android.hardware.usb.UsbRequest#getEndpoint} and
+ * {@link android.hardware.usb.UsbRequest#getClientData} can be useful in determining
+ * how to process the result of this function.
+ *
+ * @return a completed USB request, or null if an error occurred
+ */
+ public UsbRequest requestWait() {
+ UsbRequest request = native_request_wait();
+ if (request != null) {
+ request.dequeue();
+ }
+ return request;
+ }
+
+ /**
+ * Returns the serial number for the device.
+ * This will return null if the device has not been opened.
+ *
+ * @return the device serial number
+ */
+ public String getSerial() {
+ return native_get_serial();
+ }
+
+ private native boolean native_open(String deviceName, FileDescriptor pfd);
+ private native void native_close();
+ private native int native_get_fd();
+ private native boolean native_claim_interface(int interfaceID, boolean force);
+ private native boolean native_release_interface(int interfaceID);
+ private native int native_control_request(int requestType, int request, int value,
+ int index, byte[] buffer, int length, int timeout);
+ private native int native_bulk_request(int endpoint, byte[] buffer, int length, int timeout);
+ private native UsbRequest native_request_wait();
+ private native String native_get_serial();
+}
diff --git a/core/java/android/hardware/usb/UsbEndpoint.java b/core/java/android/hardware/usb/UsbEndpoint.java
index a48d88f..bc2c2c1 100644
--- a/core/java/android/hardware/usb/UsbEndpoint.java
+++ b/core/java/android/hardware/usb/UsbEndpoint.java
@@ -23,16 +23,12 @@
/**
* A class representing an endpoint on a {@link android.hardware.usb.UsbInterface}.
*/
-public final class UsbEndpoint implements Parcelable {
+public class UsbEndpoint implements Parcelable {
- private int mAddress;
- private int mAttributes;
- private int mMaxPacketSize;
- private int mInterval;
- private UsbInterface mInterface;
-
- private UsbEndpoint() {
- }
+ private final int mAddress;
+ private final int mAttributes;
+ private final int mMaxPacketSize;
+ private final int mInterval;
/**
* UsbEndpoint should only be instantiated by UsbService implementation
@@ -119,29 +115,6 @@
return mInterval;
}
- /**
- * Returns the {@link android.hardware.usb.UsbInterface} this endpoint belongs to.
- *
- * @return the endpoint's interface
- */
- public UsbInterface getInterface() {
- return mInterface;
- }
-
- /**
- * Returns the {@link android.hardware.usb.UsbDevice} this endpoint belongs to.
- *
- * @return the endpoint's device
- */
- public UsbDevice getDevice() {
- return mInterface.getDevice();
- }
-
- // only used for parcelling
- /* package */ void setInterface(UsbInterface intf) {
- mInterface = intf;
- }
-
@Override
public String toString() {
return "UsbEndpoint[mAddress=" + mAddress + ",mAttributes=" + mAttributes +
diff --git a/core/java/android/hardware/usb/UsbInterface.java b/core/java/android/hardware/usb/UsbInterface.java
index b3b0e81..2b4c7c0 100644
--- a/core/java/android/hardware/usb/UsbInterface.java
+++ b/core/java/android/hardware/usb/UsbInterface.java
@@ -25,15 +25,11 @@
*/
public class UsbInterface implements Parcelable {
- private int mId;
- private int mClass;
- private int mSubclass;
- private int mProtocol;
- private UsbDevice mDevice;
- private Parcelable[] mEndpoints;
-
- private UsbInterface() {
- }
+ private final int mId;
+ private final int mClass;
+ private final int mSubclass;
+ private final int mProtocol;
+ private final Parcelable[] mEndpoints;
/**
* UsbInterface should only be instantiated by UsbService implementation
@@ -104,20 +100,6 @@
return (UsbEndpoint)mEndpoints[index];
}
- /**
- * Returns the {@link android.hardware.usb.UsbDevice} this interface belongs to.
- *
- * @return the interface's device
- */
- public UsbDevice getDevice() {
- return mDevice;
- }
-
- // only used for parcelling
- /* package */ void setDevice(UsbDevice device) {
- mDevice = device;
- }
-
@Override
public String toString() {
return "UsbInterface[mId=" + mId + ",mClass=" + mClass +
@@ -133,11 +115,7 @@
int subClass = in.readInt();
int protocol = in.readInt();
Parcelable[] endpoints = in.readParcelableArray(UsbEndpoint.class.getClassLoader());
- UsbInterface result = new UsbInterface(id, Class, subClass, protocol, endpoints);
- for (int i = 0; i < endpoints.length; i++) {
- ((UsbEndpoint)endpoints[i]).setInterface(result);
- }
- return result;
+ return new UsbInterface(id, Class, subClass, protocol, endpoints);
}
public UsbInterface[] newArray(int size) {
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index 6683179..7bf278a 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -17,6 +17,8 @@
package android.hardware.usb;
+import android.app.PendingIntent;
+import android.content.Context;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -53,6 +55,8 @@
* {@link #USB_FUNCTION_MASS_STORAGE}, {@link #USB_FUNCTION_ADB}, {@link #USB_FUNCTION_RNDIS},
* {@link #USB_FUNCTION_MTP} and {@link #USB_FUNCTION_ACCESSORY}.
* </ul>
+ *
+ * {@hide}
*/
public static final String ACTION_USB_STATE =
"android.hardware.usb.action.USB_STATE";
@@ -98,7 +102,7 @@
*
* This intent is sent when a USB accessory is detached.
* <ul>
- * <li> {@link #EXTRA_ACCESSORY} containing the {@link android.hardware.usb.UsbAccessory}
+ * <li> {@link #EXTRA_ACCESSORY} containing the {@link UsbAccessory}
* for the attached accessory that was detached
* </ul>
*/
@@ -108,42 +112,56 @@
/**
* Boolean extra indicating whether USB is connected or disconnected.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast.
+ *
+ * {@hide}
*/
public static final String USB_CONNECTED = "connected";
/**
* Integer extra containing currently set USB configuration.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast.
+ *
+ * {@hide}
*/
public static final String USB_CONFIGURATION = "configuration";
/**
* Name of the USB mass storage USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast
+ *
+ * {@hide}
*/
public static final String USB_FUNCTION_MASS_STORAGE = "mass_storage";
/**
* Name of the adb USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast
+ *
+ * {@hide}
*/
public static final String USB_FUNCTION_ADB = "adb";
/**
* Name of the RNDIS ethernet USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast
+ *
+ * {@hide}
*/
public static final String USB_FUNCTION_RNDIS = "rndis";
/**
* Name of the MTP USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast
+ *
+ * {@hide}
*/
public static final String USB_FUNCTION_MTP = "mtp";
/**
* Name of the Accessory USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast
+ *
+ * {@hide}
*/
public static final String USB_FUNCTION_ACCESSORY = "accessory";
@@ -151,6 +169,8 @@
* Value indicating that a USB function is enabled.
* Used in {@link #USB_CONFIGURATION} extras bundle for the
* {@link #ACTION_USB_STATE} broadcast
+ *
+ * {@hide}
*/
public static final String USB_FUNCTION_ENABLED = "enabled";
@@ -158,6 +178,8 @@
* Value indicating that a USB function is disabled.
* Used in {@link #USB_CONFIGURATION} extras bundle for the
* {@link #ACTION_USB_STATE} broadcast
+ *
+ * {@hide}
*/
public static final String USB_FUNCTION_DISABLED = "disabled";
@@ -176,12 +198,22 @@
*/
public static final String EXTRA_ACCESSORY = "accessory";
- private IUsbManager mService;
+ /**
+ * Name of extra added to the {@link android.app.PendingIntent}
+ * passed into {@link #requestPermission(UsbDevice, PendingIntent)}
+ * or {@link #requestPermission(UsbAccessory, PendingIntent)}
+ * containing a boolean value indicating whether the user granted permission or not.
+ */
+ public static final String EXTRA_PERMISSION_GRANTED = "permission";
+
+ private final Context mContext;
+ private final IUsbManager mService;
/**
* {@hide}
*/
- public UsbManager(IUsbManager service) {
+ public UsbManager(Context context, IUsbManager service) {
+ mContext = context;
mService = service;
}
@@ -215,19 +247,22 @@
* @param device the device to open
* @return true if we successfully opened the device
*/
- public boolean openDevice(UsbDevice device) {
+ public UsbDeviceConnection openDevice(UsbDevice device) {
try {
- ParcelFileDescriptor pfd = mService.openDevice(device.getDeviceName());
- if (pfd == null) {
- return false;
+ String deviceName = device.getDeviceName();
+ ParcelFileDescriptor pfd = mService.openDevice(deviceName);
+ if (pfd != null) {
+ UsbDeviceConnection connection = new UsbDeviceConnection(device);
+ boolean result = connection.open(deviceName, pfd);
+ pfd.close();
+ if (result) {
+ return connection;
+ }
}
- boolean result = device.open(pfd);
- pfd.close();
- return result;
} catch (Exception e) {
Log.e(TAG, "exception in UsbManager.openDevice", e);
- return false;
}
+ return null;
}
/**
@@ -245,7 +280,7 @@
return new UsbAccessory[] { accessory };
}
} catch (RemoteException e) {
- Log.e(TAG, "RemoteException in getAccessoryList" , e);
+ Log.e(TAG, "RemoteException in getAccessoryList", e);
return null;
}
}
@@ -260,11 +295,99 @@
try {
return mService.openAccessory(accessory);
} catch (RemoteException e) {
- Log.e(TAG, "RemoteException in openAccessory" , e);
+ Log.e(TAG, "RemoteException in openAccessory", e);
return null;
}
}
+ /**
+ * Returns true if the caller has permission to access the device.
+ * Permission might have been granted temporarily via
+ * {@link #requestPermission(UsbDevice, PendingIntent)} or
+ * by the user choosing the caller as the default application for the device.
+ *
+ * @param device to check permissions for
+ * @return true if caller has permission
+ */
+ public boolean hasPermission(UsbDevice device) {
+ try {
+ return mService.hasDevicePermission(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in hasPermission", e);
+ return false;
+ }
+ }
+
+ /**
+ * Returns true if the caller has permission to access the accessory.
+ * Permission might have been granted temporarily via
+ * {@link #requestPermission(UsbAccessory, PendingIntent)} or
+ * by the user choosing the caller as the default application for the accessory.
+ *
+ * @param accessory to check permissions for
+ * @return true if caller has permission
+ */
+ public boolean hasPermission(UsbAccessory accessory) {
+ try {
+ return mService.hasAccessoryPermission(accessory);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in hasPermission", e);
+ return false;
+ }
+ }
+
+ /**
+ * Requests temporary permission for the given package to access the device.
+ * This may result in a system dialog being displayed to the user
+ * if permission had not already been granted.
+ * Success or failure is returned via the {@link android.app.PendingIntent} pi.
+ * If successful, this grants the caller permission to access the device only
+ * until the device is disconnected.
+ *
+ * The following extras will be added to pi:
+ * <ul>
+ * <li> {@link #EXTRA_DEVICE} containing the device passed into this call
+ * <li> {@link #EXTRA_PERMISSION_GRANTED} containing boolean indicating whether
+ * permission was granted by the user
+ * </ul>
+ *
+ * @param device to request permissions for
+ * @param pi PendingIntent for returning result
+ */
+ public void requestPermission(UsbDevice device, PendingIntent pi) {
+ try {
+ mService.requestDevicePermission(device, mContext.getPackageName(), pi);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in requestPermission", e);
+ }
+ }
+
+ /**
+ * Requests temporary permission for the given package to access the accessory.
+ * This may result in a system dialog being displayed to the user
+ * if permission had not already been granted.
+ * Success or failure is returned via the {@link android.app.PendingIntent} pi.
+ * If successful, this grants the caller permission to access the accessory only
+ * until the device is disconnected.
+ *
+ * The following extras will be added to pi:
+ * <ul>
+ * <li> {@link #EXTRA_ACCESSORY} containing the accessory passed into this call
+ * <li> {@link #EXTRA_PERMISSION_GRANTED} containing boolean indicating whether
+ * permission was granted by the user
+ * </ul>
+ *
+ * @param accessory to request permissions for
+ * @param pi PendingIntent for returning result
+ */
+ public void requestPermission(UsbAccessory accessory, PendingIntent pi) {
+ try {
+ mService.requestAccessoryPermission(accessory, mContext.getPackageName(), pi);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in requestPermission", e);
+ }
+ }
+
private static File getFunctionEnableFile(String function) {
return new File("/sys/class/usb_composite/" + function + "/enable");
}
@@ -275,6 +398,8 @@
*
* @param function name of the USB function
* @return true if the USB function is supported.
+ *
+ * {@hide}
*/
public static boolean isFunctionSupported(String function) {
return getFunctionEnableFile(function).exists();
@@ -285,6 +410,8 @@
*
* @param function name of the USB function
* @return true if the USB function is enabled.
+ *
+ * {@hide}
*/
public static boolean isFunctionEnabled(String function) {
try {
@@ -300,7 +427,7 @@
/**
* Enables or disables a USB function.
*
- * @hide
+ * {@hide}
*/
public static boolean setFunctionEnabled(String function, boolean enable) {
try {
diff --git a/core/java/android/hardware/usb/UsbRequest.java b/core/java/android/hardware/usb/UsbRequest.java
index 80085c1..5fe6c8c 100644
--- a/core/java/android/hardware/usb/UsbRequest.java
+++ b/core/java/android/hardware/usb/UsbRequest.java
@@ -23,9 +23,9 @@
/**
* A class representing USB request packet.
* This can be used for both reading and writing data to or from a
- * {@link android.hardware.usb.UsbDevice}.
+ * {@link android.hardware.usb.UsbDeviceConnection}.
* UsbRequests are sent asynchronously via {@link #queue} and the results
- * are read by {@link android.hardware.usb.UsbDevice#requestWait}.
+ * are read by {@link android.hardware.usb.UsbDeviceConnection#requestWait}.
*/
public class UsbRequest {
@@ -53,10 +53,9 @@
* @param endpoint the endpoint to be used for this request.
* @return true if the request was successfully opened.
*/
- public boolean initialize(UsbEndpoint endpoint) {
+ public boolean initialize(UsbDeviceConnection connection, UsbEndpoint endpoint) {
mEndpoint = endpoint;
- return native_init(endpoint.getDevice(),
- endpoint.getAddress(), endpoint.getAttributes(),
+ return native_init(connection, endpoint.getAddress(), endpoint.getAttributes(),
endpoint.getMaxPacketSize(), endpoint.getInterval());
}
@@ -94,7 +93,7 @@
* This can be used in conjunction with {@link #setClientData}
* to associate another object with this request, which can be useful for
* maintaining state between calls to {@link #queue} and
- * {@link android.hardware.usb.UsbDevice#requestWait}
+ * {@link android.hardware.usb.UsbDeviceConnection#requestWait}
*
* @return the client data for the request
*/
@@ -107,7 +106,7 @@
* This can be used in conjunction with {@link #getClientData}
* to associate another object with this request, which can be useful for
* maintaining state between calls to {@link #queue} and
- * {@link android.hardware.usb.UsbDevice#requestWait}
+ * {@link android.hardware.usb.UsbDeviceConnection#requestWait}
*
* @param data the client data for the request
*/
@@ -121,7 +120,7 @@
* For IN endpoints, the endpoint will attempt to read the given number of bytes
* into the specified buffer.
* If the queueing operation is successful, we return true and the result will be
- * returned via {@link android.hardware.usb.UsbDevice#requestWait}
+ * returned via {@link android.hardware.usb.UsbDeviceConnection#requestWait}
*
* @param buffer the buffer containing the bytes to write, or location to store
* the results of a read
@@ -166,8 +165,8 @@
return native_cancel();
}
- private native boolean native_init(UsbDevice device, int ep_address, int ep_attributes,
- int ep_max_packet_size, int ep_interval);
+ private native boolean native_init(UsbDeviceConnection connection, int ep_address,
+ int ep_attributes, int ep_max_packet_size, int ep_interval);
private native void native_close();
private native boolean native_queue_array(byte[] buffer, int length, boolean out);
private native void native_dequeue_array(byte[] buffer, int length, boolean out);
diff --git a/core/java/android/net/EthernetDataTracker.java b/core/java/android/net/EthernetDataTracker.java
new file mode 100644
index 0000000..df5fdd0
--- /dev/null
+++ b/core/java/android/net/EthernetDataTracker.java
@@ -0,0 +1,333 @@
+/*
+ * 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.
+ * 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.net;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.DhcpInfoInternal;
+import android.net.LinkAddress;
+import android.net.LinkCapabilities;
+import android.net.LinkProperties;
+import android.net.NetworkInfo;
+import android.net.NetworkInfo.DetailedState;
+import android.net.NetworkStateTracker;
+import android.net.NetworkUtils;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.INetworkManagementService;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+
+import java.net.InetAddress;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * This class tracks the data connection associated with Ethernet
+ * This is a singleton class and an instance will be created by
+ * ConnectivityService.
+ * @hide
+ */
+public class EthernetDataTracker implements NetworkStateTracker {
+ private static final String NETWORKTYPE = "ETHERNET";
+ private static final String TAG = "Ethernet";
+
+ private AtomicBoolean mTeardownRequested = new AtomicBoolean(false);
+ private AtomicBoolean mPrivateDnsRouteSet = new AtomicBoolean(false);
+ private AtomicInteger mDefaultGatewayAddr = new AtomicInteger(0);
+ private AtomicBoolean mDefaultRouteSet = new AtomicBoolean(false);
+
+ private LinkProperties mLinkProperties;
+ private LinkCapabilities mLinkCapabilities;
+ private NetworkInfo mNetworkInfo;
+ private InterfaceObserver mInterfaceObserver;
+
+ /* For sending events to connectivity service handler */
+ private Handler mCsHandler;
+ private Context mContext;
+
+ private static EthernetDataTracker sInstance;
+ private static String mIface = "";
+
+ private static class InterfaceObserver extends INetworkManagementEventObserver.Stub {
+ private EthernetDataTracker mTracker;
+
+ InterfaceObserver(EthernetDataTracker tracker) {
+ super();
+ mTracker = tracker;
+ }
+
+ public void interfaceLinkStatusChanged(String iface, boolean up) {
+ Log.d(TAG, "Interface " + iface + " link " + (up ? "up" : "down"));
+ }
+
+ public void interfaceAdded(String iface) {
+ mTracker.interfaceAdded(iface);
+ }
+
+ public void interfaceRemoved(String iface) {
+ mTracker.interfaceRemoved(iface);
+ }
+ }
+
+ private EthernetDataTracker() {
+ mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_ETHERNET, 0, NETWORKTYPE, "");
+ mLinkProperties = new LinkProperties();
+ mLinkCapabilities = new LinkCapabilities();
+
+ mNetworkInfo.setIsAvailable(false);
+ setTeardownRequested(false);
+ }
+
+ private void interfaceAdded(String iface) {
+ if (!iface.matches("eth\\d"))
+ return;
+
+ Log.d(TAG, "Adding " + iface);
+
+ synchronized(mIface) {
+ if(!mIface.isEmpty())
+ return;
+ mIface = iface;
+ }
+
+ mNetworkInfo.setIsAvailable(true);
+ Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo);
+ msg.sendToTarget();
+
+ runDhcp();
+ }
+
+ private void interfaceRemoved(String iface) {
+ if (!iface.equals(mIface))
+ return;
+
+ Log.d(TAG, "Removing " + iface);
+
+ NetworkUtils.stopDhcp(mIface);
+
+ mLinkProperties.clear();
+ mNetworkInfo.setIsAvailable(false);
+ mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);
+
+ Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo);
+ msg.sendToTarget();
+
+ msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
+ msg.sendToTarget();
+
+ mIface = "";
+ }
+
+ private void runDhcp() {
+ Thread dhcpThread = new Thread(new Runnable() {
+ public void run() {
+ DhcpInfoInternal dhcpInfoInternal = new DhcpInfoInternal();
+ if (!NetworkUtils.runDhcp(mIface, dhcpInfoInternal)) {
+ Log.e(TAG, "DHCP request error:" + NetworkUtils.getDhcpError());
+ return;
+ }
+ mLinkProperties = dhcpInfoInternal.makeLinkProperties();
+ mLinkProperties.setInterfaceName(mIface);
+
+ mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, null);
+ Message msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
+ msg.sendToTarget();
+ }
+ });
+ dhcpThread.start();
+ }
+
+ public static synchronized EthernetDataTracker getInstance() {
+ if (sInstance == null) sInstance = new EthernetDataTracker();
+ return sInstance;
+ }
+
+ public Object Clone() throws CloneNotSupportedException {
+ throw new CloneNotSupportedException();
+ }
+
+ public void setTeardownRequested(boolean isRequested) {
+ mTeardownRequested.set(isRequested);
+ }
+
+ public boolean isTeardownRequested() {
+ return mTeardownRequested.get();
+ }
+
+ /**
+ * Begin monitoring connectivity
+ */
+ public void startMonitoring(Context context, Handler target) {
+ mContext = context;
+ mCsHandler = target;
+
+ // register for notifications from NetworkManagement Service
+ IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+ INetworkManagementService service = INetworkManagementService.Stub.asInterface(b);
+ mInterfaceObserver = new InterfaceObserver(this);
+ try {
+ service.registerObserver(mInterfaceObserver);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Could not register InterfaceObserver " + e);
+ }
+ }
+
+ /**
+ * Disable connectivity to a network
+ * TODO: do away with return value after making MobileDataStateTracker async
+ */
+ public boolean teardown() {
+ mTeardownRequested.set(true);
+ NetworkUtils.stopDhcp(mIface);
+ return true;
+ }
+
+ /**
+ * Re-enable connectivity to a network after a {@link #teardown()}.
+ */
+ public boolean reconnect() {
+ mTeardownRequested.set(false);
+ runDhcp();
+ return true;
+ }
+
+ /**
+ * Turn the wireless radio off for a network.
+ * @param turnOn {@code true} to turn the radio on, {@code false}
+ */
+ public boolean setRadio(boolean turnOn) {
+ return true;
+ }
+
+ /**
+ * @return true - If are we currently tethered with another device.
+ */
+ public synchronized boolean isAvailable() {
+ return mNetworkInfo.isAvailable();
+ }
+
+ /**
+ * Tells the underlying networking system that the caller wants to
+ * begin using the named feature. The interpretation of {@code feature}
+ * is completely up to each networking implementation.
+ * @param feature the name of the feature to be used
+ * @param callingPid the process ID of the process that is issuing this request
+ * @param callingUid the user ID of the process that is issuing this request
+ * @return an integer value representing the outcome of the request.
+ * The interpretation of this value is specific to each networking
+ * implementation+feature combination, except that the value {@code -1}
+ * always indicates failure.
+ * TODO: needs to go away
+ */
+ public int startUsingNetworkFeature(String feature, int callingPid, int callingUid) {
+ return -1;
+ }
+
+ /**
+ * Tells the underlying networking system that the caller is finished
+ * using the named feature. The interpretation of {@code feature}
+ * is completely up to each networking implementation.
+ * @param feature the name of the feature that is no longer needed.
+ * @param callingPid the process ID of the process that is issuing this request
+ * @param callingUid the user ID of the process that is issuing this request
+ * @return an integer value representing the outcome of the request.
+ * The interpretation of this value is specific to each networking
+ * implementation+feature combination, except that the value {@code -1}
+ * always indicates failure.
+ * TODO: needs to go away
+ */
+ public int stopUsingNetworkFeature(String feature, int callingPid, int callingUid) {
+ return -1;
+ }
+
+ /**
+ * @param enabled
+ */
+ public void setDataEnable(boolean enabled) {
+ Log.d(TAG, "setDataEnabled: IGNORING enabled=" + enabled);
+ }
+
+ /**
+ * Check if private DNS route is set for the network
+ */
+ public boolean isPrivateDnsRouteSet() {
+ return mPrivateDnsRouteSet.get();
+ }
+
+ /**
+ * Set a flag indicating private DNS route is set
+ */
+ public void privateDnsRouteSet(boolean enabled) {
+ mPrivateDnsRouteSet.set(enabled);
+ }
+
+ /**
+ * Fetch NetworkInfo for the network
+ */
+ public synchronized NetworkInfo getNetworkInfo() {
+ return mNetworkInfo;
+ }
+
+ /**
+ * Fetch LinkProperties for the network
+ */
+ public synchronized LinkProperties getLinkProperties() {
+ return new LinkProperties(mLinkProperties);
+ }
+
+ /**
+ * A capability is an Integer/String pair, the capabilities
+ * are defined in the class LinkSocket#Key.
+ *
+ * @return a copy of this connections capabilities, may be empty but never null.
+ */
+ public LinkCapabilities getLinkCapabilities() {
+ return new LinkCapabilities(mLinkCapabilities);
+ }
+
+ /**
+ * Fetch default gateway address for the network
+ */
+ public int getDefaultGatewayAddr() {
+ return mDefaultGatewayAddr.get();
+ }
+
+ /**
+ * Check if default route is set
+ */
+ public boolean isDefaultRouteSet() {
+ return mDefaultRouteSet.get();
+ }
+
+ /**
+ * Set a flag indicating default route is set for the network
+ */
+ public void defaultRouteSet(boolean enabled) {
+ mDefaultRouteSet.set(enabled);
+ }
+
+ /**
+ * Return the system properties name associated with the tcp buffer sizes
+ * for this network.
+ */
+ public String getTcpBufferSizesPropName() {
+ return "net.tcp.buffersize.wifi";
+ }
+}
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index ec5030c..e308c2c 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -423,9 +423,16 @@
/**
* Returns whether the device has an external storage device which is
- * emulated. If true, the device does not have real external storage
- * and certain system services such as the package manager use this
+ * emulated. If true, the device does not have real external storage, and the directory
+ * returned by {@link #getExternalStorageDirectory()} will be allocated using a portion of
+ * the internal storage system.
+ *
+ * <p>Certain system services, such as the package manager, use this
* to determine where to install an application.
+ *
+ * <p>Emulated external storage may also be encrypted - see
+ * {@link android.app.admin.DevicePolicyManager#setStorageEncryption(
+ * android.content.ComponentName, boolean)} for additional details.
*/
public static boolean isExternalStorageEmulated() {
if (mIsExternalStorageEmulated == null) {
diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java
index 2b609ea..ad0bc84 100644
--- a/core/java/android/preference/PreferenceActivity.java
+++ b/core/java/android/preference/PreferenceActivity.java
@@ -1049,7 +1049,7 @@
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
transaction.replace(com.android.internal.R.id.prefs, f);
- transaction.commit();
+ transaction.commitAllowingStateLoss();
}
/**
@@ -1144,7 +1144,7 @@
} else {
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
}
- transaction.commit();
+ transaction.commitAllowingStateLoss();
}
/**
@@ -1184,7 +1184,7 @@
}
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
transaction.addToBackStack(BACK_STACK_PREFS);
- transaction.commit();
+ transaction.commitAllowingStateLoss();
}
}
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 186af70..95830ec 100755
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -44,6 +44,8 @@
*/
public class TextToSpeech {
+ private static final String TAG = "TextToSpeech";
+
/**
* Denotes a successful operation.
*/
@@ -579,29 +581,16 @@
mITts.addSpeech(mPackageName, text, packagename, resourceId);
return SUCCESS;
} catch (RemoteException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - addSpeech", "RemoteException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("addSpeech", e);
} catch (NullPointerException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - addSpeech", "NullPointerException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("addSpeech", e);
} catch (IllegalStateException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - addSpeech", "IllegalStateException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("addSpeech", e);
}
return ERROR;
}
}
-
/**
* Adds a mapping between a string of text and a sound file. Using this, it
* is possible to add custom pronounciations for a string of text.
@@ -626,23 +615,11 @@
mITts.addSpeechFile(mPackageName, text, filename);
return SUCCESS;
} catch (RemoteException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - addSpeech", "RemoteException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("addSpeech", e);
} catch (NullPointerException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - addSpeech", "NullPointerException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("addSpeech", e);
} catch (IllegalStateException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - addSpeech", "IllegalStateException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("addSpeech", e);
}
return ERROR;
}
@@ -683,23 +660,11 @@
mITts.addEarcon(mPackageName, earcon, packagename, resourceId);
return SUCCESS;
} catch (RemoteException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - addEarcon", "RemoteException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("addEarcon", e);
} catch (NullPointerException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - addEarcon", "NullPointerException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("addEarcon", e);
} catch (IllegalStateException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - addEarcon", "IllegalStateException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("addEarcon", e);
}
return ERROR;
}
@@ -730,23 +695,11 @@
mITts.addEarconFile(mPackageName, earcon, filename);
return SUCCESS;
} catch (RemoteException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - addEarcon", "RemoteException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("addEarcon", e);
} catch (NullPointerException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - addEarcon", "NullPointerException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("addEarcon", e);
} catch (IllegalStateException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - addEarcon", "IllegalStateException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("addEarcon", e);
}
return ERROR;
}
@@ -790,27 +743,15 @@
}
result = mITts.speak(mPackageName, text, queueMode, mCachedParams);
} catch (RemoteException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - speak", "RemoteException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("speak", e);
} catch (NullPointerException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - speak", "NullPointerException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("speak", e);
} catch (IllegalStateException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - speak", "IllegalStateException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("speak", e);
} finally {
resetCachedParams();
- return result;
}
+ return result;
}
}
@@ -849,27 +790,15 @@
}
result = mITts.playEarcon(mPackageName, earcon, queueMode, null);
} catch (RemoteException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - playEarcon", "RemoteException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("playEarcon", e);
} catch (NullPointerException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - playEarcon", "NullPointerException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("playEarcon", e);
} catch (IllegalStateException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - playEarcon", "IllegalStateException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("playEarcon", e);
} finally {
resetCachedParams();
- return result;
}
+ return result;
}
}
@@ -901,27 +830,15 @@
}
result = mITts.playSilence(mPackageName, durationInMs, queueMode, mCachedParams);
} catch (RemoteException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - playSilence", "RemoteException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("playSilence", e);
} catch (NullPointerException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - playSilence", "NullPointerException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("playSilence", e);
} catch (IllegalStateException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - playSilence", "IllegalStateException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("playSilence", e);
} finally {
resetCachedParams();
- return result;
}
+ return result;
}
}
@@ -939,23 +856,11 @@
try {
return mITts.isSpeaking();
} catch (RemoteException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - isSpeaking", "RemoteException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("isSpeaking", e);
} catch (NullPointerException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - isSpeaking", "NullPointerException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("isSpeaking", e);
} catch (IllegalStateException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - isSpeaking", "IllegalStateException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("isSpeaking", e);
}
return false;
}
@@ -977,26 +882,13 @@
try {
result = mITts.stop(mPackageName);
} catch (RemoteException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - stop", "RemoteException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("stop", e);
} catch (NullPointerException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - stop", "NullPointerException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("stop", e);
} catch (IllegalStateException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - stop", "IllegalStateException");
- e.printStackTrace();
- mStarted = false;
- initTts();
- } finally {
- return result;
+ restart("stop", e);
}
+ return result;
}
}
@@ -1032,20 +924,11 @@
}
}
} catch (NullPointerException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - setSpeechRate", "NullPointerException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("setSpeechRate", e);
} catch (IllegalStateException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - setSpeechRate", "IllegalStateException");
- e.printStackTrace();
- mStarted = false;
- initTts();
- } finally {
- return result;
+ restart("setSpeechRate", e);
}
+ return result;
}
}
@@ -1077,20 +960,11 @@
result = SUCCESS;
}
} catch (NullPointerException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - setPitch", "NullPointerException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("setPitch", e);
} catch (IllegalStateException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - setPitch", "IllegalStateException");
- e.printStackTrace();
- mStarted = false;
- initTts();
- } finally {
- return result;
+ restart("setPitch", e);
}
+ return result;
}
}
@@ -1141,26 +1015,13 @@
}
}
} catch (RemoteException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - setLanguage", "RemoteException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("setLanguage", e);
} catch (NullPointerException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - setLanguage", "NullPointerException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("setLanguage", e);
} catch (IllegalStateException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - setLanguage", "IllegalStateException");
- e.printStackTrace();
- mStarted = false;
- initTts();
- } finally {
- return result;
+ restart("setLanguage", e);
}
+ return result;
}
}
@@ -1191,23 +1052,11 @@
mCachedParams[Engine.PARAM_POSITION_VARIANT + 1]);
}
} catch (RemoteException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - getLanguage", "RemoteException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("getLanguage", e);
} catch (NullPointerException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - getLanguage", "NullPointerException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("getLanguage", e);
} catch (IllegalStateException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - getLanguage", "IllegalStateException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("getLanguage", e);
}
return null;
}
@@ -1233,26 +1082,13 @@
result = mITts.isLanguageAvailable(loc.getISO3Language(),
loc.getISO3Country(), loc.getVariant(), mCachedParams);
} catch (RemoteException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - isLanguageAvailable", "RemoteException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("isLanguageAvailable", e);
} catch (NullPointerException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - isLanguageAvailable", "NullPointerException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("isLanguageAvailable", e);
} catch (IllegalStateException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - isLanguageAvailable", "IllegalStateException");
- e.printStackTrace();
- mStarted = false;
- initTts();
- } finally {
- return result;
+ restart("isLanguageAvailable", e);
}
+ return result;
}
}
@@ -1293,27 +1129,15 @@
result = mITts.synthesizeToFile(mPackageName, text, mCachedParams, filename) ?
SUCCESS : ERROR;
} catch (RemoteException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - synthesizeToFile", "RemoteException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("synthesizeToFile", e);
} catch (NullPointerException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - synthesizeToFile", "NullPointerException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("synthesizeToFile", e);
} catch (IllegalStateException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - synthesizeToFile", "IllegalStateException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("synthesizeToFile", e);
} finally {
resetCachedParams();
- return result;
}
+ return result;
}
}
@@ -1366,26 +1190,13 @@
try {
result = mITts.registerCallback(mPackageName, mITtscallback);
} catch (RemoteException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - registerCallback", "RemoteException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("registerCallback", e);
} catch (NullPointerException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - registerCallback", "NullPointerException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("registerCallback", e);
} catch (IllegalStateException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - registerCallback", "IllegalStateException");
- e.printStackTrace();
- mStarted = false;
- initTts();
- } finally {
- return result;
+ restart("registerCallback", e);
}
+ return result;
}
}
@@ -1409,26 +1220,13 @@
mCachedParams[Engine.PARAM_POSITION_ENGINE + 1] = enginePackageName;
}
} catch (RemoteException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - setEngineByPackageName", "RemoteException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("setEngineByPackageName", e);
} catch (NullPointerException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - setEngineByPackageName", "NullPointerException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("setEngineByPackageName", e);
} catch (IllegalStateException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - setEngineByPackageName", "IllegalStateException");
- e.printStackTrace();
- mStarted = false;
- initTts();
- } finally {
- return result;
+ restart("setEngineByPackageName", e);
}
+ return result;
}
}
@@ -1447,26 +1245,13 @@
try {
engineName = mITts.getDefaultEngine();
} catch (RemoteException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - setEngineByPackageName", "RemoteException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("getDefaultEngine", e);
} catch (NullPointerException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - setEngineByPackageName", "NullPointerException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("getDefaultEngine", e);
} catch (IllegalStateException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - setEngineByPackageName", "IllegalStateException");
- e.printStackTrace();
- mStarted = false;
- initTts();
- } finally {
- return engineName;
+ restart("getDefaultEngine", e);
}
+ return engineName;
}
}
@@ -1486,26 +1271,23 @@
try {
defaultsEnforced = mITts.areDefaultsEnforced();
} catch (RemoteException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - areDefaultsEnforced", "RemoteException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("areDefaultsEnforced", e);
} catch (NullPointerException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - areDefaultsEnforced", "NullPointerException");
- e.printStackTrace();
- mStarted = false;
- initTts();
+ restart("areDefaultsEnforced", e);
} catch (IllegalStateException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - areDefaultsEnforced", "IllegalStateException");
- e.printStackTrace();
- mStarted = false;
- initTts();
- } finally {
- return defaultsEnforced;
+ restart("areDefaultsEnforced", e);
}
+ return defaultsEnforced;
}
}
+
+ /**
+ * Restarts the TTS after a failure.
+ */
+ private void restart(String method, Exception e) {
+ // TTS died; restart it.
+ Log.e(TAG, method, e);
+ mStarted = false;
+ initTts();
+ }
}
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index a826a97..9e48eff 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -235,6 +235,8 @@
} else {
MetricAffectingSpan[] spans =
spanned.getSpans(spanStart, spanEnd, MetricAffectingSpan.class);
+ spans = TextUtils.removeEmptySpans(spans, spanned,
+ MetricAffectingSpan.class);
measured.addStyleRun(paint, spans, spanLen, fm);
}
}
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index 90279d1..1b7f2f3 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -127,12 +127,12 @@
boolean hasReplacement = false;
if (text instanceof Spanned) {
mSpanned = (Spanned) text;
- hasReplacement = mSpanned.getSpans(start, limit,
- ReplacementSpan.class).length > 0;
+ ReplacementSpan[] spans = mSpanned.getSpans(start, limit, ReplacementSpan.class);
+ spans = TextUtils.removeEmptySpans(spans, mSpanned, ReplacementSpan.class);
+ hasReplacement = spans.length > 0;
}
- mCharsValid = hasReplacement || hasTabs ||
- directions != Layout.DIRS_ALL_LEFT_TO_RIGHT;
+ mCharsValid = hasReplacement || hasTabs || directions != Layout.DIRS_ALL_LEFT_TO_RIGHT;
if (mCharsValid) {
if (mChars == null || mChars.length < mLen) {
@@ -147,10 +147,11 @@
// zero-width characters.
char[] chars = mChars;
for (int i = start, inext; i < limit; i = inext) {
- inext = mSpanned.nextSpanTransition(i, limit,
- ReplacementSpan.class);
- if (mSpanned.getSpans(i, inext, ReplacementSpan.class)
- .length > 0) { // transition into a span
+ inext = mSpanned.nextSpanTransition(i, limit, ReplacementSpan.class);
+ ReplacementSpan[] spans = mSpanned.getSpans(i, inext, ReplacementSpan.class);
+ spans = TextUtils.removeEmptySpans(spans, mSpanned, ReplacementSpan.class);
+ if (spans.length > 0) {
+ // transition into a span
chars[i - start] = '\ufffc';
for (int j = i - start + 1, e = inext - start; j < e; ++j) {
chars[j] = '\ufeff'; // used as ZWNBS, marks positions to skip
@@ -197,7 +198,6 @@
boolean runIsRtl = (runs[i+1] & Layout.RUN_RTL_FLAG) != 0;
int segstart = runStart;
- char[] chars = mChars;
for (int j = mHasTabs ? runStart : runLimit; j <= runLimit; j++) {
int codept = 0;
Bitmap bm = null;
@@ -629,6 +629,7 @@
MetricAffectingSpan[] spans = mSpanned.getSpans(mStart + spanStart,
mStart + spanLimit, MetricAffectingSpan.class);
+ spans = TextUtils.removeEmptySpans(spans, mSpanned, MetricAffectingSpan.class);
if (spans.length > 0) {
ReplacementSpan replacement = null;
@@ -835,6 +836,7 @@
mlimit = inext < measureLimit ? inext : measureLimit;
MetricAffectingSpan[] spans = mSpanned.getSpans(mStart + i,
mStart + mlimit, MetricAffectingSpan.class);
+ spans = TextUtils.removeEmptySpans(spans, mSpanned, MetricAffectingSpan.class);
if (spans.length > 0) {
ReplacementSpan replacement = null;
@@ -868,6 +870,7 @@
CharacterStyle[] spans = mSpanned.getSpans(mStart + j,
mStart + jnext, CharacterStyle.class);
+ spans = TextUtils.removeEmptySpans(spans, mSpanned, CharacterStyle.class);
wp.set(mPaint);
for (int k = 0; k < spans.length; k++) {
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index d5010c6..30a1f48 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -44,6 +44,7 @@
import android.text.style.UnderlineSpan;
import android.util.Printer;
+import java.lang.reflect.Array;
import java.util.Iterator;
import java.util.regex.Pattern;
@@ -54,7 +55,7 @@
public static void getChars(CharSequence s, int start, int end,
char[] dest, int destoff) {
- Class c = s.getClass();
+ Class<? extends CharSequence> c = s.getClass();
if (c == String.class)
((String) s).getChars(start, end, dest, destoff);
@@ -75,7 +76,7 @@
}
public static int indexOf(CharSequence s, char ch, int start) {
- Class c = s.getClass();
+ Class<? extends CharSequence> c = s.getClass();
if (c == String.class)
return ((String) s).indexOf(ch, start);
@@ -84,7 +85,7 @@
}
public static int indexOf(CharSequence s, char ch, int start, int end) {
- Class c = s.getClass();
+ Class<? extends CharSequence> c = s.getClass();
if (s instanceof GetChars || c == StringBuffer.class ||
c == StringBuilder.class || c == String.class) {
@@ -125,7 +126,7 @@
}
public static int lastIndexOf(CharSequence s, char ch, int last) {
- Class c = s.getClass();
+ Class<? extends CharSequence> c = s.getClass();
if (c == String.class)
return ((String) s).lastIndexOf(ch, last);
@@ -142,7 +143,7 @@
int end = last + 1;
- Class c = s.getClass();
+ Class<? extends CharSequence> c = s.getClass();
if (s instanceof GetChars || c == StringBuffer.class ||
c == StringBuilder.class || c == String.class) {
@@ -499,6 +500,7 @@
return new String(buf);
}
+ @Override
public String toString() {
return subSequence(0, length()).toString();
}
@@ -621,7 +623,7 @@
* Read and return a new CharSequence, possibly with styles,
* from the parcel.
*/
- public CharSequence createFromParcel(Parcel p) {
+ public CharSequence createFromParcel(Parcel p) {
int kind = p.readInt();
if (kind == 1)
@@ -760,7 +762,7 @@
if (where >= 0)
tb.setSpan(sources[i], where, where + sources[i].length(),
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
for (int i = 0; i < sources.length; i++) {
@@ -1114,7 +1116,6 @@
int remaining = commaCount + 1;
int ok = 0;
- int okRemaining = remaining;
String okFormat = "";
int w = 0;
@@ -1146,7 +1147,6 @@
if (w + moreWid <= avail) {
ok = i + 1;
- okRemaining = remaining;
okFormat = format;
}
}
@@ -1179,6 +1179,7 @@
MetricAffectingSpan.class);
MetricAffectingSpan[] spans = sp.getSpans(
spanStart, spanEnd, MetricAffectingSpan.class);
+ spans = TextUtils.removeEmptySpans(spans, sp, MetricAffectingSpan.class);
width += mt.addStyleRun(paint, spans, spanEnd - spanStart, null);
}
}
@@ -1537,6 +1538,56 @@
return false;
}
+ /**
+ * Removes empty spans from the <code>spans</code> array.
+ *
+ * When parsing a Spanned using {@link Spanned#nextSpanTransition(int, int, Class)}, empty spans
+ * will (correctly) create span transitions, and calling getSpans on a slice of text bounded by
+ * one of these transitions will (correctly) include the empty overlapping span.
+ *
+ * However, these empty spans should not be taken into account when layouting or rendering the
+ * string and this method provides a way to filter getSpans' results accordingly.
+ *
+ * @param spans A list of spans retrieved using {@link Spanned#getSpans(int, int, Class)} from
+ * the <code>spanned</code>
+ * @param spanned The Spanned from which spans were extracted
+ * @return A subset of spans where empty spans ({@link Spanned#getSpanStart(Object)} ==
+ * {@link Spanned#getSpanEnd(Object)} have been removed. The initial order is preserved
+ * @hide
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T[] removeEmptySpans(T[] spans, Spanned spanned, Class<T> klass) {
+ T[] copy = null;
+ int count = 0;
+
+ for (int i = 0; i < spans.length; i++) {
+ final T span = spans[i];
+ final int start = spanned.getSpanStart(span);
+ final int end = spanned.getSpanEnd(span);
+
+ if (start == end) {
+ if (copy == null) {
+ copy = (T[]) Array.newInstance(klass, spans.length - 1);
+ System.arraycopy(spans, 0, copy, 0, i);
+ count = i;
+ }
+ } else {
+ if (copy != null) {
+ copy[count] = span;
+ count++;
+ }
+ }
+ }
+
+ if (copy != null) {
+ T[] result = (T[]) Array.newInstance(klass, count);
+ System.arraycopy(copy, 0, result, 0, count);
+ return result;
+ } else {
+ return spans;
+ }
+ }
+
private static Object sLock = new Object();
private static char[] sTemp = null;
}
diff --git a/core/java/android/util/LruCache.java b/core/java/android/util/LruCache.java
index a1501e6..834dac3 100644
--- a/core/java/android/util/LruCache.java
+++ b/core/java/android/util/LruCache.java
@@ -139,8 +139,7 @@
* Caches {@code value} for {@code key}. The value is moved to the head of
* the queue.
*
- * @return the previous value mapped by {@code key}. Although that entry is
- * no longer cached, it has not been passed to {@link #entryEvicted}.
+ * @return the previous value mapped by {@code key}.
*/
public final V put(K key, V value) {
if (key == null || value == null) {
@@ -195,15 +194,14 @@
evictionCount++;
}
- entryEvicted(key, value);
+ entryRemoved(true, key, value, null);
}
}
/**
* Removes the entry for {@code key} if it exists.
*
- * @return the previous value mapped by {@code key}. Although that entry is
- * no longer cached, it has not been passed to {@link #entryEvicted}.
+ * @return the previous value mapped by {@code key}.
*/
public final V remove(K key) {
if (key == null) {
@@ -226,16 +224,6 @@
}
/**
- * Calls {@link #entryRemoved}.
- *
- * @deprecated replaced by entryRemoved
- */
- @Deprecated
- protected void entryEvicted(K key, V value) {
- entryRemoved(true, key, value, null);
- }
-
- /**
* Called for entries that have been evicted or removed. This method is
* invoked when a value is evicted to make space, removed by a call to
* {@link #remove}, or replaced by a call to {@link #put}. The default
@@ -291,7 +279,7 @@
}
/**
- * Clear the cache, calling {@link #entryEvicted} on each removed entry.
+ * Clear the cache, calling {@link #entryRemoved} on each removed entry.
*/
public final void evictAll() {
trimToSize(-1); // -1 will evict 0-sized elements
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 9a6a274..fa5479b 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -245,11 +245,12 @@
private static native void nDestroyDisplayList(int displayList);
@Override
- public boolean drawDisplayList(DisplayList displayList) {
- return nDrawDisplayList(mRenderer, ((GLES20DisplayList) displayList).mNativeDisplayList);
+ public boolean drawDisplayList(DisplayList displayList, Rect dirty) {
+ return nDrawDisplayList(mRenderer,
+ ((GLES20DisplayList) displayList).mNativeDisplayList, dirty);
}
- private static native boolean nDrawDisplayList(int renderer, int displayList);
+ private static native boolean nDrawDisplayList(int renderer, int displayList, Rect dirty);
///////////////////////////////////////////////////////////////////////////
// Hardware layer
diff --git a/core/java/android/view/GLES20DisplayList.java b/core/java/android/view/GLES20DisplayList.java
index 262eb81..aeff31f 100644
--- a/core/java/android/view/GLES20DisplayList.java
+++ b/core/java/android/view/GLES20DisplayList.java
@@ -40,13 +40,6 @@
hostView = new WeakReference<View>(view);
}
- public void invalidateView() {
- View v = hostView.get();
- if (v != null) {
- v.invalidate();
- }
- }
-
@Override
HardwareCanvas start() {
if (mStarted) {
diff --git a/core/java/android/view/HardwareCanvas.java b/core/java/android/view/HardwareCanvas.java
index e6fecc8..cb1003a 100644
--- a/core/java/android/view/HardwareCanvas.java
+++ b/core/java/android/view/HardwareCanvas.java
@@ -53,8 +53,13 @@
* Draws the specified display list onto this canvas.
*
* @param displayList The display list to replay.
+ * @param dirty The dirty region to redraw in the next pass, matters only
+ * if this method returns true, can be null.
+ *
+ * @return True if the content of the display list requires another
+ * drawing pass (invalidate()), false otherwise
*/
- abstract boolean drawDisplayList(DisplayList displayList);
+ abstract boolean drawDisplayList(DisplayList displayList, Rect dirty);
/**
* Draws the specified layer onto this canvas.
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index b53aa21..0cf7ae6 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -269,7 +269,7 @@
static EGLDisplay sEglDisplay;
static EGLConfig sEglConfig;
- private static Thread sEglThread;
+ private static Thread sEglThread;
EGLSurface mEglSurface;
@@ -284,6 +284,8 @@
final boolean mTranslucent;
private boolean mDestroyed;
+
+ private final Rect mRedrawClip = new Rect();
GlRenderer(int glVersion, boolean translucent) {
mGlVersion = glVersion;
@@ -606,8 +608,13 @@
DisplayList displayList = view.getDisplayList();
if (displayList != null) {
- if (canvas.drawDisplayList(displayList)) {
- view.invalidate();
+ if (canvas.drawDisplayList(displayList, mRedrawClip)) {
+ if (mRedrawClip.isEmpty() || view.getParent() == null) {
+ view.invalidate();
+ } else {
+ view.getParent().invalidateChild(view, mRedrawClip);
+ }
+ mRedrawClip.setEmpty();
}
} else {
// Shouldn't reach here
@@ -646,8 +653,8 @@
private int checkCurrent() {
// TODO: Don't check the current context when we have one per UI thread
// TODO: Use a threadlocal flag to know whether the surface has changed
- if (sEgl.eglGetCurrentContext() != sEglContext ||
- sEgl.eglGetCurrentSurface(EGL10.EGL_DRAW) != mEglSurface) {
+ if (!sEglContext.equals(sEgl.eglGetCurrentContext()) ||
+ !mEglSurface.equals(sEgl.eglGetCurrentSurface(EGL10.EGL_DRAW))) {
if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, sEglContext)) {
fallback(true);
Log.e(LOG_TAG, "eglMakeCurrent failed " +
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index def1161..98d4eb9 100755
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -20,7 +20,9 @@
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.util.SparseArray;
+
+import java.util.ArrayList;
+import java.util.List;
/**
* Describes the capabilities of a particular input device.
@@ -43,8 +45,7 @@
private int mSources;
private int mKeyboardType;
- private final SparseArray<MotionRange> mMotionRanges = new SparseArray<MotionRange>();
- private int[] mMotionAxes;
+ private final ArrayList<MotionRange> mMotionRanges = new ArrayList<MotionRange>();
/**
* A mask for input source classes.
@@ -354,6 +355,11 @@
/**
* Gets information about the range of values for a particular {@link MotionEvent} axis.
+ * If the device supports multiple sources, the same axis may have different meanings
+ * for each source. Returns information about the first axis found for any source.
+ * To obtain information about the axis for a specific source, use
+ * {@link #getMotionRange(int, int)}.
+ *
* @param axis The axis constant.
* @return The range of values, or null if the requested axis is not
* supported by the device.
@@ -363,30 +369,55 @@
* @see #getSupportedAxes()
*/
public MotionRange getMotionRange(int axis) {
- return mMotionRanges.get(axis);
+ final int numRanges = mMotionRanges.size();
+ for (int i = 0; i < numRanges; i++) {
+ final MotionRange range = mMotionRanges.get(i);
+ if (range.mAxis == axis) {
+ return range;
+ }
+ }
+ return null;
}
/**
- * Gets the axis ids of all motion axes supported by this device.
- * @return The axis ids of all motion axes supported by this device.
+ * Gets information about the range of values for a particular {@link MotionEvent} axis
+ * used by a particular source on the device.
+ * If the device supports multiple sources, the same axis may have different meanings
+ * for each source.
*
- * @see #getMotionRange(int)
+ * @param axis The axis constant.
+ * @param source The source for which to return information.
+ * @return The range of values, or null if the requested axis is not
+ * supported by the device.
+ *
+ * @see MotionEvent#AXIS_X
+ * @see MotionEvent#AXIS_Y
+ * @see #getSupportedAxes()
*/
- public int[] getMotionAxes() {
- synchronized (this) {
- if (mMotionAxes == null) {
- final int count = mMotionRanges.size();
- mMotionAxes = new int[count];
- for (int i = 0; i < count; i++) {
- mMotionAxes[i] = mMotionRanges.keyAt(i);
- }
+ public MotionRange getMotionRange(int axis, int source) {
+ final int numRanges = mMotionRanges.size();
+ for (int i = 0; i < numRanges; i++) {
+ final MotionRange range = mMotionRanges.get(i);
+ if (range.mAxis == axis && range.mSource == source) {
+ return range;
}
- return mMotionAxes;
}
+ return null;
}
- private void addMotionRange(int axis, float min, float max, float flat, float fuzz) {
- mMotionRanges.append(axis, new MotionRange(min, max, flat, fuzz));
+ /**
+ * Gets the ranges for all axes supported by the device.
+ * @return The motion ranges for the device.
+ *
+ * @see #getMotionRange(int, int)
+ */
+ public List<MotionRange> getMotionRanges() {
+ return mMotionRanges;
+ }
+
+ private void addMotionRange(int axis, int source,
+ float min, float max, float flat, float fuzz) {
+ mMotionRanges.add(new MotionRange(axis, source, min, max, flat, fuzz));
}
/**
@@ -395,12 +426,16 @@
* @see InputDevice#getMotionRange(int)
*/
public static final class MotionRange {
+ private int mAxis;
+ private int mSource;
private float mMin;
private float mMax;
private float mFlat;
private float mFuzz;
- private MotionRange(float min, float max, float flat, float fuzz) {
+ private MotionRange(int axis, int source, float min, float max, float flat, float fuzz) {
+ mAxis = axis;
+ mSource = source;
mMin = min;
mMax = max;
mFlat = flat;
@@ -408,6 +443,22 @@
}
/**
+ * Gets the axis id.
+ * @return The axis id.
+ */
+ public int getAxis() {
+ return mAxis;
+ }
+
+ /**
+ * Gets the source for which the axis is defined.
+ * @return The source.
+ */
+ public int getSource() {
+ return mSource;
+ }
+
+ /**
* Gets the inclusive minimum value for the axis.
* @return The inclusive minimum value.
*/
@@ -480,7 +531,8 @@
if (axis < 0) {
break;
}
- addMotionRange(axis, in.readFloat(), in.readFloat(), in.readFloat(), in.readFloat());
+ addMotionRange(axis, in.readInt(),
+ in.readFloat(), in.readFloat(), in.readFloat(), in.readFloat());
}
}
@@ -491,11 +543,11 @@
out.writeInt(mSources);
out.writeInt(mKeyboardType);
- final int numAxes = mMotionRanges.size();
- for (int i = 0; i < numAxes; i++) {
- int axis = mMotionRanges.keyAt(i);
- MotionRange range = mMotionRanges.valueAt(i);
- out.writeInt(axis);
+ final int numRanges = mMotionRanges.size();
+ for (int i = 0; i < numRanges; i++) {
+ MotionRange range = mMotionRanges.get(i);
+ out.writeInt(range.mAxis);
+ out.writeInt(range.mSource);
out.writeFloat(range.mMin);
out.writeFloat(range.mMax);
out.writeFloat(range.mFlat);
@@ -528,7 +580,7 @@
}
description.append("\n");
- description.append(" Sources: ").append(Integer.toHexString(mSources)).append(" (");
+ description.append(" Sources: 0x").append(Integer.toHexString(mSources)).append(" (");
appendSourceDescriptionIfApplicable(description, SOURCE_KEYBOARD, "keyboard");
appendSourceDescriptionIfApplicable(description, SOURCE_DPAD, "dpad");
appendSourceDescriptionIfApplicable(description, SOURCE_TOUCHSCREEN, "touchscreen");
@@ -541,10 +593,10 @@
final int numAxes = mMotionRanges.size();
for (int i = 0; i < numAxes; i++) {
- int axis = mMotionRanges.keyAt(i);
- MotionRange range = mMotionRanges.valueAt(i);
- description.append(" ").append(MotionEvent.axisToString(axis));
- description.append(": min=").append(range.mMin);
+ MotionRange range = mMotionRanges.get(i);
+ description.append(" ").append(MotionEvent.axisToString(range.mAxis));
+ description.append(": source=0x").append(Integer.toHexString(range.mSource));
+ description.append(" min=").append(range.mMin);
description.append(" max=").append(range.mMax);
description.append(" flat=").append(range.mFlat);
description.append(" fuzz=").append(range.mFuzz);
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index f70f1fb..a17db5d 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -675,6 +675,87 @@
public static final int AXIS_RTRIGGER = 18;
/**
+ * Constant used to identify the Throttle axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a joystick, reports the absolute position of the throttle control.
+ * The value is normalized to a range from 0.0 (fully open) to 1.0 (fully closed).
+ * </ul>
+ * </p>
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_THROTTLE = 19;
+
+ /**
+ * Constant used to identify the Rudder axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a joystick, reports the absolute position of the rudder control.
+ * The value is normalized to a range from -1.0 (turn left) to 1.0 (turn right).
+ * </ul>
+ * </p>
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_RUDDER = 20;
+
+ /**
+ * Constant used to identify the Wheel axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a joystick, reports the absolute position of the steering wheel control.
+ * The value is normalized to a range from -1.0 (turn left) to 1.0 (turn right).
+ * </ul>
+ * </p>
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_WHEEL = 21;
+
+ /**
+ * Constant used to identify the Gas axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a joystick, reports the absolute position of the gas (accelerator) control.
+ * The value is normalized to a range from 0.0 (no acceleration)
+ * to 1.0 (maximum acceleration).
+ * </ul>
+ * </p>
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GAS = 22;
+
+ /**
+ * Constant used to identify the Brake axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a joystick, reports the absolute position of the brake control.
+ * The value is normalized to a range from 0.0 (no braking) to 1.0 (maximum braking).
+ * </ul>
+ * </p>
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_BRAKE = 23;
+
+ /**
* Constant used to identify the Generic 1 axis of a motion event.
* The interpretation of a generic axis is device-specific.
*
@@ -877,6 +958,11 @@
names.append(AXIS_HAT_Y, "AXIS_HAT_Y");
names.append(AXIS_LTRIGGER, "AXIS_LTRIGGER");
names.append(AXIS_RTRIGGER, "AXIS_RTRIGGER");
+ names.append(AXIS_THROTTLE, "AXIS_THROTTLE");
+ names.append(AXIS_RUDDER, "AXIS_RUDDER");
+ names.append(AXIS_WHEEL, "AXIS_WHEEL");
+ names.append(AXIS_GAS, "AXIS_GAS");
+ names.append(AXIS_BRAKE, "AXIS_BRAKE");
names.append(AXIS_GENERIC_1, "AXIS_GENERIC_1");
names.append(AXIS_GENERIC_2, "AXIS_GENERIC_2");
names.append(AXIS_GENERIC_3, "AXIS_GENERIC_3");
diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java
index 0124151..5521e92 100644
--- a/core/java/android/view/ScaleGestureDetector.java
+++ b/core/java/android/view/ScaleGestureDetector.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.util.DisplayMetrics;
import android.util.FloatMath;
+import android.util.Log;
/**
* Detects transformation gestures involving more than one pointer ("multitouch")
@@ -36,6 +37,8 @@
* </ul>
*/
public class ScaleGestureDetector {
+ private static final String TAG = "ScaleGestureDetector";
+
/**
* The listener for receiving notifications when gestures occur.
* If you want to listen for all the different gestures then implement
@@ -170,6 +173,10 @@
final int action = event.getActionMasked();
boolean handled = true;
+ if (action == MotionEvent.ACTION_DOWN) {
+ reset(); // Start fresh
+ }
+
if (!mGestureInProgress) {
switch (action) {
case MotionEvent.ACTION_DOWN: {
@@ -197,6 +204,11 @@
int index1 = event.getActionIndex();
int index0 = event.findPointerIndex(mActiveId0);
mActiveId1 = event.getPointerId(index1);
+ if (index0 < 0 || index0 == index1) {
+ // Probably someone sending us a broken event stream.
+ index0 = findNewActiveIndex(event, index0 == index1 ? -1 : mActiveId1, index0);
+ mActiveId0 = event.getPointerId(index0);
+ }
mActive0MostRecent = false;
setContext(event);
@@ -315,6 +327,7 @@
final int index = event.findPointerIndex(actionId == mActiveId0 ?
mActiveId1 : mActiveId0);
mActiveId0 = event.getPointerId(index);
+
mActive0MostRecent = true;
mActiveId1 = -1;
mFocusX = event.getX(index);
@@ -338,6 +351,18 @@
mActiveId1 = event.getPointerId(event.getActionIndex());
mActive0MostRecent = false;
+ int index0 = event.findPointerIndex(mActiveId0);
+ if (index0 < 0 || mActiveId0 == mActiveId1) {
+ // Probably someone sending us a broken event stream.
+ Log.e(TAG, "Got " + MotionEvent.actionToString(action) +
+ " with bad state while a gesture was in progress. " +
+ "Did you forget to pass an event to " +
+ "ScaleGestureDetector#onTouchEvent?");
+ index0 = findNewActiveIndex(event,
+ mActiveId0 == mActiveId1 ? -1 : mActiveId1, index0);
+ mActiveId0 = event.getPointerId(index0);
+ }
+
setContext(event);
mGestureInProgress = mListener.onScaleBegin(this);
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 3153ac5..f9692da 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -2585,7 +2585,7 @@
}
} else {
child.mPrivateFlags &= ~DIRTY_MASK;
- ((HardwareCanvas) canvas).drawDisplayList(displayList);
+ ((HardwareCanvas) canvas).drawDisplayList(displayList, null);
}
}
} else if (cache != null) {
@@ -3680,7 +3680,7 @@
// flag coming from the child that initiated the invalidate
if (view != null) {
if ((view.mViewFlags & FADING_EDGE_MASK) != 0 &&
- view.getSolidColor() == 0 && !view.isOpaque()) {
+ view.getSolidColor() == 0) {
opaqueFlag = DIRTY;
}
if ((view.mPrivateFlags & DIRTY_MASK) != DIRTY) {
@@ -4275,11 +4275,10 @@
* does not exist within the group
*/
public View getChildAt(int index) {
- try {
- return mChildren[index];
- } catch (IndexOutOfBoundsException ex) {
+ if (index < 0 || index >= mChildrenCount) {
return null;
}
+ return mChildren[index];
}
/**
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 5468230..a53c6d0 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -498,15 +498,21 @@
mAttachInfo.mHardwareAccelerationRequested = false;
// Try to enable hardware acceleration if requested
- if (attrs != null &&
- (attrs.flags & WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0) {
+ final boolean hardwareAccelerated =
+ (attrs.flags & WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
+
+ if (attrs != null && hardwareAccelerated) {
// Only enable hardware acceleration if we are not in the system process
// The window manager creates ViewRoots to display animated preview windows
// of launching apps and we don't want those to be hardware accelerated
- if (!HardwareRenderer.sRendererDisabled) {
+
+ final boolean systemHwAccelerated =
+ (attrs.flags & WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED_SYSTEM) != 0;
+
+ if (!HardwareRenderer.sRendererDisabled || systemHwAccelerated) {
// Don't enable hardware acceleration when we're not on the main thread
- if (Looper.getMainLooper() != Looper.myLooper()) {
- Log.w(HardwareRenderer.LOG_TAG, "Attempting to initialize hardware "
+ if (!systemHwAccelerated && Looper.getMainLooper() != Looper.myLooper()) {
+ Log.w(HardwareRenderer.LOG_TAG, "Attempting to initialize hardware "
+ "acceleration outside of the main thread, aborting");
return;
}
@@ -1606,13 +1612,9 @@
return;
} catch (IllegalArgumentException e) {
Log.e(TAG, "IllegalArgumentException locking surface", e);
- try {
- if (!sWindowSession.outOfMemory(mWindow)) {
- Slog.w(TAG, "No processes killed for memory; killing self");
- Process.killProcess(Process.myPid());
- }
- } catch (RemoteException ex) {
- }
+ // Don't assume this is due to out of memory, it could be
+ // something else, and if it is something else then we could
+ // kill stuff (or ourself) for no reason.
mLayoutRequested = true; // ask wm for a new surface next time.
return;
}
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index ca932e9..8a18aaf 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -665,6 +665,17 @@
* XML attribute is set to true on an activity or on the application.</p>
*/
public static final int FLAG_HARDWARE_ACCELERATED = 0x01000000;
+
+ /**
+ * Like {@link #FLAG_HARDWARE_ACCELERATED} except for trusted system windows
+ * that need hardware acceleration (e.g. LockScreen), where hardware acceleration
+ * is generally disabled. This flag must be specified in addition to
+ * {@link #FLAG_HARDWARE_ACCELERATED} to enable hardware acceleration for system
+ * windows.
+ *
+ * @hide
+ */
+ public static final int FLAG_HARDWARE_ACCELERATED_SYSTEM = 0x02000000;
// ----- HIDDEN FLAGS.
// These start at the high bit and go down.
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 24c0e68..6306274 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -1240,11 +1240,17 @@
}
}
-
/*package*/ SearchBox getSearchBox() {
return mSearchBox;
}
+ /**
+ * Called by JNI when processing the X-Auto-Login header.
+ */
+ private void autoLogin(String realm, String account, String args) {
+ mCallbackProxy.onReceivedLoginRequest(realm, account, args);
+ }
+
//==========================================================================
// native functions
//==========================================================================
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index c66d701..23fd12d 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -117,6 +117,7 @@
private static final int AUTH_CREDENTIALS = 137;
private static final int SET_INSTALLABLE_WEBAPP = 138;
private static final int NOTIFY_SEARCHBOX_LISTENERS = 139;
+ private static final int AUTO_LOGIN = 140;
// Message triggered by the client to resume execution
private static final int NOTIFY = 200;
@@ -770,7 +771,7 @@
(WebHistoryItem) msg.obj, msg.arg1);
}
break;
- case AUTH_CREDENTIALS:
+ case AUTH_CREDENTIALS: {
String host = msg.getData().getString("host");
String realm = msg.getData().getString("realm");
username = msg.getData().getString("username");
@@ -778,6 +779,7 @@
mWebView.setHttpAuthUsernamePassword(
host, realm, username, password);
break;
+ }
case SET_INSTALLABLE_WEBAPP:
if (mWebChromeClient != null) {
mWebChromeClient.setInstallableWebApp();
@@ -789,6 +791,17 @@
@SuppressWarnings("unchecked")
List<String> suggestions = (List<String>) msg.obj;
searchBox.handleSuggestions(msg.getData().getString("query"), suggestions);
+ break;
+ case AUTO_LOGIN: {
+ if (mWebViewClient != null) {
+ String realm = msg.getData().getString("realm");
+ String account = msg.getData().getString("account");
+ String args = msg.getData().getString("args");
+ mWebViewClient.onReceivedLoginRequest(mWebView, realm,
+ account, args);
+ }
+ break;
+ }
}
}
@@ -1051,6 +1064,20 @@
sendMessage(msg);
}
+ void onReceivedLoginRequest(String realm, String account, String args) {
+ // Do an unsynchronized quick check to avoid posting if no callback has
+ // been set.
+ if (mWebViewClient == null) {
+ return;
+ }
+ Message msg = obtainMessage(AUTO_LOGIN);
+ Bundle bundle = msg.getData();
+ bundle.putString("realm", realm);
+ bundle.putString("account", account);
+ bundle.putString("args", args);
+ sendMessage(msg);
+ }
+
//--------------------------------------------------------------------------
// DownloadListener functions.
//--------------------------------------------------------------------------
diff --git a/core/java/android/webkit/DebugFlags.java b/core/java/android/webkit/DebugFlags.java
index 2dac7e9..3cb5e24 100644
--- a/core/java/android/webkit/DebugFlags.java
+++ b/core/java/android/webkit/DebugFlags.java
@@ -31,7 +31,7 @@
public static final boolean CACHE_MANAGER = false;
public static final boolean CALLBACK_PROXY = false;
public static final boolean COOKIE_MANAGER = false;
- public static final boolean COOKIE_SYNC_MANAGER = true;
+ public static final boolean COOKIE_SYNC_MANAGER = false;
public static final boolean FRAME_LOADER = false;
public static final boolean J_WEB_CORE_JAVA_BRIDGE = false;// HIGHLY VERBOSE
public static final boolean LOAD_LISTENER = false;
@@ -41,7 +41,7 @@
public static final boolean URL_UTIL = false;
public static final boolean WEB_BACK_FORWARD_LIST = false;
public static final boolean WEB_SETTINGS = false;
- public static final boolean WEB_SYNC_MANAGER = true;
+ public static final boolean WEB_SYNC_MANAGER = false;
public static final boolean WEB_TEXT_VIEW = false;
public static final boolean WEB_VIEW = false;
public static final boolean WEB_VIEW_CORE = false;
diff --git a/core/java/android/webkit/HTML5VideoView.java b/core/java/android/webkit/HTML5VideoView.java
new file mode 100644
index 0000000..2312160
--- /dev/null
+++ b/core/java/android/webkit/HTML5VideoView.java
@@ -0,0 +1,211 @@
+
+package android.webkit;
+
+import android.graphics.SurfaceTexture;
+import android.media.MediaPlayer;
+import android.util.Log;
+import android.webkit.HTML5VideoViewProxy;
+import android.widget.MediaController;
+import android.opengl.GLES20;
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * @hide This is only used by the browser
+ */
+public class HTML5VideoView implements MediaPlayer.OnPreparedListener{
+ // Due to the fact that SurfaceTexture consume a lot of memory, we make it
+ // as static. m_textureNames is the texture bound with this SurfaceTexture.
+ private static SurfaceTexture mSurfaceTexture = null;
+ private static int[] mTextureNames;
+
+ // Only when the video is prepared, we render using SurfaceTexture.
+ // This in fact is used to avoid showing the obsolete content when
+ // switching videos.
+ private static boolean mReadyToUseSurfTex = false;
+
+ // For handling the seekTo before prepared, we need to know whether or not
+ // the video is prepared. Therefore, we differentiate the state between
+ // prepared and not prepared.
+ // When the video is not prepared, we will have to save the seekTo time,
+ // and use it when prepared to play.
+ private static final int STATE_NOTPREPARED = 0;
+ private static final int STATE_PREPARED = 1;
+
+ // We only need state for handling seekTo
+ private int mCurrentState;
+
+ // Basically for calling back the OnPrepared in the proxy
+ private HTML5VideoViewProxy mProxy;
+
+ // Save the seek time when not prepared. This can happen when switching
+ // video besides initial load.
+ private int mSaveSeekTime;
+
+ // This is used to find the VideoLayer on the native side.
+ private int mVideoLayerId;
+
+ // Every video will have one MediaPlayer. Given the fact we only have one
+ // SurfaceTexture, there is only one MediaPlayer in action. Every time we
+ // switch videos, a new instance of MediaPlayer will be created in reset().
+ private MediaPlayer mPlayer;
+
+ private static HTML5VideoView mInstance = new HTML5VideoView();
+
+ // Video control FUNCTIONS:
+ public void start() {
+ if (mCurrentState == STATE_PREPARED) {
+ mPlayer.start();
+ mReadyToUseSurfTex = true;
+ }
+ }
+
+ public void pause() {
+ mPlayer.pause();
+ }
+
+ public int getDuration() {
+ return mPlayer.getDuration();
+ }
+
+ public int getCurrentPosition() {
+ return mPlayer.getCurrentPosition();
+ }
+
+ public void seekTo(int pos) {
+ if (mCurrentState == STATE_PREPARED)
+ mPlayer.seekTo(pos);
+ else
+ mSaveSeekTime = pos;
+ }
+
+ public boolean isPlaying() {
+ return mPlayer.isPlaying();
+ }
+
+ public void release() {
+ mPlayer.release();
+ }
+
+ public void stopPlayback() {
+ mPlayer.stop();
+ }
+
+ private void reset(int videoLayerId) {
+ mPlayer = new MediaPlayer();
+ mCurrentState = STATE_NOTPREPARED;
+ mProxy = null;
+ mVideoLayerId = videoLayerId;
+ mReadyToUseSurfTex = false;
+ }
+
+ public static HTML5VideoView getInstance(int videoLayerId) {
+ // Every time we switch between the videos, a new MediaPlayer will be
+ // created. Make sure we call the m_player.release() when it is done.
+ mInstance.reset(videoLayerId);
+ return mInstance;
+ }
+
+ private HTML5VideoView() {
+ // This is a singleton across WebViews (i.e. Tabs).
+ // HTML5VideoViewProxy will reset the internal state every time a new
+ // video start.
+ }
+
+ public void setMediaController(MediaController m) {
+ this.setMediaController(m);
+ }
+
+ public void setVideoURI(String uri, Map<String, String> headers) {
+ // When switching players, surface texture will be reused.
+ mPlayer.setTexture(getSurfaceTextureInstance());
+
+ // When there is exception, we could just bail out silently.
+ // No Video will be played though. Write the stack for debug
+ try {
+ mPlayer.setDataSource(uri, headers);
+ mPlayer.prepareAsync();
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ } catch (IllegalStateException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ // TODO [FULL SCREEN SUPPORT]
+
+ // Listeners setup FUNCTIONS:
+ public void setOnCompletionListener(HTML5VideoViewProxy proxy) {
+ mPlayer.setOnCompletionListener(proxy);
+ }
+
+ public void setOnErrorListener(HTML5VideoViewProxy proxy) {
+ mPlayer.setOnErrorListener(proxy);
+ }
+
+ public void setOnPreparedListener(HTML5VideoViewProxy proxy) {
+ mProxy = proxy;
+ mPlayer.setOnPreparedListener(this);
+ }
+
+ // Inline Video specific FUNCTIONS:
+
+ public SurfaceTexture getSurfaceTexture() {
+ return mSurfaceTexture;
+ }
+
+ public void deleteSurfaceTexture() {
+ mSurfaceTexture = null;
+ return;
+ }
+
+ // SurfaceTexture is a singleton here , too
+ private SurfaceTexture getSurfaceTextureInstance() {
+ // Create the surface texture.
+ if (mSurfaceTexture == null)
+ {
+ mTextureNames = new int[1];
+ GLES20.glGenTextures(1, mTextureNames, 0);
+ mSurfaceTexture = new SurfaceTexture(mTextureNames[0]);
+ }
+ return mSurfaceTexture;
+ }
+
+ public int getTextureName() {
+ return mTextureNames[0];
+ }
+
+ public int getVideoLayerId() {
+ return mVideoLayerId;
+ }
+
+ public boolean getReadyToUseSurfTex() {
+ return mReadyToUseSurfTex;
+ }
+
+ public void setFrameAvailableListener(SurfaceTexture.OnFrameAvailableListener l) {
+ mSurfaceTexture.setOnFrameAvailableListener(l);
+ }
+
+ @Override
+ public void onPrepared(MediaPlayer mp) {
+ mCurrentState = STATE_PREPARED;
+ seekTo(mSaveSeekTime);
+ if (mProxy != null)
+ mProxy.onPrepared(mp);
+ }
+
+ // Pause the play and update the play/pause button
+ public void pauseAndDispatch(HTML5VideoViewProxy proxy) {
+ if (isPlaying()) {
+ pause();
+ if (proxy != null) {
+ proxy.dispatchOnPaused();
+ }
+ }
+ mReadyToUseSurfTex = false;
+ }
+
+}
diff --git a/core/java/android/webkit/HTML5VideoViewProxy.java b/core/java/android/webkit/HTML5VideoViewProxy.java
index 85763da..b614d8f 100644
--- a/core/java/android/webkit/HTML5VideoViewProxy.java
+++ b/core/java/android/webkit/HTML5VideoViewProxy.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
+import android.graphics.SurfaceTexture;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnPreparedListener;
import android.media.MediaPlayer.OnCompletionListener;
@@ -59,7 +60,8 @@
class HTML5VideoViewProxy extends Handler
implements MediaPlayer.OnPreparedListener,
MediaPlayer.OnCompletionListener,
- MediaPlayer.OnErrorListener {
+ MediaPlayer.OnErrorListener,
+ SurfaceTexture.OnFrameAvailableListener {
// Logging tag.
private static final String LOGTAG = "HTML5VideoViewProxy";
@@ -101,7 +103,7 @@
private static HTML5VideoViewProxy mCurrentProxy;
// The VideoView instance. This is a singleton for now, at least until
// http://b/issue?id=1973663 is fixed.
- private static VideoView mVideoView;
+ private static HTML5VideoView mHTML5VideoView;
// The progress view.
private static View mProgressView;
// The container for the progress view and video view
@@ -122,131 +124,149 @@
}
// The spec says the timer should fire every 250 ms or less.
private static final int TIMEUPDATE_PERIOD = 250; // ms
- static boolean isVideoSelfEnded = false;
+ private static boolean isVideoSelfEnded = false;
+ // By using the baseLayer and the current video Layer ID, we can
+ // identify the exact layer on the UI thread to use the SurfaceTexture.
+ private static int mBaseLayer = 0;
- private static final WebChromeClient.CustomViewCallback mCallback =
- new WebChromeClient.CustomViewCallback() {
- public void onCustomViewHidden() {
- // At this point the videoview is pretty much destroyed.
- // It listens to SurfaceHolder.Callback.SurfaceDestroyed event
- // which happens when the video view is detached from its parent
- // view. This happens in the WebChromeClient before this method
- // is invoked.
- mTimer.cancel();
- mTimer = null;
- if (mVideoView.isPlaying()) {
- mVideoView.stopPlayback();
+ // TODO: [FULL SCREEN SUPPORT]
+
+ // Every time webView setBaseLayer, this will be called.
+ // When we found the Video layer, then we set the Surface Texture to it.
+ // Otherwise, we may want to delete the Surface Texture to save memory.
+ public static void setBaseLayer(int layer) {
+ if (mHTML5VideoView != null) {
+ mBaseLayer = layer;
+ SurfaceTexture surfTexture = mHTML5VideoView.getSurfaceTexture();
+ int textureName = mHTML5VideoView.getTextureName();
+
+ int currentVideoLayerId = mHTML5VideoView.getVideoLayerId();
+ if (layer != 0 && surfTexture != null && currentVideoLayerId != -1) {
+ boolean readyToUseSurfTex =
+ mHTML5VideoView.getReadyToUseSurfTex();
+ boolean foundInTree = nativeSendSurfaceTexture(surfTexture,
+ layer, currentVideoLayerId, textureName,
+ readyToUseSurfTex);
+ if (readyToUseSurfTex && !foundInTree) {
+ mHTML5VideoView.pauseAndDispatch(mCurrentProxy);
+ mHTML5VideoView.deleteSurfaceTexture();
}
- if (isVideoSelfEnded)
- mCurrentProxy.dispatchOnEnded();
- else
- mCurrentProxy.dispatchOnPaused();
-
- // Re enable plugin views.
- mCurrentProxy.getWebView().getViewManager().showAll();
-
- isVideoSelfEnded = false;
- mCurrentProxy = null;
- mLayout.removeView(mVideoView);
- mVideoView = null;
- if (mProgressView != null) {
- mLayout.removeView(mProgressView);
- mProgressView = null;
- }
- mLayout = null;
}
- };
-
- public static void play(String url, int time, HTML5VideoViewProxy proxy,
- WebChromeClient client) {
- if (mCurrentProxy == proxy) {
- if (!mVideoView.isPlaying()) {
- mVideoView.start();
- }
- return;
}
+ }
- if (mCurrentProxy != null) {
+ // When a WebView is paused, we also want to pause the video in it.
+ public static void pauseAndDispatch() {
+ if (mHTML5VideoView != null) {
+ mHTML5VideoView.pauseAndDispatch(mCurrentProxy);
+ // When switching out, clean the video content on the old page
+ // by telling the layer not readyToUseSurfTex.
+ setBaseLayer(mBaseLayer);
+ }
+ }
+
+ // This is on the UI thread.
+ // When native tell Java to play, we need to check whether or not it is
+ // still the same video by using videoLayerId and treat it differently.
+ public static void play(String url, int time, HTML5VideoViewProxy proxy,
+ WebChromeClient client, int videoLayerId) {
+ int currentVideoLayerId = -1;
+ if (mHTML5VideoView != null)
+ currentVideoLayerId = mHTML5VideoView.getVideoLayerId();
+
+ if (currentVideoLayerId != videoLayerId
+ || mHTML5VideoView.getSurfaceTexture() == null) {
+ // Here, we handle the case when switching to a new video,
+ // either inside a WebView or across WebViews
+ // For switching videos within a WebView or across the WebView,
+ // we need to pause the old one and re-create a new media player
+ // inside the HTML5VideoView.
+ if (mHTML5VideoView != null) {
+ mHTML5VideoView.pauseAndDispatch(mCurrentProxy);
+ // release the media player to avoid finalize error
+ mHTML5VideoView.release();
+ }
+ // HTML5VideoView is singleton, however, the internal state will
+ // be reset since we are switching from one video to another.
+ // Then we need to set up all the source/listener etc...
+ mHTML5VideoView = HTML5VideoView.getInstance(videoLayerId);
+
+ mCurrentProxy = proxy;
+
+ // TODO: [FULL SCREEN SUPPORT]
+
+ boolean isPrivate = mCurrentProxy.getWebView().isPrivateBrowsingEnabled();
+ String cookieValue = CookieManager.getInstance().getCookie(url, isPrivate);
+ Map<String, String> headers = new HashMap<String, String>();
+ if (cookieValue != null) {
+ headers.put(COOKIE, cookieValue);
+ }
+ if (isPrivate) {
+ headers.put(HIDE_URL_LOGS, "true");
+ }
+
+ mHTML5VideoView.setVideoURI(url, headers);
+ mHTML5VideoView.setOnCompletionListener(proxy);
+ mHTML5VideoView.setOnPreparedListener(proxy);
+ mHTML5VideoView.setOnErrorListener(proxy);
+ mHTML5VideoView.setFrameAvailableListener(proxy);
+
+ mHTML5VideoView.seekTo(time);
+
+ mTimer = new Timer();
+
+ } else if (mCurrentProxy == proxy) {
+ // Here, we handle the case when we keep playing with one video
+ if (!mHTML5VideoView.isPlaying()) {
+ mHTML5VideoView.seekTo(time);
+ mHTML5VideoView.start();
+ }
+ } else if (mCurrentProxy != null) {
// Some other video is already playing. Notify the caller that its playback ended.
proxy.dispatchOnEnded();
- return;
}
-
- mCurrentProxy = proxy;
- // Create a FrameLayout that will contain the VideoView and the
- // progress view (if any).
- mLayout = new FrameLayout(proxy.getContext());
- FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT,
- ViewGroup.LayoutParams.WRAP_CONTENT,
- Gravity.CENTER);
- mVideoView = new VideoView(proxy.getContext());
- mVideoView.setWillNotDraw(false);
- mVideoView.setMediaController(new MediaController(proxy.getContext()));
-
- boolean isPrivate = mCurrentProxy.getWebView().isPrivateBrowsingEnabled();
- String cookieValue = CookieManager.getInstance().getCookie(url, isPrivate);
- Map<String, String> headers = new HashMap<String, String>();
- if (cookieValue != null) {
- headers.put(COOKIE, cookieValue);
- }
- if (isPrivate) {
- headers.put(HIDE_URL_LOGS, "true");
- }
-
- mVideoView.setVideoURI(Uri.parse(url), headers);
- mVideoView.setOnCompletionListener(proxy);
- mVideoView.setOnPreparedListener(proxy);
- mVideoView.setOnErrorListener(proxy);
- mVideoView.seekTo(time);
- mLayout.addView(mVideoView, layoutParams);
- mProgressView = client.getVideoLoadingProgressView();
- if (mProgressView != null) {
- mLayout.addView(mProgressView, layoutParams);
- mProgressView.setVisibility(View.VISIBLE);
- }
- mLayout.setVisibility(View.VISIBLE);
- mTimer = new Timer();
- mVideoView.start();
- client.onShowCustomView(mLayout, mCallback);
- // Plugins like Flash will draw over the video so hide
- // them while we're playing.
- mCurrentProxy.getWebView().getViewManager().hideAll();
}
public static boolean isPlaying(HTML5VideoViewProxy proxy) {
- return (mCurrentProxy == proxy && mVideoView != null && mVideoView.isPlaying());
+ return (mCurrentProxy == proxy && mHTML5VideoView != null
+ && mHTML5VideoView.isPlaying());
}
public static int getCurrentPosition() {
int currentPosMs = 0;
- if (mVideoView != null) {
- currentPosMs = mVideoView.getCurrentPosition();
+ if (mHTML5VideoView != null) {
+ currentPosMs = mHTML5VideoView.getCurrentPosition();
}
return currentPosMs;
}
public static void seek(int time, HTML5VideoViewProxy proxy) {
- if (mCurrentProxy == proxy && time >= 0 && mVideoView != null) {
- mVideoView.seekTo(time);
+ if (mCurrentProxy == proxy && time >= 0 && mHTML5VideoView != null) {
+ mHTML5VideoView.seekTo(time);
}
}
public static void pause(HTML5VideoViewProxy proxy) {
- if (mCurrentProxy == proxy && mVideoView != null) {
- mVideoView.pause();
+ if (mCurrentProxy == proxy && mHTML5VideoView != null) {
+ mHTML5VideoView.pause();
mTimer.purge();
}
}
public static void onPrepared() {
- if (mProgressView == null || mLayout == null) {
- return;
- }
+ mHTML5VideoView.start();
mTimer.schedule(new TimeupdateTask(mCurrentProxy), TIMEUPDATE_PERIOD, TIMEUPDATE_PERIOD);
- mProgressView.setVisibility(View.GONE);
- mLayout.removeView(mProgressView);
- mProgressView = null;
+ // TODO: [FULL SCREEN SUPPORT]
+ }
+
+ public static void end() {
+ if (mCurrentProxy != null) {
+ if (isVideoSelfEnded)
+ mCurrentProxy.dispatchOnEnded();
+ else
+ mCurrentProxy.dispatchOnPaused();
+ }
+ isVideoSelfEnded = false;
}
}
@@ -292,6 +312,14 @@
sendMessage(obtainMessage(TIMEUPDATE));
}
+ // When there is a frame ready from surface texture, we should tell WebView
+ // to refresh.
+ @Override
+ public void onFrameAvailable(SurfaceTexture surfaceTexture) {
+ // TODO: This should support partial invalidation too.
+ mWebView.invalidate();
+ }
+
// Handler for the messages from WebCore or Timer thread to the UI thread.
@Override
public void handleMessage(Message msg) {
@@ -300,8 +328,9 @@
case PLAY: {
String url = (String) msg.obj;
WebChromeClient client = mWebView.getWebChromeClient();
+ int videoLayerID = msg.arg1;
if (client != null) {
- VideoPlayer.play(url, mSeekPosition, this, client);
+ VideoPlayer.play(url, mSeekPosition, this, client, videoLayerID);
}
break;
}
@@ -318,6 +347,10 @@
case ENDED:
if (msg.arg1 == 1)
VideoPlayer.isVideoSelfEnded = true;
+ VideoPlayer.end();
+ break;
+ // TODO: [FULL SCREEN SUPPORT]
+ // For full screen case, end may need hide the view.
case ERROR: {
WebChromeClient client = mWebView.getWebChromeClient();
if (client != null) {
@@ -500,6 +533,10 @@
super(Looper.getMainLooper());
// Save the WebView object.
mWebView = webView;
+ // Pass Proxy into webview, such that every time we have a setBaseLayer
+ // call, we tell this Proxy to call the native to update the layer tree
+ // for the Video Layer's surface texture info
+ mWebView.setHTML5VideoViewProxy(this);
// Save the native ptr
mNativePointer = nativePtr;
// create the message handler for this thread
@@ -565,7 +602,7 @@
* Play a video stream.
* @param url is the URL of the video stream.
*/
- public void play(String url, int position) {
+ public void play(String url, int position, int videoLayerID) {
if (url == null) {
return;
}
@@ -573,8 +610,8 @@
if (position > 0) {
seek(position);
}
-
Message message = obtainMessage(PLAY);
+ message.arg1 = videoLayerID;
message.obj = url;
sendMessage(message);
}
@@ -628,6 +665,14 @@
mPosterDownloader.start();
}
+ // These two function are called from UI thread only by WebView.
+ public void setBaseLayer(int layer) {
+ VideoPlayer.setBaseLayer(layer);
+ }
+
+ public void pauseAndDispatch() {
+ VideoPlayer.pauseAndDispatch();
+ }
/**
* The factory for HTML5VideoViewProxy instances.
* @param webViewCore is the WebViewCore that is requesting the proxy.
@@ -647,4 +692,7 @@
private native void nativeOnPaused(int nativePointer);
private native void nativeOnPosterFetched(Bitmap poster, int nativePointer);
private native void nativeOnTimeupdate(int position, int nativePointer);
+ private native static boolean nativeSendSurfaceTexture(SurfaceTexture texture,
+ int baseLayer, int videoLayerId, int textureName,
+ boolean updateTexture);
}
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 28b09519..7f4f103 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -26,14 +26,15 @@
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
+import android.os.ResultReceiver;
import android.text.BoringLayout.Metrics;
import android.text.DynamicLayout;
import android.text.Editable;
import android.text.InputFilter;
import android.text.Layout;
-import android.text.Layout.Alignment;
import android.text.Selection;
import android.text.Spannable;
import android.text.TextPaint;
@@ -50,8 +51,8 @@
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputConnection;
+import android.view.inputmethod.InputMethodManager;
import android.widget.AbsoluteLayout.LayoutParams;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
@@ -136,6 +137,23 @@
// Used to determine whether onFocusChanged was called as a result of
// calling remove().
private boolean mInsideRemove;
+ private class MyResultReceiver extends ResultReceiver {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ if (resultCode == InputMethodManager.RESULT_SHOWN
+ && mWebView != null) {
+ mWebView.revealSelection();
+ }
+ }
+
+ /**
+ * @param handler
+ */
+ public MyResultReceiver(Handler handler) {
+ super(handler);
+ }
+ }
+ private MyResultReceiver mReceiver;
// Types used with setType. Keep in sync with CachedInput.h
private static final int NORMAL_TEXT_FIELD = 0;
@@ -184,7 +202,7 @@
}
}
};
-
+ mReceiver = new MyResultReceiver(mHandler);
}
public void setAutoFillable(int queryId) {
@@ -362,6 +380,8 @@
}
}
+ /* package */ ResultReceiver getResultReceiver() { return mReceiver; }
+
/**
* Determine whether this WebTextView currently represents the node
* represented by ptr.
@@ -495,7 +515,6 @@
int candEnd = EditableInputConnection.getComposingSpanEnd(sp);
imm.updateSelection(this, selStart, selEnd, candStart, candEnd);
}
- updateCursorControllerPositions();
}
@Override
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index d488a22..2a5c45f 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -44,6 +44,7 @@
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
+import android.graphics.SurfaceTexture;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.net.Proxy;
@@ -352,7 +353,8 @@
private ZoomManager mZoomManager;
- private Rect mGLRectViewport = new Rect();
+ private final Rect mGLRectViewport = new Rect();
+ private final Rect mViewRectViewport = new Rect();
private boolean mGLViewportEmpty = false;
/**
@@ -497,15 +499,6 @@
// default is not set, the UI will continue handle them.
private boolean mDeferTouchProcess;
- // Currently, multi-touch events are sent to WebKit first then back to
- // WebView while single-touch events are handled in WebView first.
- // So there is a chance that a single-touch move event is handled in WebView
- // before multi-touch events are finished.
- // if mIsHandlingMultiTouch is true, which means multi-touch event handling
- // is not finished, then any single-touch move event will be skipped.
- // FIXME: send single-touch events to WebKit first then back to WebView.
- private boolean mIsHandlingMultiTouch = false;
-
// to avoid interfering with the current touch events, track them
// separately. Currently no snapping or fling in the deferred process mode
private int mDeferTouchMode = TOUCH_DONE_MODE;
@@ -617,6 +610,10 @@
private int mTouchHighlightX;
private int mTouchHighlightY;
+ // Basically this proxy is used to tell the Video to update layer tree at
+ // SetBaseLayer time and to pause when WebView paused.
+ private HTML5VideoViewProxy mHTML5VideoViewProxy;
+
/*
* Private message ids
*/
@@ -675,6 +672,7 @@
static final int SELECT_AT = 135;
static final int SCREEN_ON = 136;
+ static final int ENTER_FULLSCREEN_VIDEO = 137;
private static final int FIRST_PACKAGE_MSG_ID = SCROLL_TO_MSG_ID;
private static final int LAST_PACKAGE_MSG_ID = SET_TOUCH_HIGHLIGHT_RECTS;
@@ -729,7 +727,8 @@
"SET_AUTOFILLABLE", // = 133;
"AUTOFILL_COMPLETE", // = 134;
"SELECT_AT", // = 135;
- "SCREEN_ON" // = 136;
+ "SCREEN_ON", // = 136;
+ "ENTER_FULLSCREEN_VIDEO" // = 137;
};
// If the site doesn't use the viewport meta tag to specify the viewport,
@@ -848,6 +847,9 @@
private Rect mScrollingLayerBounds = new Rect();
private boolean mSentAutoScrollMessage = false;
+ // used for serializing asynchronously handled touch events.
+ private final TouchEventQueue mTouchEventQueue = new TouchEventQueue();
+
// Used to notify listeners of a new picture.
private PictureListener mPictureListener;
/**
@@ -1129,10 +1131,13 @@
protected Set<String> doInBackground(Void... unused) {
Set<String> installedPackages = new HashSet<String>();
PackageManager pm = mContext.getPackageManager();
- List<PackageInfo> packages = pm.getInstalledPackages(0);
- for (PackageInfo p : packages) {
- if (sGoogleApps.contains(p.packageName)) {
- installedPackages.add(p.packageName);
+ for (String name : sGoogleApps) {
+ try {
+ PackageInfo pInfo = pm.getPackageInfo(name,
+ PackageManager.GET_ACTIVITIES | PackageManager.GET_SERVICES);
+ installedPackages.add(name);
+ } catch(PackageManager.NameNotFoundException e) {
+ // package not found
}
}
return installedPackages;
@@ -1183,6 +1188,7 @@
// Initially use a size of two, since the user is likely to only hold
// down two keys at a time (shift + another key)
mKeysPressed = new Vector<Integer>(2);
+ mHTML5VideoViewProxy = null ;
}
/**
@@ -2891,6 +2897,11 @@
if (!mIsPaused) {
mIsPaused = true;
mWebViewCore.sendMessage(EventHub.ON_PAUSE);
+ // We want to pause the current playing video when switching out
+ // from the current WebView/tab.
+ if (mHTML5VideoViewProxy != null) {
+ mHTML5VideoViewProxy.pauseAndDispatch();
+ }
}
}
@@ -3002,7 +3013,8 @@
}
/**
- * Start an ActionMode for finding text in this WebView.
+ * Start an ActionMode for finding text in this WebView. Only works if this
+ * WebView is attached to the view system.
* @param text If non-null, will be the initial text to search for.
* Otherwise, the last String searched for in this WebView will
* be used to start.
@@ -3012,7 +3024,7 @@
*/
public boolean showFindDialog(String text, boolean showIme) {
FindActionModeCallback callback = new FindActionModeCallback(mContext);
- if (startActionMode(callback) == null) {
+ if (getParent() == null || startActionMode(callback) == null) {
// Could not start the action mode, so end Find on page
return false;
}
@@ -4018,14 +4030,12 @@
}
}
- void setBaseLayer(int layer, Rect invalRect, boolean showVisualIndciator) {
+ void setBaseLayer(int layer, Region invalRegion, boolean showVisualIndicator) {
if (mNativeClass == 0)
return;
- if (invalRect == null) {
- Rect rect = new Rect(0, 0, mContentWidth, mContentHeight);
- nativeSetBaseLayer(layer, rect, showVisualIndciator);
- } else {
- nativeSetBaseLayer(layer, invalRect, showVisualIndciator);
+ nativeSetBaseLayer(layer, invalRegion, showVisualIndicator);
+ if (mHTML5VideoViewProxy != null) {
+ mHTML5VideoViewProxy.setBaseLayer(layer);
}
}
@@ -4099,7 +4109,7 @@
}
if (animateZoom) {
mZoomManager.animateZoom(canvas);
- } else {
+ } else if (!canvas.isHardwareAccelerated()) {
canvas.scale(mZoomManager.getScale(), mZoomManager.getScale());
}
@@ -4136,7 +4146,7 @@
if (canvas.isHardwareAccelerated()) {
int functor = nativeGetDrawGLFunction(mGLViewportEmpty ? null : mGLRectViewport,
- getScale(), extras);
+ mGLViewportEmpty ? null : mViewRectViewport, getScale(), extras);
((HardwareCanvas) canvas).callDrawGLFunction(functor);
} else {
DrawFilter df = null;
@@ -4266,7 +4276,7 @@
if (isTextView) {
rebuildWebTextView();
if (inEditingMode()) {
- imm.showSoftInput(mWebTextView, 0);
+ imm.showSoftInput(mWebTextView, 0, mWebTextView.getResultReceiver());
if (zoom) {
didUpdateWebTextViewDimensions(INTERSECTS_SCREEN);
}
@@ -5066,6 +5076,8 @@
}
addAccessibilityApisToJavaScript();
+
+ mTouchEventQueue.reset();
}
@Override
@@ -5238,6 +5250,7 @@
// Then need to invert the Y axis, just for GL
View rootView = getRootView();
int rootViewHeight = rootView.getHeight();
+ mViewRectViewport.set(mGLRectViewport);
int savedWebViewBottom = mGLRectViewport.bottom;
mGLRectViewport.bottom = rootViewHeight - mGLRectViewport.top - getVisibleTitleHeight();
mGLRectViewport.top = rootViewHeight - savedWebViewBottom;
@@ -5245,7 +5258,8 @@
} else {
mGLViewportEmpty = true;
}
- nativeUpdateDrawGLFunction(mGLViewportEmpty ? null : mGLRectViewport);
+ nativeUpdateDrawGLFunction(mGLViewportEmpty ? null : mGLRectViewport,
+ mGLViewportEmpty ? null : mViewRectViewport);
}
/**
@@ -5417,34 +5431,17 @@
+ " numPointers=" + ev.getPointerCount());
}
- int action = ev.getActionMasked();
- if (ev.getPointerCount() > 1) { // Multi-touch
- mIsHandlingMultiTouch = true;
-
- // If WebKit already showed no interests in this sequence of events,
- // WebView handles them directly.
- if (mPreventDefault == PREVENT_DEFAULT_NO) {
- handleMultiTouchInWebView(ev);
- } else {
- passMultiTouchToWebKit(ev);
- }
- return true;
+ // If WebKit wasn't interested in this multitouch gesture, enqueue
+ // the event for handling directly rather than making the round trip
+ // to WebKit and back.
+ if (ev.getPointerCount() > 1 && mPreventDefault != PREVENT_DEFAULT_NO) {
+ passMultiTouchToWebKit(ev, mTouchEventQueue.nextTouchSequence());
} else {
- final ScaleGestureDetector detector = mZoomManager.getMultiTouchGestureDetector();
- if (detector != null) {
- // ScaleGestureDetector needs a consistent event stream to operate properly.
- // It won't take any action with fewer than two pointers, but it needs to
- // update internal bookkeeping state.
- detector.onTouchEvent(ev);
- }
+ mTouchEventQueue.enqueueTouchEvent(ev);
}
- // Skip ACTION_MOVE for single touch if it's still handling multi-touch.
- if (mIsHandlingMultiTouch && action == MotionEvent.ACTION_MOVE) {
- return false;
- }
-
- return handleTouchEventCommon(ev, action, Math.round(ev.getX()), Math.round(ev.getY()));
+ // Since all events are handled asynchronously, we always want the gesture stream.
+ return true;
}
/*
@@ -5472,7 +5469,6 @@
case MotionEvent.ACTION_DOWN: {
mPreventDefault = PREVENT_DEFAULT_NO;
mConfirmMove = false;
- mIsHandlingMultiTouch = false;
mInitialHitTestResult = null;
if (!mScroller.isFinished()) {
// stop the current scroll animation, but if this is
@@ -5564,6 +5560,7 @@
ted.mReprocess = mDeferTouchProcess;
ted.mNativeLayer = nativeScrollableLayer(
contentX, contentY, ted.mNativeLayerRect, null);
+ ted.mSequence = mTouchEventQueue.nextTouchSequence();
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
if (mDeferTouchProcess) {
// still needs to set them for compute deltaX/Y
@@ -5610,6 +5607,7 @@
ted.mReprocess = mDeferTouchProcess;
ted.mNativeLayer = mScrollingLayer;
ted.mNativeLayerRect.set(mScrollingLayerRect);
+ ted.mSequence = mTouchEventQueue.nextTouchSequence();
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
mLastSentTouchTime = eventTime;
if (mDeferTouchProcess) {
@@ -5791,6 +5789,7 @@
ted.mReprocess = mDeferTouchProcess;
ted.mNativeLayer = mScrollingLayer;
ted.mNativeLayerRect.set(mScrollingLayerRect);
+ ted.mSequence = mTouchEventQueue.nextTouchSequence();
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
}
mLastTouchUpTime = eventTime;
@@ -5813,6 +5812,7 @@
ted.mNativeLayer = nativeScrollableLayer(
contentX, contentY,
ted.mNativeLayerRect, null);
+ ted.mSequence = mTouchEventQueue.nextTouchSequence();
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
} else if (mPreventDefault != PREVENT_DEFAULT_YES){
mZoomManager.handleDoubleTap(mLastTouchX, mLastTouchY);
@@ -5937,7 +5937,7 @@
return true;
}
- private void passMultiTouchToWebKit(MotionEvent ev) {
+ private void passMultiTouchToWebKit(MotionEvent ev, long sequence) {
TouchEventData ted = new TouchEventData();
ted.mAction = ev.getActionMasked();
final int count = ev.getPointerCount();
@@ -5952,13 +5952,13 @@
ted.mMetaState = ev.getMetaState();
ted.mReprocess = true;
ted.mMotionEvent = MotionEvent.obtain(ev);
+ ted.mSequence = sequence;
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
cancelLongPress();
mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
- mPreventDefault = PREVENT_DEFAULT_IGNORE;
}
- private void handleMultiTouchInWebView(MotionEvent ev) {
+ void handleMultiTouchInWebView(MotionEvent ev) {
if (DebugFlags.WEB_VIEW) {
Log.v(LOGTAG, "multi-touch: " + ev + " at " + ev.getEventTime()
+ " mTouchMode=" + mTouchMode
@@ -5976,24 +5976,26 @@
float x = ev.getX();
float y = ev.getY();
- detector.onTouchEvent(ev);
+ if (mPreventDefault != PREVENT_DEFAULT_YES) {
+ detector.onTouchEvent(ev);
- if (detector.isInProgress()) {
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "detector is in progress");
- }
- mLastTouchTime = ev.getEventTime();
- x = detector.getFocusX();
- y = detector.getFocusY();
+ if (detector.isInProgress()) {
+ if (DebugFlags.WEB_VIEW) {
+ Log.v(LOGTAG, "detector is in progress");
+ }
+ mLastTouchTime = ev.getEventTime();
+ x = detector.getFocusX();
+ y = detector.getFocusY();
- cancelLongPress();
- mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
- if (!mZoomManager.supportsPanDuringZoom()) {
- return;
- }
- mTouchMode = TOUCH_DRAG_MODE;
- if (mVelocityTracker == null) {
- mVelocityTracker = VelocityTracker.obtain();
+ cancelLongPress();
+ mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
+ if (!mZoomManager.supportsPanDuringZoom()) {
+ return;
+ }
+ mTouchMode = TOUCH_DRAG_MODE;
+ if (mVelocityTracker == null) {
+ mVelocityTracker = VelocityTracker.obtain();
+ }
}
}
@@ -6001,11 +6003,10 @@
if (action == MotionEvent.ACTION_POINTER_DOWN) {
cancelTouch();
action = MotionEvent.ACTION_DOWN;
- } else if (action == MotionEvent.ACTION_POINTER_UP) {
+ } else if (action == MotionEvent.ACTION_POINTER_UP && ev.getPointerCount() == 2) {
// set mLastTouchX/Y to the remaining point
mLastTouchX = Math.round(x);
mLastTouchY = Math.round(y);
- mIsHandlingMultiTouch = false;
} else if (action == MotionEvent.ACTION_MOVE) {
// negative x or y indicate it is on the edge, skip it.
if (x < 0 || y < 0) {
@@ -6020,6 +6021,7 @@
if (shouldForwardTouchEvent()) {
if (removeEvents) {
mWebViewCore.removeMessages(EventHub.TOUCH_EVENT);
+ mTouchEventQueue.ignoreCurrentlyMissingEvents();
}
TouchEventData ted = new TouchEventData();
ted.mIds = new int[1];
@@ -6029,6 +6031,7 @@
ted.mAction = MotionEvent.ACTION_CANCEL;
ted.mNativeLayer = nativeScrollableLayer(
x, y, ted.mNativeLayerRect, null);
+ ted.mSequence = mTouchEventQueue.nextTouchSequence();
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
mPreventDefault = PREVENT_DEFAULT_IGNORE;
}
@@ -7106,6 +7109,351 @@
return mWebViewCore;
}
+ /**
+ * Used only by TouchEventQueue to store pending touch events.
+ */
+ private static class QueuedTouch {
+ long mSequence;
+ MotionEvent mEvent; // Optional
+ TouchEventData mTed; // Optional
+
+ QueuedTouch mNext;
+
+ public QueuedTouch set(TouchEventData ted) {
+ mSequence = ted.mSequence;
+ mTed = ted;
+ mEvent = null;
+ mNext = null;
+ return this;
+ }
+
+ public QueuedTouch set(MotionEvent ev, long sequence) {
+ mEvent = MotionEvent.obtain(ev);
+ mSequence = sequence;
+ mTed = null;
+ mNext = null;
+ return this;
+ }
+
+ public QueuedTouch add(QueuedTouch other) {
+ if (other.mSequence < mSequence) {
+ other.mNext = this;
+ return other;
+ }
+
+ QueuedTouch insertAt = this;
+ while (insertAt.mNext != null && insertAt.mNext.mSequence < other.mSequence) {
+ insertAt = insertAt.mNext;
+ }
+ other.mNext = insertAt.mNext;
+ insertAt.mNext = other;
+ return this;
+ }
+ }
+
+ /**
+ * WebView handles touch events asynchronously since some events must be passed to WebKit
+ * for potentially slower processing. TouchEventQueue serializes touch events regardless
+ * of which path they take to ensure that no events are ever processed out of order
+ * by WebView.
+ */
+ private class TouchEventQueue {
+ private long mNextTouchSequence = Long.MIN_VALUE + 1;
+ private long mLastHandledTouchSequence = Long.MIN_VALUE;
+ private long mIgnoreUntilSequence = Long.MIN_VALUE;
+ private QueuedTouch mTouchEventQueue;
+ private QueuedTouch mQueuedTouchRecycleBin;
+ private int mQueuedTouchRecycleCount;
+ private static final int MAX_RECYCLED_QUEUED_TOUCH = 15;
+
+ // milliseconds until we abandon hope of getting all of a previous gesture
+ private static final int QUEUED_GESTURE_TIMEOUT = 2000;
+
+ private QueuedTouch obtainQueuedTouch() {
+ if (mQueuedTouchRecycleBin != null) {
+ QueuedTouch result = mQueuedTouchRecycleBin;
+ mQueuedTouchRecycleBin = result.mNext;
+ mQueuedTouchRecycleCount--;
+ return result;
+ }
+ return new QueuedTouch();
+ }
+
+ /**
+ * Allow events with any currently missing sequence numbers to be skipped in processing.
+ */
+ public void ignoreCurrentlyMissingEvents() {
+ mIgnoreUntilSequence = mNextTouchSequence;
+ }
+
+ private void recycleQueuedTouch(QueuedTouch qd) {
+ if (mQueuedTouchRecycleCount < MAX_RECYCLED_QUEUED_TOUCH) {
+ qd.mNext = mQueuedTouchRecycleBin;
+ mQueuedTouchRecycleBin = qd;
+ mQueuedTouchRecycleCount++;
+ }
+ }
+
+ /**
+ * Reset the touch event queue. This will dump any pending events
+ * and reset the sequence numbering.
+ */
+ public void reset() {
+ mNextTouchSequence = Long.MIN_VALUE + 1;
+ mLastHandledTouchSequence = Long.MIN_VALUE;
+ mIgnoreUntilSequence = Long.MIN_VALUE;
+ while (mTouchEventQueue != null) {
+ QueuedTouch recycleMe = mTouchEventQueue;
+ mTouchEventQueue = mTouchEventQueue.mNext;
+ recycleQueuedTouch(recycleMe);
+ }
+ }
+
+ /**
+ * Return the next valid sequence number for tagging incoming touch events.
+ * @return The next touch event sequence number
+ */
+ public long nextTouchSequence() {
+ return mNextTouchSequence++;
+ }
+
+ /**
+ * Enqueue a touch event in the form of TouchEventData.
+ * The sequence number will be read from the mSequence field of the argument.
+ *
+ * If the touch event's sequence number is the next in line to be processed, it will
+ * be handled before this method returns. Any subsequent events that have already
+ * been queued will also be processed in their proper order.
+ *
+ * @param ted Touch data to be processed in order.
+ */
+ public void enqueueTouchEvent(TouchEventData ted) {
+ if (ted.mSequence < mLastHandledTouchSequence) {
+ // Stale event and we already moved on; drop it. (Should not be common.)
+ Log.w(LOGTAG, "Stale touch event " + MotionEvent.actionToString(ted.mAction) +
+ " received from webcore; ignoring");
+ return;
+ }
+
+ dropStaleGestures(ted.mMotionEvent, ted.mSequence);
+
+ if (mLastHandledTouchSequence + 1 == ted.mSequence) {
+ handleQueuedTouchEventData(ted);
+
+ mLastHandledTouchSequence++;
+
+ // Do we have any more? Run them if so.
+ QueuedTouch qd = mTouchEventQueue;
+ while (qd != null && qd.mSequence == mLastHandledTouchSequence + 1) {
+ handleQueuedTouch(qd);
+ QueuedTouch recycleMe = qd;
+ qd = qd.mNext;
+ recycleQueuedTouch(recycleMe);
+ mLastHandledTouchSequence++;
+ }
+ mTouchEventQueue = qd;
+ } else {
+ QueuedTouch qd = obtainQueuedTouch().set(ted);
+ mTouchEventQueue = mTouchEventQueue == null ? qd : mTouchEventQueue.add(qd);
+ }
+ }
+
+ /**
+ * Enqueue a touch event in the form of a MotionEvent from the framework.
+ *
+ * If the touch event's sequence number is the next in line to be processed, it will
+ * be handled before this method returns. Any subsequent events that have already
+ * been queued will also be processed in their proper order.
+ *
+ * @param ev MotionEvent to be processed in order
+ */
+ public void enqueueTouchEvent(MotionEvent ev) {
+ final long sequence = nextTouchSequence();
+
+ dropStaleGestures(ev, sequence);
+
+ if (mLastHandledTouchSequence + 1 == sequence) {
+ handleQueuedMotionEvent(ev);
+
+ mLastHandledTouchSequence++;
+
+ // Do we have any more? Run them if so.
+ QueuedTouch qd = mTouchEventQueue;
+ while (qd != null && qd.mSequence == mLastHandledTouchSequence + 1) {
+ handleQueuedTouch(qd);
+ QueuedTouch recycleMe = qd;
+ qd = qd.mNext;
+ recycleQueuedTouch(recycleMe);
+ mLastHandledTouchSequence++;
+ }
+ mTouchEventQueue = qd;
+ } else {
+ QueuedTouch qd = obtainQueuedTouch().set(ev, sequence);
+ mTouchEventQueue = mTouchEventQueue == null ? qd : mTouchEventQueue.add(qd);
+ }
+ }
+
+ private void dropStaleGestures(MotionEvent ev, long sequence) {
+ if (mTouchEventQueue == null) return;
+
+ MotionEvent nextQueueEvent = mTouchEventQueue.mTed != null ?
+ mTouchEventQueue.mTed.mMotionEvent : mTouchEventQueue.mEvent;
+
+ if (ev != null && ev.getAction() == MotionEvent.ACTION_DOWN && nextQueueEvent != null) {
+ long eventTime = ev.getEventTime();
+ long nextQueueTime = nextQueueEvent.getEventTime();
+ if (eventTime > nextQueueTime + QUEUED_GESTURE_TIMEOUT) {
+ Log.w(LOGTAG, "Got ACTION_DOWN but still waiting on stale event. " +
+ "Ignoring previous queued events.");
+ QueuedTouch qd = mTouchEventQueue;
+ while (qd != null && qd.mSequence < sequence) {
+ QueuedTouch recycleMe = qd;
+ qd = qd.mNext;
+ recycleQueuedTouch(recycleMe);
+ }
+ mTouchEventQueue = qd;
+ mLastHandledTouchSequence = sequence - 1;
+ }
+ }
+
+ if (mIgnoreUntilSequence > mLastHandledTouchSequence) {
+ QueuedTouch qd = mTouchEventQueue;
+ while (qd != null && qd.mSequence < mIgnoreUntilSequence &&
+ qd.mSequence < sequence) {
+ mLastHandledTouchSequence = qd.mSequence;
+ QueuedTouch recycleMe = qd;
+ qd = qd.mNext;
+ recycleQueuedTouch(recycleMe);
+ }
+ mTouchEventQueue = qd;
+ }
+ }
+
+ private void handleQueuedTouch(QueuedTouch qt) {
+ if (qt.mTed != null) {
+ handleQueuedTouchEventData(qt.mTed);
+ } else {
+ handleQueuedMotionEvent(qt.mEvent);
+ qt.mEvent.recycle();
+ }
+ }
+
+ private void handleQueuedMotionEvent(MotionEvent ev) {
+ int action = ev.getActionMasked();
+ if (ev.getPointerCount() > 1) { // Multi-touch
+ handleMultiTouchInWebView(ev);
+ } else {
+ final ScaleGestureDetector detector = mZoomManager.getMultiTouchGestureDetector();
+ if (detector != null && mPreventDefault != PREVENT_DEFAULT_YES) {
+ // ScaleGestureDetector needs a consistent event stream to operate properly.
+ // It won't take any action with fewer than two pointers, but it needs to
+ // update internal bookkeeping state.
+ detector.onTouchEvent(ev);
+ }
+
+ handleTouchEventCommon(ev, action, Math.round(ev.getX()), Math.round(ev.getY()));
+ }
+ }
+
+ private void handleQueuedTouchEventData(TouchEventData ted) {
+ if (!ted.mReprocess) {
+ if (ted.mAction == MotionEvent.ACTION_DOWN
+ && mPreventDefault == PREVENT_DEFAULT_MAYBE_YES) {
+ // if prevent default is called from WebCore, UI
+ // will not handle the rest of the touch events any
+ // more.
+ mPreventDefault = ted.mNativeResult ? PREVENT_DEFAULT_YES
+ : PREVENT_DEFAULT_NO_FROM_TOUCH_DOWN;
+ } else if (ted.mAction == MotionEvent.ACTION_MOVE
+ && mPreventDefault == PREVENT_DEFAULT_NO_FROM_TOUCH_DOWN) {
+ // the return for the first ACTION_MOVE will decide
+ // whether UI will handle touch or not. Currently no
+ // support for alternating prevent default
+ mPreventDefault = ted.mNativeResult ? PREVENT_DEFAULT_YES
+ : PREVENT_DEFAULT_NO;
+ }
+ if (mPreventDefault == PREVENT_DEFAULT_YES) {
+ mTouchHighlightRegion.setEmpty();
+ }
+ } else {
+ if (ted.mPoints.length > 1) { // multi-touch
+ if (!ted.mNativeResult && mPreventDefault != PREVENT_DEFAULT_YES) {
+ mPreventDefault = PREVENT_DEFAULT_NO;
+ handleMultiTouchInWebView(ted.mMotionEvent);
+ } else {
+ mPreventDefault = PREVENT_DEFAULT_YES;
+ }
+ return;
+ }
+
+ // prevent default is not called in WebCore, so the
+ // message needs to be reprocessed in UI
+ if (!ted.mNativeResult) {
+ // Following is for single touch.
+ switch (ted.mAction) {
+ case MotionEvent.ACTION_DOWN:
+ mLastDeferTouchX = contentToViewX(ted.mPoints[0].x)
+ - mScrollX;
+ mLastDeferTouchY = contentToViewY(ted.mPoints[0].y)
+ - mScrollY;
+ mDeferTouchMode = TOUCH_INIT_MODE;
+ break;
+ case MotionEvent.ACTION_MOVE: {
+ // no snapping in defer process
+ int x = contentToViewX(ted.mPoints[0].x) - mScrollX;
+ int y = contentToViewY(ted.mPoints[0].y) - mScrollY;
+ if (mDeferTouchMode != TOUCH_DRAG_MODE) {
+ mDeferTouchMode = TOUCH_DRAG_MODE;
+ mLastDeferTouchX = x;
+ mLastDeferTouchY = y;
+ startScrollingLayer(x, y);
+ startDrag();
+ }
+ int deltaX = pinLocX((int) (mScrollX
+ + mLastDeferTouchX - x))
+ - mScrollX;
+ int deltaY = pinLocY((int) (mScrollY
+ + mLastDeferTouchY - y))
+ - mScrollY;
+ doDrag(deltaX, deltaY);
+ if (deltaX != 0) mLastDeferTouchX = x;
+ if (deltaY != 0) mLastDeferTouchY = y;
+ break;
+ }
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ if (mDeferTouchMode == TOUCH_DRAG_MODE) {
+ // no fling in defer process
+ mScroller.springBack(mScrollX, mScrollY, 0,
+ computeMaxScrollX(), 0,
+ computeMaxScrollY());
+ invalidate();
+ WebViewCore.resumePriority();
+ WebViewCore.resumeUpdatePicture(mWebViewCore);
+ }
+ mDeferTouchMode = TOUCH_DONE_MODE;
+ break;
+ case WebViewCore.ACTION_DOUBLETAP:
+ // doDoubleTap() needs mLastTouchX/Y as anchor
+ mLastTouchX = contentToViewX(ted.mPoints[0].x) - mScrollX;
+ mLastTouchY = contentToViewY(ted.mPoints[0].y) - mScrollY;
+ mZoomManager.handleDoubleTap(mLastTouchX, mLastTouchY);
+ mDeferTouchMode = TOUCH_DONE_MODE;
+ break;
+ case WebViewCore.ACTION_LONGPRESS:
+ HitTestResult hitTest = getHitTestResult();
+ if (hitTest != null && hitTest.mType
+ != HitTestResult.UNKNOWN_TYPE) {
+ performLongClick();
+ }
+ mDeferTouchMode = TOUCH_DONE_MODE;
+ break;
+ }
+ }
+ }
+ }
+ }
+
//-------------------------------------------------------------------------
// Methods can be called from a separate thread, like WebViewCore
// If it needs to call the View system, it has to send message.
@@ -7221,6 +7569,7 @@
ted.mNativeLayer = nativeScrollableLayer(
ted.mPoints[0].x, ted.mPoints[0].y,
ted.mNativeLayerRect, null);
+ ted.mSequence = mTouchEventQueue.nextTouchSequence();
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
} else if (mPreventDefault != PREVENT_DEFAULT_YES) {
mTouchMode = TOUCH_DONE_MODE;
@@ -7266,7 +7615,7 @@
case NEW_PICTURE_MSG_ID: {
// called for new content
final WebViewCore.DrawData draw = (WebViewCore.DrawData) msg.obj;
- setBaseLayer(draw.mBaseLayer, draw.mInvalRegion.getBounds(),
+ setBaseLayer(draw.mBaseLayer, draw.mInvalRegion,
getSettings().getShowVisualIndicator());
final Point viewSize = draw.mViewSize;
WebViewCore.ViewState viewState = draw.mViewState;
@@ -7438,106 +7787,13 @@
if (inFullScreenMode()) {
break;
}
- if (msg.obj == null) {
- if (msg.arg1 == MotionEvent.ACTION_DOWN
- && mPreventDefault == PREVENT_DEFAULT_MAYBE_YES) {
- // if prevent default is called from WebCore, UI
- // will not handle the rest of the touch events any
- // more.
- mPreventDefault = msg.arg2 == 1 ? PREVENT_DEFAULT_YES
- : PREVENT_DEFAULT_NO_FROM_TOUCH_DOWN;
- } else if (msg.arg1 == MotionEvent.ACTION_MOVE
- && mPreventDefault == PREVENT_DEFAULT_NO_FROM_TOUCH_DOWN) {
- // the return for the first ACTION_MOVE will decide
- // whether UI will handle touch or not. Currently no
- // support for alternating prevent default
- mPreventDefault = msg.arg2 == 1 ? PREVENT_DEFAULT_YES
- : PREVENT_DEFAULT_NO;
- }
- if (mPreventDefault == PREVENT_DEFAULT_YES) {
- mTouchHighlightRegion.setEmpty();
- }
- } else {
- TouchEventData ted = (TouchEventData) msg.obj;
+ TouchEventData ted = (TouchEventData) msg.obj;
- if (ted.mPoints.length > 1) { // multi-touch
- if (ted.mAction == MotionEvent.ACTION_POINTER_UP) {
- mIsHandlingMultiTouch = false;
- }
- if (msg.arg2 == 0) {
- mPreventDefault = PREVENT_DEFAULT_NO;
- handleMultiTouchInWebView(ted.mMotionEvent);
- } else {
- mPreventDefault = PREVENT_DEFAULT_YES;
- }
- break;
- }
+ // WebCore is responding to us; remove pending timeout.
+ // It will be re-posted when needed.
+ removeMessages(PREVENT_DEFAULT_TIMEOUT);
- // prevent default is not called in WebCore, so the
- // message needs to be reprocessed in UI
- if (msg.arg2 == 0) {
- // Following is for single touch.
- switch (ted.mAction) {
- case MotionEvent.ACTION_DOWN:
- mLastDeferTouchX = contentToViewX(ted.mPoints[0].x)
- - mScrollX;
- mLastDeferTouchY = contentToViewY(ted.mPoints[0].y)
- - mScrollY;
- mDeferTouchMode = TOUCH_INIT_MODE;
- break;
- case MotionEvent.ACTION_MOVE: {
- // no snapping in defer process
- int x = contentToViewX(ted.mPoints[0].x) - mScrollX;
- int y = contentToViewY(ted.mPoints[0].y) - mScrollY;
- if (mDeferTouchMode != TOUCH_DRAG_MODE) {
- mDeferTouchMode = TOUCH_DRAG_MODE;
- mLastDeferTouchX = x;
- mLastDeferTouchY = y;
- startScrollingLayer(x, y);
- startDrag();
- }
- int deltaX = pinLocX((int) (mScrollX
- + mLastDeferTouchX - x))
- - mScrollX;
- int deltaY = pinLocY((int) (mScrollY
- + mLastDeferTouchY - y))
- - mScrollY;
- doDrag(deltaX, deltaY);
- if (deltaX != 0) mLastDeferTouchX = x;
- if (deltaY != 0) mLastDeferTouchY = y;
- break;
- }
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- if (mDeferTouchMode == TOUCH_DRAG_MODE) {
- // no fling in defer process
- mScroller.springBack(mScrollX, mScrollY, 0,
- computeMaxScrollX(), 0,
- computeMaxScrollY());
- invalidate();
- WebViewCore.resumePriority();
- WebViewCore.resumeUpdatePicture(mWebViewCore);
- }
- mDeferTouchMode = TOUCH_DONE_MODE;
- break;
- case WebViewCore.ACTION_DOUBLETAP:
- // doDoubleTap() needs mLastTouchX/Y as anchor
- mLastTouchX = contentToViewX(ted.mPoints[0].x) - mScrollX;
- mLastTouchY = contentToViewY(ted.mPoints[0].y) - mScrollY;
- mZoomManager.handleDoubleTap(mLastTouchX, mLastTouchY);
- mDeferTouchMode = TOUCH_DONE_MODE;
- break;
- case WebViewCore.ACTION_LONGPRESS:
- HitTestResult hitTest = getHitTestResult();
- if (hitTest != null && hitTest.mType
- != HitTestResult.UNKNOWN_TYPE) {
- performLongClick();
- }
- mDeferTouchMode = TOUCH_DONE_MODE;
- break;
- }
- }
- }
+ mTouchEventQueue.enqueueTouchEvent(ted);
break;
case REQUEST_KEYBOARD:
@@ -7579,6 +7835,11 @@
setKeepScreenOn(msg.arg1 == 1);
break;
+ case ENTER_FULLSCREEN_VIDEO:
+ int layerId = msg.arg1;
+ Log.v(LOGTAG, "Display the video layer " + layerId + " fullscreen");
+ break;
+
case SHOW_FULLSCREEN: {
View view = (View) msg.obj;
int npp = msg.arg1;
@@ -8257,6 +8518,15 @@
}
/**
+ * Enable the communication b/t the webView and VideoViewProxy
+ *
+ * @hide only used by the Browser
+ */
+ public void setHTML5VideoViewProxy(HTML5VideoViewProxy proxy) {
+ mHTML5VideoViewProxy = proxy;
+ }
+
+ /**
* Enable expanded tiles bound for smoother scrolling.
*
* @hide only used by the Browser
@@ -8325,8 +8595,9 @@
boolean splitIfNeeded);
private native void nativeDumpDisplayTree(String urlOrNull);
private native boolean nativeEvaluateLayersAnimations();
- private native int nativeGetDrawGLFunction(Rect rect, float scale, int extras);
- private native void nativeUpdateDrawGLFunction(Rect rect);
+ private native int nativeGetDrawGLFunction(Rect rect, Rect viewRect,
+ float scale, int extras);
+ private native void nativeUpdateDrawGLFunction(Rect rect, Rect viewRect);
private native boolean nativeDrawGL(Rect rect, float scale, int extras);
private native void nativeExtendSelection(int x, int y);
private native int nativeFindAll(String findLower, String findUpper,
@@ -8402,7 +8673,7 @@
private native void nativeSetFindIsEmpty();
private native void nativeSetFindIsUp(boolean isUp);
private native void nativeSetHeightCanMeasure(boolean measure);
- private native void nativeSetBaseLayer(int layer, Rect invalRect,
+ private native void nativeSetBaseLayer(int layer, Region invalRegion,
boolean showVisualIndicator);
private native void nativeShowCursorTimed();
private native void nativeReplaceBaseContent(int content);
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index db605de..65026a5 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -256,4 +256,18 @@
*/
public void onScaleChanged(WebView view, float oldScale, float newScale) {
}
+
+ /**
+ * Notify the host application that a request to automatically log in the
+ * user has been processed.
+ * @param view The WebView requesting the login.
+ * @param realm The account realm used to look up accounts.
+ * @param account An optional account. If not null, the account should be
+ * checked against accounts on the device. If it is a valid
+ * account, it should be used to log in the user.
+ * @param args Authenticator specific arguments used to log in the user.
+ */
+ public void onReceivedLoginRequest(WebView view, String realm,
+ String account, String args) {
+ }
}
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index c18c9e4..979eb2b 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -480,6 +480,15 @@
mCallbackProxy.setInstallableWebApp();
}
+ /**
+ * Notify the webview that we want to display the video layer fullscreen.
+ */
+ protected void enterFullscreenForVideoLayer(int layerId) {
+ if (mWebView == null) return;
+ Message.obtain(mWebView.mPrivateHandler,
+ WebView.ENTER_FULLSCREEN_VIDEO, layerId, 0).sendToTarget();
+ }
+
//-------------------------------------------------------------------------
// JNI methods
//-------------------------------------------------------------------------
@@ -825,6 +834,8 @@
MotionEvent mMotionEvent;
int mNativeLayer;
Rect mNativeLayerRect = new Rect();
+ long mSequence;
+ boolean mNativeResult;
}
static class GeolocationPermissionsData {
@@ -1332,13 +1343,14 @@
nativeScrollLayer(ted.mNativeLayer,
ted.mNativeLayerRect);
}
+ ted.mNativeResult = nativeHandleTouchEvent(ted.mAction, ted.mIds,
+ xArray, yArray, count, ted.mMetaState);
Message.obtain(
mWebView.mPrivateHandler,
WebView.PREVENT_TOUCH_ID,
ted.mAction,
- nativeHandleTouchEvent(ted.mAction, ted.mIds,
- xArray, yArray, count, ted.mMetaState) ? 1 : 0,
- ted.mReprocess ? ted : null).sendToTarget();
+ ted.mNativeResult ? 1 : 0,
+ ted).sendToTarget();
break;
}
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index f27ced8..72052a6 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -23,6 +23,7 @@
import android.graphics.Rect;
import android.os.Bundle;
import android.os.SystemClock;
+import android.util.FloatMath;
import android.util.Log;
import android.view.ScaleGestureDetector;
import android.view.View;
@@ -112,6 +113,22 @@
private float mZoomCenterY;
/*
+ * Similar to mZoomCenterX(Y), these track the focus point of the scale
+ * gesture. The difference is these get updated every time when onScale is
+ * invoked no matter if a zooming really happens.
+ */
+ private float mFocusX;
+ private float mFocusY;
+
+ /*
+ * mFocusMovementQueue keeps track of the previous focus point movement
+ * has been through. Comparing to the difference of the gesture's previous
+ * span and current span, it determines if the gesture is for panning or
+ * zooming or both.
+ */
+ private FocusMovementQueue mFocusMovementQueue;
+
+ /*
* These values represent the point around which the screen should be
* centered after zooming. In other words it is used to determine the center
* point of the visible document after the page has finished zooming. This
@@ -196,6 +213,8 @@
* viewport size is.
*/
setZoomOverviewWidth(WebView.DEFAULT_VIEWPORT_WIDTH);
+
+ mFocusMovementQueue = new FocusMovementQueue();
}
/**
@@ -336,6 +355,10 @@
return scale;
}
+ public final boolean isScaleOverLimits(float scale) {
+ return scale <= mMinZoomScale || scale >= mMaxZoomScale;
+ }
+
public final boolean isZoomScaleFixed() {
return mMinZoomScale >= mMaxZoomScale;
}
@@ -507,7 +530,7 @@
mTextWrapScale = scale;
}
- if (exceedsMinScaleIncrement(scale, mActualScale) || force) {
+ if (scale != mActualScale || force) {
float oldScale = mActualScale;
float oldInvScale = mInvActualScale;
@@ -714,21 +737,91 @@
return mScaleDetector;
}
+ private class FocusMovementQueue {
+ private static final int QUEUE_CAPACITY = 5;
+ private float[] mQueue;
+ private float mSum;
+ private int mSize;
+ private int mIndex;
+
+ FocusMovementQueue() {
+ mQueue = new float[QUEUE_CAPACITY];
+ mSize = 0;
+ mSum = 0;
+ mIndex = 0;
+ }
+
+ private void clear() {
+ mSize = 0;
+ mSum = 0;
+ mIndex = 0;
+ for (int i = 0; i < QUEUE_CAPACITY; ++i) {
+ mQueue[i] = 0;
+ }
+ }
+
+ private void add(float focusDelta) {
+ mSum += focusDelta;
+ if (mSize < QUEUE_CAPACITY) { // fill up the queue.
+ mSize++;
+ } else { // circulate the queue.
+ mSum -= mQueue[mIndex];
+ }
+ mQueue[mIndex] = focusDelta;
+ mIndex = (mIndex + 1) % QUEUE_CAPACITY;
+ }
+
+ private float getSum() {
+ return mSum;
+ }
+ }
+
private class ScaleDetectorListener implements ScaleGestureDetector.OnScaleGestureListener {
+ private float mAccumulatedSpan;
public boolean onScaleBegin(ScaleGestureDetector detector) {
mInitialZoomOverview = false;
dismissZoomPicker();
+ mFocusMovementQueue.clear();
mWebView.mViewManager.startZoom();
mWebView.onPinchToZoomAnimationStart();
+ mAccumulatedSpan = 0;
return true;
}
- public boolean onScale(ScaleGestureDetector detector) {
+ // If the user moves the fingers but keeps the same distance between them,
+ // we should do panning only.
+ public boolean isPanningOnly(ScaleGestureDetector detector) {
+ float prevFocusX = mFocusX;
+ float prevFocusY = mFocusY;
+ mFocusX = detector.getFocusX();
+ mFocusY = detector.getFocusY();
+ float focusDelta = (prevFocusX == 0 && prevFocusY == 0) ? 0 :
+ FloatMath.sqrt((mFocusX - prevFocusX) * (mFocusX - prevFocusX)
+ + (mFocusY - prevFocusY) * (mFocusY - prevFocusY));
+ mFocusMovementQueue.add(focusDelta);
+ float deltaSpan = detector.getCurrentSpan() - detector.getPreviousSpan() +
+ mAccumulatedSpan;
+ final boolean result = mFocusMovementQueue.getSum() > Math.abs(deltaSpan);
+ if (result) {
+ mAccumulatedSpan += deltaSpan;
+ } else {
+ mAccumulatedSpan = 0;
+ }
+ return result;
+ }
+
+ public boolean handleScale(ScaleGestureDetector detector) {
+ float scale = detector.getScaleFactor() * mActualScale;
+
+ // if scale is limited by any reason, don't zoom but do ask
+ // the detector to update the event.
+ boolean isScaleLimited =
+ isScaleOverLimits(scale) || scale < getZoomOverviewScale();
+
// Prevent scaling beyond overview scale.
- float scale = Math.max(
- computeScaleWithLimits(detector.getScaleFactor() * mActualScale),
- getZoomOverviewScale());
+ scale = Math.max(computeScaleWithLimits(scale), getZoomOverviewScale());
+
if (mPinchToZoomAnimating || willScaleTriggerZoom(scale)) {
mPinchToZoomAnimating = true;
// limit the scale change per step
@@ -740,13 +833,21 @@
scale = computeScaleWithLimits(scale);
// if the scale change is too small, regard it as jitter and skip it.
if (Math.abs(scale - mActualScale) < MINIMUM_SCALE_WITHOUT_JITTER) {
- return false;
+ return isScaleLimited;
}
setZoomCenter(detector.getFocusX(), detector.getFocusY());
setZoomScale(scale, false);
mWebView.invalidate();
return true;
}
+ return isScaleLimited;
+ }
+
+ public boolean onScale(ScaleGestureDetector detector) {
+ if (isPanningOnly(detector) || handleScale(detector)) {
+ mFocusMovementQueue.clear();
+ return true;
+ }
return false;
}
@@ -960,14 +1061,15 @@
final Point viewSize = drawData.mViewSize;
updateZoomRange(viewState, viewSize.x, drawData.mMinPrefWidth);
setupZoomOverviewWidth(drawData, mWebView.getViewWidth());
+ final float overviewScale = getZoomOverviewScale();
if (!mMinZoomScaleFixed) {
- mMinZoomScale = getZoomOverviewScale();
+ mMinZoomScale = (mInitialScale > 0) ?
+ Math.min(mInitialScale, overviewScale) : overviewScale;
mMaxZoomScale = Math.max(mMaxZoomScale, mMinZoomScale);
}
if (!mWebView.drawHistory()) {
float scale;
- final float overviewScale = getZoomOverviewScale();
WebSettings settings = mWebView.getSettings();
if (mInitialScale > 0) {
diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java
index 200c870..fb57ce0 100644
--- a/core/java/android/widget/FastScroller.java
+++ b/core/java/android/widget/FastScroller.java
@@ -564,6 +564,9 @@
}
} else {
int index = (int) (position * count);
+ // Don't overflow
+ if (index > count - 1) index = count - 1;
+
if (mList instanceof ExpandableListView) {
ExpandableListView expList = (ExpandableListView) mList;
expList.setSelectionFromTop(expList.getFlatListPosition(
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index d92588cb..17b3bda 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -477,8 +477,7 @@
break;
case MotionEvent.ACTION_POINTER_DOWN: {
final int index = ev.getActionIndex();
- final float x = ev.getX(index);
- mLastMotionX = x;
+ mLastMotionX = ev.getX(index);
mActivePointerId = ev.getPointerId(index);
break;
}
@@ -1446,6 +1445,7 @@
super.setOverScrollMode(mode);
}
+ @SuppressWarnings({"SuspiciousNameCombination"})
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 427126b..af954c9 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -3019,12 +3019,13 @@
hasOpaqueScrollbars()) || super.isOpaque();
if (retValue) {
// only return true if the list items cover the entire area of the view
- final int listTop = mListPadding.top;
+ final int listTop = mListPadding != null ? mListPadding.top : mPaddingTop;
View first = getChildAt(0);
if (first == null || first.getTop() > listTop) {
return false;
}
- final int listBottom = getHeight() - mListPadding.bottom;
+ final int listBottom = getHeight() -
+ (mListPadding != null ? mListPadding.bottom : mPaddingBottom);
View last = getChildAt(getChildCount() - 1);
if (last == null || last.getBottom() < listBottom) {
return false;
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 9002b1d..72b70bc 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -1039,7 +1039,7 @@
*
* @return true if the popup is translated upwards to fit on screen
*/
- boolean findDropDownPosition(View anchor, WindowManager.LayoutParams p,
+ private boolean findDropDownPosition(View anchor, WindowManager.LayoutParams p,
int xoff, int yoff) {
anchor.getLocationInWindow(mDrawingLocation);
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index 2d2165b..1c0a2bb 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -889,7 +889,7 @@
boolean isConnected = mServiceConnection.isConnected();
boolean hasNewItems = false;
- if (!isConnected) {
+ if (!isInCache && !isConnected) {
// Requesting bind service will trigger a super.notifyDataSetChanged(), which will
// in turn trigger another request to getView()
requestBindService();
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index 2d164fd..6088654 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -83,6 +83,7 @@
private CursorAdapter mSuggestionsAdapter;
private View mSearchButton;
private View mSubmitButton;
+ private View mSearchPlate;
private View mSubmitArea;
private ImageView mCloseButton;
private View mSearchEditFrame;
@@ -190,6 +191,7 @@
mQueryTextView.setSearchView(this);
mSearchEditFrame = findViewById(R.id.search_edit_frame);
+ mSearchPlate = findViewById(R.id.search_plate);
mSubmitArea = findViewById(R.id.submit_area);
mSubmitButton = findViewById(R.id.search_go_btn);
mCloseButton = (ImageView) findViewById(R.id.search_close_btn);
@@ -258,6 +260,7 @@
mSearchable = searchable;
if (mSearchable != null) {
updateSearchAutoComplete();
+ updateQueryHint();
}
// Cache the voice search capability
mVoiceButtonEnabled = hasVoiceSearch();
@@ -575,19 +578,19 @@
}
private void updateSubmitButton(boolean hasText) {
- mSubmitButton.setVisibility(
- isSubmitAreaEnabled() ? (hasText ? VISIBLE : INVISIBLE) : GONE);
+ int visibility = GONE;
+ if (isSubmitAreaEnabled() && hasFocus() && (hasText || !mVoiceButtonEnabled)) {
+ visibility = VISIBLE;
+ }
+ mSubmitButton.setVisibility(visibility);
}
private void updateSubmitArea() {
int visibility = GONE;
- if (isSubmitAreaEnabled()) {
- if (mSubmitButton.getVisibility() == VISIBLE
- || mVoiceButton.getVisibility() == VISIBLE) {
- visibility = VISIBLE;
- } else {
- visibility = INVISIBLE;
- }
+ if (isSubmitAreaEnabled()
+ && (mSubmitButton.getVisibility() == VISIBLE
+ || mVoiceButton.getVisibility() == VISIBLE)) {
+ visibility = VISIBLE;
}
mSubmitArea.setVisibility(visibility);
}
@@ -601,6 +604,11 @@
mCloseButton.getDrawable().setState(hasText ? ENABLED_STATE_SET : EMPTY_STATE_SET);
}
+ private void updateFocusedState(boolean focused) {
+ mSearchPlate.getBackground().setState(focused ? FOCUSED_STATE_SET : EMPTY_STATE_SET);
+ mSubmitArea.getBackground().setState(focused ? FOCUSED_STATE_SET : EMPTY_STATE_SET);
+ }
+
private void setImeVisibility(boolean visible) {
InputMethodManager imm = (InputMethodManager)
getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
@@ -851,16 +859,11 @@
* Update the visibility of the voice button. There are actually two voice search modes,
* either of which will activate the button.
* @param empty whether the search query text field is empty. If it is, then the other
- * criteria apply to make the voice button visible. Otherwise the voice button will not
- * be visible - i.e., if the user has typed a query, remove the voice button.
+ * criteria apply to make the voice button visible.
*/
private void updateVoiceButton(boolean empty) {
- // If the voice button is to be visible, show it
- // Else, make it gone if the submit button is enabled, otherwise invisible to
- // avoid losing the real-estate
- int visibility = mSubmitButtonEnabled ? GONE : INVISIBLE;
-
- if (mVoiceButtonEnabled && !isIconified() && empty) {
+ int visibility = GONE;
+ if (mVoiceButtonEnabled && !isIconified() && (empty || !mSubmitButtonEnabled)) {
visibility = VISIBLE;
mSubmitButton.setVisibility(GONE);
}
@@ -958,7 +961,8 @@
}
void onTextFocusChanged() {
- updateCloseButton();
+ updateViewsVisibility(isIconified());
+ updateFocusedState(mQueryTextView.hasFocus());
}
private boolean onItemClicked(int position, int actionKey, String actionMsg) {
diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java
index bab469b..21c61bd 100644
--- a/core/java/android/widget/StackView.java
+++ b/core/java/android/widget/StackView.java
@@ -531,6 +531,8 @@
@Override
protected void dispatchDraw(Canvas canvas) {
+ boolean expandClipRegion = false;
+
canvas.getClipBounds(stackInvalidateRect);
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
@@ -540,12 +542,22 @@
child.getAlpha() == 0f || child.getVisibility() != VISIBLE) {
lp.resetInvalidateRect();
}
- stackInvalidateRect.union(lp.getInvalidateRect());
+ Rect childInvalidateRect = lp.getInvalidateRect();
+ if (!childInvalidateRect.isEmpty()) {
+ expandClipRegion = true;
+ stackInvalidateRect.union(childInvalidateRect);
+ }
}
- canvas.save(Canvas.CLIP_SAVE_FLAG);
- canvas.clipRect(stackInvalidateRect, Region.Op.UNION);
- super.dispatchDraw(canvas);
- canvas.restore();
+
+ // We only expand the clip bounds if necessary.
+ if (expandClipRegion) {
+ canvas.save(Canvas.CLIP_SAVE_FLAG);
+ canvas.clipRect(stackInvalidateRect, Region.Op.UNION);
+ super.dispatchDraw(canvas);
+ canvas.restore();
+ } else {
+ super.dispatchDraw(canvas);
+ }
}
private void onLayout() {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 09c1ac5..00124e1 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -4498,8 +4498,6 @@
*/
canvas.restore();
-
- updateCursorControllerPositions();
}
private void updateCursorsPositions() {
@@ -4551,23 +4549,6 @@
if (translate) canvas.translate(0, -cursorOffsetVertical);
}
- /**
- * Update the positions of the CursorControllers. Needed by WebTextView,
- * which does not draw.
- * @hide
- */
- protected void updateCursorControllerPositions() {
- // No need to create the controllers if they were not already
- if (mInsertionPointCursorController != null &&
- mInsertionPointCursorController.isShowing()) {
- mInsertionPointCursorController.updatePosition();
- }
- if (mSelectionModifierCursorController != null &&
- mSelectionModifierCursorController.isShowing()) {
- mSelectionModifierCursorController.updatePosition();
- }
- }
-
@Override
public void getFocusedRect(Rect r) {
if (mLayout == null) {
@@ -6285,15 +6266,15 @@
}
if (isFocused()) {
- // This offsets because getInterestingRect() is in terms of
- // viewport coordinates, but requestRectangleOnScreen()
- // is in terms of content coordinates.
+ // This offsets because getInterestingRect() is in terms of viewport coordinates, but
+ // requestRectangleOnScreen() is in terms of content coordinates.
- Rect r = new Rect(x, top, x + 1, bottom);
- getInterestingRect(r, line);
- r.offset(mScrollX, mScrollY);
+ if (mTempRect == null) mTempRect = new Rect();
+ mTempRect.set(x, top, x + 1, bottom);
+ getInterestingRect(mTempRect, line);
+ mTempRect.offset(mScrollX, mScrollY);
- if (requestRectangleOnScreen(r)) {
+ if (requestRectangleOnScreen(mTempRect)) {
changed = true;
}
}
@@ -6766,25 +6747,21 @@
}
/**
- * This method is called when the text is changed, in case any
- * subclasses would like to know.
+ * This method is called when the text is changed, in case any subclasses
+ * would like to know.
*
- * @param text The text the TextView is displaying.
- * @param start The offset of the start of the range of the text
- * that was modified.
- * @param before The offset of the former end of the range of the
- * text that was modified. If text was simply inserted,
- * this will be the same as <code>start</code>.
- * If text was replaced with new text or deleted, the
- * length of the old text was <code>before-start</code>.
- * @param after The offset of the end of the range of the text
- * that was modified. If text was simply deleted,
- * this will be the same as <code>start</code>.
- * If text was replaced with new text or inserted,
- * the length of the new text is <code>after-start</code>.
+ * Within <code>text</code>, the <code>lengthAfter</code> characters
+ * beginning at <code>start</code> have just replaced old text that had
+ * length <code>lengthBefore</code>. It is an error to attempt to make
+ * changes to <code>text</code> from this callback.
+ *
+ * @param text The text the TextView is displaying
+ * @param start The offset of the start of the range of the text that was
+ * modified
+ * @param lengthBefore The length of the former text that has been replaced
+ * @param lengthAfter The length of the replacement modified text
*/
- protected void onTextChanged(CharSequence text,
- int start, int before, int after) {
+ protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
}
/**
@@ -7336,9 +7313,6 @@
&& mText instanceof Spannable && mLayout != null) {
boolean handled = false;
- final int oldScrollX = mScrollX;
- final int oldScrollY = mScrollY;
-
if (mMovement != null) {
handled |= mMovement.onTouchEvent(this, (Spannable) mText, event);
}
@@ -7355,33 +7329,20 @@
}
}
- if (isTextEditable() || mTextIsSelectable) {
- if (mScrollX != oldScrollX || mScrollY != oldScrollY) {
- // Hide insertion anchor while scrolling. Leave selection.
- hideInsertionPointCursorController();
- // No need to create the controller, since there is nothing to update.
- if (mSelectionModifierCursorController != null &&
- mSelectionModifierCursorController.isShowing()) {
- mSelectionModifierCursorController.updatePosition();
- }
+ if ((isTextEditable() || mTextIsSelectable) && touchIsFinished) {
+ // Show the IME, except when selecting in read-only text.
+ if (!mTextIsSelectable) {
+ final InputMethodManager imm = InputMethodManager.peekInstance();
+ handled |= imm != null && imm.showSoftInput(this, 0);
}
- if (touchIsFinished) {
- // Show the IME, except when selecting in read-only text.
- if (!mTextIsSelectable) {
- final InputMethodManager imm = InputMethodManager.peekInstance();
- handled |= imm != null && imm.showSoftInput(this, 0);
- }
-
-
- boolean selectAllGotFocus = mSelectAllOnFocus && didTouchFocusSelect();
- if (!selectAllGotFocus && hasSelection()) {
- startSelectionActionMode();
- } else {
- stopSelectionActionMode();
- if (hasInsertionController() && !selectAllGotFocus && mText.length() > 0) {
- getInsertionController().show();
- }
+ boolean selectAllGotFocus = mSelectAllOnFocus && didTouchFocusSelect();
+ if (!selectAllGotFocus && hasSelection()) {
+ startSelectionActionMode();
+ } else {
+ stopSelectionActionMode();
+ if (hasInsertionController() && !selectAllGotFocus && mText.length() > 0) {
+ getInsertionController().show();
}
}
}
@@ -8196,7 +8157,7 @@
final int offset = getOffset(mLastDownPositionX, mLastDownPositionY);
stopSelectionActionMode();
Selection.setSelection((Spannable)mText, offset);
- getInsertionController().show(0);
+ getInsertionController().showWithPaste();
handled = true;
}
@@ -8469,55 +8430,6 @@
}
}
- /**
- * A CursorController instance can be used to control a cursor in the text.
- * It is not used outside of {@link TextView}.
- * @hide
- */
- private interface CursorController extends ViewTreeObserver.OnTouchModeChangeListener {
- /**
- * Makes the cursor controller visible on screen. Will be drawn by {@link #draw(Canvas)}.
- * See also {@link #hide()}.
- */
- public void show();
-
- /**
- * Hide the cursor controller from screen.
- * See also {@link #show()}.
- */
- public void hide();
-
- /**
- * @return true if the CursorController is currently visible
- */
- public boolean isShowing();
-
- /**
- * Update the controller's position.
- */
- public void updatePosition(HandleView handle, int x, int y);
-
- public void updateOffset(HandleView handle, int offset);
-
- public void updatePosition();
-
- public int getCurrentOffset(HandleView handle);
-
- /**
- * This method is called by {@link #onTouchEvent(MotionEvent)} and gives the controller
- * a chance to become active and/or visible.
- * @param event The touch event
- */
- public boolean onTouchEvent(MotionEvent event);
-
- /**
- * Called when the view is detached from window. Perform house keeping task, such as
- * stopping Runnable thread that would otherwise keep a reference on the context, thus
- * preventing the activity to be recycled.
- */
- public void onDetached();
- }
-
private class PastePopupMenu implements OnClickListener {
private final PopupWindow mContainer;
private int mPositionX;
@@ -8653,27 +8565,43 @@
}
}
- private class HandleView extends View implements ViewTreeObserver.OnScrollChangedListener {
- private Drawable mDrawable;
- private final ScrollingPopupWindow mContainer;
- private int mPositionX;
- private int mPositionY;
- private final CursorController mController;
+ private abstract class HandleView extends View implements ViewTreeObserver.OnPreDrawListener {
+ protected Drawable mDrawable;
+ private final PopupWindow mContainer;
+ // Position with respect to the parent TextView
+ private int mPositionX, mPositionY;
private boolean mIsDragging;
- private float mTouchToWindowOffsetX;
- private float mTouchToWindowOffsetY;
- private float mHotspotX;
+ // Offset from touch position to mPosition
+ private float mTouchToWindowOffsetX, mTouchToWindowOffsetY;
+ protected float mHotspotX;
// Offsets the hotspot point up, so that cursor is not hidden by the finger when moving up
private float mTouchOffsetY;
// Where the touch position should be on the handle to ensure a maximum cursor visibility
private float mIdealVerticalOffset;
- private int mLastParentX;
- private int mLastParentY;
- private float mDownPositionX, mDownPositionY;
+ // Parent's (TextView) position in window
+ private int mLastParentX, mLastParentY;
+ // PopupWindow container absolute position with respect to the enclosing window
private int mContainerPositionX, mContainerPositionY;
- private long mTouchTimer;
- private boolean mIsInsertionHandle = false;
- private PastePopupMenu mPastePopupWindow;
+ // Visible or not (scrolled off screen), whether or not this handle should be visible
+ private boolean mIsActive = false;
+
+ public HandleView() {
+ super(TextView.this.mContext);
+ mContainer = new PopupWindow(TextView.this.mContext, null,
+ com.android.internal.R.attr.textSelectHandleWindowStyle);
+ mContainer.setSplitTouchEnabled(true);
+ mContainer.setClippingEnabled(false);
+ mContainer.setWindowLayoutType(WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL);
+ mContainer.setContentView(this);
+
+ initDrawable();
+
+ final int handleHeight = mDrawable.getIntrinsicHeight();
+ mTouchOffsetY = -0.3f * handleHeight;
+ mIdealVerticalOffset = 0.7f * handleHeight;
+ }
+
+ protected abstract void initDrawable();
// Touch-up filter: number of previous positions remembered
private static final int HISTORY_SIZE = 5;
@@ -8684,12 +8612,12 @@
private int mPreviousOffsetIndex = 0;
private int mNumberPreviousOffsets = 0;
- public void startTouchUpFilter(int offset) {
+ private void startTouchUpFilter(int offset) {
mNumberPreviousOffsets = 0;
addPositionToTouchUpFilter(offset);
}
- public void addPositionToTouchUpFilter(int offset) {
+ private void addPositionToTouchUpFilter(int offset) {
if (mNumberPreviousOffsets > 0 &&
mPreviousOffsets[mPreviousOffsetIndex] == offset) {
// Make sure only actual changes of position are recorded.
@@ -8702,7 +8630,7 @@
mNumberPreviousOffsets++;
}
- public void filterOnTouchUp() {
+ private void filterOnTouchUp() {
final long now = SystemClock.uptimeMillis();
int i = 0;
int index = mPreviousOffsetIndex;
@@ -8714,98 +8642,46 @@
if (i > 0 && i < iMax &&
(now - mPreviousOffsetsTimes[index]) > TOUCH_UP_FILTER_DELAY_BEFORE) {
- mController.updateOffset(this, mPreviousOffsets[index]);
+ updateOffset(mPreviousOffsets[index]);
}
}
- public static final int LEFT = 0;
- public static final int CENTER = 1;
- public static final int RIGHT = 2;
-
- public HandleView(CursorController controller, int pos) {
- super(TextView.this.mContext);
- mController = controller;
- mContainer = new ScrollingPopupWindow(TextView.this.mContext, null,
- com.android.internal.R.attr.textSelectHandleWindowStyle);
- mContainer.setSplitTouchEnabled(true);
- mContainer.setClippingEnabled(false);
- mContainer.setWindowLayoutType(WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL);
-
- setOrientation(pos);
- }
-
- public void setOrientation(int pos) {
- int handleWidth;
- switch (pos) {
- case LEFT: {
- if (mSelectHandleLeft == null) {
- mSelectHandleLeft = mContext.getResources().getDrawable(
- mTextSelectHandleLeftRes);
- }
- mDrawable = mSelectHandleLeft;
- handleWidth = mDrawable.getIntrinsicWidth();
- mHotspotX = handleWidth * 3.0f / 4.0f;
- break;
- }
-
- case RIGHT: {
- if (mSelectHandleRight == null) {
- mSelectHandleRight = mContext.getResources().getDrawable(
- mTextSelectHandleRightRes);
- }
- mDrawable = mSelectHandleRight;
- handleWidth = mDrawable.getIntrinsicWidth();
- mHotspotX = handleWidth / 4.0f;
- break;
- }
-
- case CENTER:
- default: {
- if (mSelectHandleCenter == null) {
- mSelectHandleCenter = mContext.getResources().getDrawable(
- mTextSelectHandleRes);
- }
- mDrawable = mSelectHandleCenter;
- handleWidth = mDrawable.getIntrinsicWidth();
- mHotspotX = handleWidth / 2.0f;
- mIsInsertionHandle = true;
- break;
- }
- }
-
- final int handleHeight = mDrawable.getIntrinsicHeight();
-
- mTouchOffsetY = -0.3f * handleHeight;
- mIdealVerticalOffset = 0.7f * handleHeight;
- invalidate();
- }
-
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- setMeasuredDimension(mDrawable.getIntrinsicWidth(),
- mDrawable.getIntrinsicHeight());
+ setMeasuredDimension(mDrawable.getIntrinsicWidth(), mDrawable.getIntrinsicHeight());
}
public void show() {
- if (!isPositionVisible()) {
- hide();
- return;
- }
- mContainer.setContentView(this);
- mContainerPositionX = mPositionX;
- mContainerPositionY = mPositionY - TextView.this.getHeight();
- mContainer.showAsDropDown(TextView.this, mContainerPositionX, mContainerPositionY);
+ updateContainerPosition();
+ if (isShowing()) {
+ mContainer.update(mContainerPositionX, mContainerPositionY,
+ mRight - mLeft, mBottom - mTop);
- // Hide paste view when handle is moved on screen.
- hidePastePopupWindow();
+ hideAssociatedPopupWindow();
+ } else {
+ mContainer.showAtLocation(TextView.this, 0,
+ mContainerPositionX, mContainerPositionY);
+
+ mIsActive = true;
+
+ ViewTreeObserver vto = TextView.this.getViewTreeObserver();
+ vto.addOnPreDrawListener(this);
+ }
+ }
+
+ protected void dismiss() {
+ mIsDragging = false;
+ mContainer.dismiss();
+ hideAssociatedPopupWindow();
}
public void hide() {
- mIsDragging = false;
- mContainer.dismiss();
- hidePastePopupWindow();
+ dismiss();
+
+ mIsActive = false;
+
ViewTreeObserver vto = TextView.this.getViewTreeObserver();
- vto.removeOnScrollChangedListener(this);
+ vto.removeOnPreDrawListener(this);
}
public boolean isShowing() {
@@ -8829,9 +8705,7 @@
final TextView hostView = TextView.this;
- if (mTempRect == null) {
- mTempRect = new Rect();
- }
+ if (mTempRect == null) mTempRect = new Rect();
final Rect clip = mTempRect;
clip.left = compoundPaddingLeft;
clip.top = extendedPaddingTop;
@@ -8856,44 +8730,83 @@
private void moveTo(int x, int y) {
mPositionX = x - TextView.this.mScrollX;
mPositionY = y - TextView.this.mScrollY;
- if (isPositionVisible()) {
- int[] coords = null;
- if (mContainer.isShowing()) {
- final int containerPositionX = mPositionX;
- final int containerPositionY = mPositionY - TextView.this.getHeight();
- if (containerPositionX != mContainerPositionX ||
- containerPositionY != mContainerPositionY) {
- mContainerPositionX = containerPositionX;
- mContainerPositionY = containerPositionY;
+ if (mIsDragging) {
+ TextView.this.getLocationInWindow(mTempCoords);
+ if (mTempCoords[0] != mLastParentX || mTempCoords[1] != mLastParentY) {
+ mTouchToWindowOffsetX += mTempCoords[0] - mLastParentX;
+ mTouchToWindowOffsetY += mTempCoords[1] - mLastParentY;
+ mLastParentX = mTempCoords[0];
+ mLastParentY = mTempCoords[1];
+ }
- mContainer.update(TextView.this, mContainerPositionX, mContainerPositionY,
- mRight - mLeft, mBottom - mTop);
+ hideAssociatedPopupWindow();
+ }
+ }
- // Hide paste popup window as soon as a scroll occurs.
- hidePastePopupWindow();
+ public abstract int getCurrentCursorOffset();
+
+ public abstract void updateOffset(int offset);
+
+ public abstract void updatePosition(int x, int y);
+
+ protected void positionAtCursorOffset(int offset) {
+ addPositionToTouchUpFilter(offset);
+ final int width = mDrawable.getIntrinsicWidth();
+ final int height = mDrawable.getIntrinsicHeight();
+ final int line = mLayout.getLineForOffset(offset);
+ final int lineBottom = mLayout.getLineBottom(line);
+
+ final Rect bounds = sCursorControllerTempRect;
+ bounds.left = (int) (mLayout.getPrimaryHorizontal(offset) - 0.5f - mHotspotX) +
+ TextView.this.mScrollX;
+ bounds.top = lineBottom + TextView.this.mScrollY;
+
+ bounds.right = bounds.left + width;
+ bounds.bottom = bounds.top + height;
+
+ convertFromViewportToContentCoordinates(bounds);
+ moveTo(bounds.left, bounds.top);
+ }
+
+ /**
+ * Updates the global container's position.
+ * @return whether or not the position has actually changed
+ */
+ private boolean updateContainerPosition() {
+ positionAtCursorOffset(getCurrentCursorOffset());
+ TextView.this.getLocationInWindow(mTempCoords);
+ final int containerPositionX = mTempCoords[0] + mPositionX;
+ final int containerPositionY = mTempCoords[1] + mPositionY;
+
+ if (containerPositionX != mContainerPositionX ||
+ containerPositionY != mContainerPositionY) {
+ mContainerPositionX = containerPositionX;
+ mContainerPositionY = containerPositionY;
+ return true;
+ }
+ return false;
+ }
+
+ public boolean onPreDraw() {
+ if (updateContainerPosition()) {
+ if (isPositionVisible()) {
+ mContainer.update(mContainerPositionX, mContainerPositionY,
+ mRight - mLeft, mBottom - mTop);
+
+ if (mIsActive && !isShowing()) {
+ show();
}
} else {
- show();
+ if (isShowing()) {
+ dismiss();
+ }
}
- if (mIsDragging) {
- if (coords == null) {
- coords = mTempCoords;
- TextView.this.getLocationInWindow(coords);
- }
- if (coords[0] != mLastParentX || coords[1] != mLastParentY) {
- mTouchToWindowOffsetX += coords[0] - mLastParentX;
- mTouchToWindowOffsetY += coords[1] - mLastParentY;
- mLastParentX = coords[0];
- mLastParentY = coords[1];
- }
- // Hide paste popup window as soon as the handle is dragged.
- hidePastePopupWindow();
- }
- } else {
- hide();
+ // Hide paste popup as soon as the view is scrolled or moved
+ hideAssociatedPopupWindow();
}
+ return true;
}
@Override
@@ -8906,20 +8819,15 @@
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getActionMasked()) {
case MotionEvent.ACTION_DOWN: {
- startTouchUpFilter(mController.getCurrentOffset(this));
- mDownPositionX = ev.getRawX();
- mDownPositionY = ev.getRawY();
- mTouchToWindowOffsetX = mDownPositionX - mPositionX;
- mTouchToWindowOffsetY = mDownPositionY - mPositionY;
+ startTouchUpFilter(getCurrentCursorOffset());
+ mTouchToWindowOffsetX = ev.getRawX() - mPositionX;
+ mTouchToWindowOffsetY = ev.getRawY() - mPositionY;
final int[] coords = mTempCoords;
TextView.this.getLocationInWindow(coords);
mLastParentX = coords[0];
mLastParentY = coords[1];
mIsDragging = true;
- if (mIsInsertionHandle) {
- mTouchTimer = SystemClock.uptimeMillis();
- }
break;
}
@@ -8943,27 +8851,11 @@
final float newPosX = rawX - mTouchToWindowOffsetX + mHotspotX;
final float newPosY = rawY - mTouchToWindowOffsetY + mTouchOffsetY;
- mController.updatePosition(this, Math.round(newPosX), Math.round(newPosY));
+ updatePosition(Math.round(newPosX), Math.round(newPosY));
break;
}
case MotionEvent.ACTION_UP:
- if (mIsInsertionHandle) {
- long delay = SystemClock.uptimeMillis() - mTouchTimer;
- if (delay < ViewConfiguration.getTapTimeout()) {
- final float deltaX = mDownPositionX - ev.getRawX();
- final float deltaY = mDownPositionY - ev.getRawY();
- final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
- if (distanceSquared < mSquaredTouchSlopDistance) {
- if (mPastePopupWindow != null && mPastePopupWindow.isShowing()) {
- // Tapping on the handle dismisses the displayed paste view,
- mPastePopupWindow.hide();
- } else {
- ((InsertionPointCursorController) mController).show(0);
- }
- }
- }
- }
filterOnTouchUp();
mIsDragging = false;
break;
@@ -8979,104 +8871,40 @@
return mIsDragging;
}
- void positionAtCursor(final int offset) {
- addPositionToTouchUpFilter(offset);
- final int width = mDrawable.getIntrinsicWidth();
- final int height = mDrawable.getIntrinsicHeight();
- final int line = mLayout.getLineForOffset(offset);
- final int lineBottom = mLayout.getLineBottom(line);
-
- final Rect bounds = sCursorControllerTempRect;
- bounds.left = (int) (mLayout.getPrimaryHorizontal(offset) - 0.5f - mHotspotX) +
- TextView.this.mScrollX;
- bounds.top = lineBottom + TextView.this.mScrollY;
-
- bounds.right = bounds.left + width;
- bounds.bottom = bounds.top + height;
-
- convertFromViewportToContentCoordinates(bounds);
- moveTo(bounds.left, bounds.top);
+ void hideAssociatedPopupWindow() {
+ // No associated popup window by default
}
-
- void showPastePopupWindow() {
- if (mIsInsertionHandle) {
- if (mPastePopupWindow == null) {
- // Lazy initialisation: create when actually shown only.
- mPastePopupWindow = new PastePopupMenu();
- }
- mPastePopupWindow.show();
- }
- }
-
- void hidePastePopupWindow() {
- if (mPastePopupWindow != null) {
- mPastePopupWindow.hide();
- }
- }
-
- /**
- * A popup window, attached to a view, and that listens to scroll events in its anchors'
- * view hierarchy, so that it is automatically moved on such events.
- */
- private class ScrollingPopupWindow extends PopupWindow {
-
- private int[] mDrawingLocations = new int[2];
-
- public ScrollingPopupWindow(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
-
- @Override
- public boolean findDropDownPosition(View anchor, WindowManager.LayoutParams p,
- int xoff, int yoff) {
- anchor.getLocationInWindow(mDrawingLocations);
- p.x = mDrawingLocations[0] + xoff;
- p.y = mDrawingLocations[1] + anchor.getHeight() + yoff;
-
- // Hide paste popup as soon as the view is scrolled.
- hidePastePopupWindow();
-
- if (!isPositionVisible()) {
- dismiss();
- onHandleBecomeInvisible();
- }
-
- return false;
- }
- }
-
- public void onScrollChanged() {
- if (isPositionVisible()) {
- show();
- ViewTreeObserver vto = TextView.this.getViewTreeObserver();
- vto.removeOnScrollChangedListener(this);
- }
- }
-
- public void onHandleBecomeInvisible() {
- ViewTreeObserver vto = TextView.this.getViewTreeObserver();
- vto.addOnScrollChangedListener(this);
+
+ public void onDetached() {
+ // Should be overriden to clean possible Runnable
}
}
- private class InsertionPointCursorController implements CursorController {
+ private class InsertionHandleView extends HandleView {
private static final int DELAY_BEFORE_FADE_OUT = 4000;
- private static final int DELAY_BEFORE_PASTE = 2000;
- private static final int RECENT_CUT_COPY_DURATION = 15 * 1000;
+ private static final int RECENT_CUT_COPY_DURATION = 15 * 1000; // seconds
- // The cursor controller image. Lazily created.
- private HandleView mHandle;
+ // Used to detect taps on the insertion handle, which will affect the PastePopupMenu
+ private long mTouchTimer;
+ private float mDownPositionX, mDownPositionY;
+ private PastePopupMenu mPastePopupWindow;
private Runnable mHider;
private Runnable mPastePopupShower;
+ public InsertionHandleView() {
+ super();
+ }
+
+ @Override
public void show() {
- show(DELAY_BEFORE_PASTE);
+ super.show();
+ hideDelayed();
+ removePastePopupCallback();
}
public void show(int delayBeforePaste) {
- updatePosition();
- hideDelayed();
- removePastePopupCallback();
+ show();
+
final long durationSinceCutOrCopy = SystemClock.uptimeMillis() - sLastCutOrCopyTime;
if (durationSinceCutOrCopy < RECENT_CUT_COPY_DURATION) {
delayBeforePaste = 0;
@@ -9085,7 +8913,7 @@
if (mPastePopupShower == null) {
mPastePopupShower = new Runnable() {
public void run() {
- getHandle().showPastePopupWindow();
+ showAssociatedPopupWindow();
}
};
}
@@ -9093,24 +8921,15 @@
}
}
- private void removePastePopupCallback() {
- if (mPastePopupShower != null) {
- removeCallbacks(mPastePopupShower);
- }
+ @Override
+ protected void dismiss() {
+ super.dismiss();
+ onDetached();
}
- private void removeHiderCallback() {
- if (mHider != null) {
- removeCallbacks(mHider);
- }
- }
-
+ @Override
public void hide() {
- if (mHandle != null) {
- mHandle.hide();
- }
- removeHiderCallback();
- removePastePopupCallback();
+ super.hide();
}
private void hideDelayed() {
@@ -9125,41 +8944,244 @@
postDelayed(mHider, DELAY_BEFORE_FADE_OUT);
}
- public boolean isShowing() {
- return mHandle != null && mHandle.isShowing();
+ private void removePastePopupCallback() {
+ if (mPastePopupShower != null) {
+ removeCallbacks(mPastePopupShower);
+ }
}
- public void updatePosition(HandleView handle, int x, int y) {
- final int previousOffset = getSelectionStart();
+ private void removeHiderCallback() {
+ if (mHider != null) {
+ removeCallbacks(mHider);
+ }
+ }
+
+ @Override
+ protected void initDrawable() {
+ if (mSelectHandleCenter == null) {
+ mSelectHandleCenter = mContext.getResources().getDrawable(
+ mTextSelectHandleRes);
+ }
+ mDrawable = mSelectHandleCenter;
+ mHotspotX = mDrawable.getIntrinsicWidth() / 2.0f;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ final boolean result = super.onTouchEvent(ev);
+
+ switch (ev.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN:
+ mDownPositionX = ev.getRawX();
+ mDownPositionY = ev.getRawY();
+ mTouchTimer = SystemClock.uptimeMillis();
+ break;
+
+ case MotionEvent.ACTION_UP:
+ long delay = SystemClock.uptimeMillis() - mTouchTimer;
+ if (delay < ViewConfiguration.getTapTimeout()) {
+ final float deltaX = mDownPositionX - ev.getRawX();
+ final float deltaY = mDownPositionY - ev.getRawY();
+ final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
+ if (distanceSquared < mSquaredTouchSlopDistance) {
+ if (mPastePopupWindow != null && mPastePopupWindow.isShowing()) {
+ // Tapping on the handle dismisses the displayed paste view,
+ mPastePopupWindow.hide();
+ } else {
+ show(0);
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return result;
+ }
+
+ @Override
+ public int getCurrentCursorOffset() {
+ return TextView.this.getSelectionStart();
+ }
+
+ @Override
+ public void updateOffset(int offset) {
+ Selection.setSelection((Spannable) mText, offset);
+ positionAtCursorOffset(offset);
+ }
+
+ @Override
+ public void updatePosition(int x, int y) {
+ final int previousOffset = getCurrentCursorOffset();
final int newOffset = getOffset(x, y);
if (newOffset != previousOffset) {
- updateOffset(handle, newOffset);
+ updateOffset(newOffset);
removePastePopupCallback();
}
hideDelayed();
}
- public void updateOffset(HandleView handle, int offset) {
- Selection.setSelection((Spannable) mText, offset);
- updatePosition();
- }
-
- public void updatePosition() {
- final int offset = getSelectionStart();
-
- if (offset < 0) {
- // Should never happen, safety check.
- Log.w(LOG_TAG, "Update cursor controller position called with no cursor");
- hide();
- return;
+ void showAssociatedPopupWindow() {
+ if (mPastePopupWindow == null) {
+ // Lazy initialisation: create when actually shown only.
+ mPastePopupWindow = new PastePopupMenu();
}
-
- getHandle().positionAtCursor(offset);
+ mPastePopupWindow.show();
}
- public int getCurrentOffset(HandleView handle) {
- return getSelectionStart();
+ @Override
+ void hideAssociatedPopupWindow() {
+ if (mPastePopupWindow != null) {
+ mPastePopupWindow.hide();
+ }
+ }
+
+ @Override
+ public void onDetached() {
+ removeHiderCallback();
+ removePastePopupCallback();
+ }
+ }
+
+ private class SelectionStartHandleView extends HandleView {
+ public SelectionStartHandleView() {
+ super();
+ }
+
+ @Override
+ protected void initDrawable() {
+ if (mSelectHandleLeft == null) {
+ mSelectHandleLeft = mContext.getResources().getDrawable(
+ mTextSelectHandleLeftRes);
+ }
+ mDrawable = mSelectHandleLeft;
+ mHotspotX = mDrawable.getIntrinsicWidth() * 3.0f / 4.0f;
+ }
+
+ @Override
+ public int getCurrentCursorOffset() {
+ return TextView.this.getSelectionStart();
+ }
+
+ @Override
+ public void updateOffset(int offset) {
+ Selection.setSelection((Spannable) mText, offset, getSelectionEnd());
+ positionAtCursorOffset(offset);
+ }
+
+ @Override
+ public void updatePosition(int x, int y) {
+ final int selectionStart = getSelectionStart();
+ final int selectionEnd = getSelectionEnd();
+
+ int offset = getOffset(x, y);
+
+ // No need to redraw when the offset is unchanged
+ if (offset == selectionStart) return;
+ // Handles can not cross and selection is at least one character
+ if (offset >= selectionEnd) offset = selectionEnd - 1;
+
+ Selection.setSelection((Spannable) mText, offset, selectionEnd);
+ positionAtCursorOffset(offset);
+ }
+ }
+
+ private class SelectionEndHandleView extends HandleView {
+ public SelectionEndHandleView() {
+ super();
+ }
+
+ @Override
+ protected void initDrawable() {
+ if (mSelectHandleRight == null) {
+ mSelectHandleRight = mContext.getResources().getDrawable(
+ mTextSelectHandleRightRes);
+ }
+ mDrawable = mSelectHandleRight;
+ mHotspotX = mDrawable.getIntrinsicWidth() / 4.0f;
+ }
+
+ @Override
+ public int getCurrentCursorOffset() {
+ return TextView.this.getSelectionEnd();
+ }
+
+ @Override
+ public void updateOffset(int offset) {
+ Selection.setSelection((Spannable) mText, getSelectionStart(), offset);
+ positionAtCursorOffset(offset);
+ }
+
+ @Override
+ public void updatePosition(int x, int y) {
+ final int selectionStart = getSelectionStart();
+ final int selectionEnd = getSelectionEnd();
+
+ int offset = getOffset(x, y);
+
+ // No need to redraw when the offset is unchanged
+ if (offset == selectionEnd) return;
+ // Handles can not cross and selection is at least one character
+ if (offset <= selectionStart) offset = selectionStart + 1;
+
+ Selection.setSelection((Spannable) mText, selectionStart, offset);
+ positionAtCursorOffset(offset);
+ }
+ }
+
+ /**
+ * A CursorController instance can be used to control a cursor in the text.
+ * It is not used outside of {@link TextView}.
+ * @hide
+ */
+ private interface CursorController extends ViewTreeObserver.OnTouchModeChangeListener {
+ /**
+ * Makes the cursor controller visible on screen. Will be drawn by {@link #draw(Canvas)}.
+ * See also {@link #hide()}.
+ */
+ public void show();
+
+ /**
+ * Hide the cursor controller from screen.
+ * See also {@link #show()}.
+ */
+ public void hide();
+
+ /**
+ * This method is called by {@link #onTouchEvent(MotionEvent)} and gives the controller
+ * a chance to become active and/or visible.
+ * @param event The touch event
+ */
+ public boolean onTouchEvent(MotionEvent event);
+
+ /**
+ * Called when the view is detached from window. Perform house keeping task, such as
+ * stopping Runnable thread that would otherwise keep a reference on the context, thus
+ * preventing the activity from being recycled.
+ */
+ public void onDetached();
+ }
+
+ private class InsertionPointCursorController implements CursorController {
+ private static final int DELAY_BEFORE_PASTE = 2000;
+
+ private InsertionHandleView mHandle;
+
+ public void show() {
+ ((InsertionHandleView) getHandle()).show(DELAY_BEFORE_PASTE);
+ }
+
+ public void showWithPaste() {
+ ((InsertionHandleView) getHandle()).show(0);
+ }
+
+ public void hide() {
+ if (mHandle != null) {
+ mHandle.hide();
+ }
}
public boolean onTouchEvent(MotionEvent ev) {
@@ -9174,30 +9196,27 @@
private HandleView getHandle() {
if (mHandle == null) {
- mHandle = new HandleView(this, HandleView.CENTER);
+ mHandle = new InsertionHandleView();
}
return mHandle;
}
@Override
public void onDetached() {
- removeHiderCallback();
- removePastePopupCallback();
+ if (mHandle == null) mHandle.onDetached();
}
}
private class SelectionModifierCursorController implements CursorController {
- // The cursor controller images, lazily created when shown.
- private HandleView mStartHandle, mEndHandle;
+ // The cursor controller handles, lazily created when shown.
+ private SelectionStartHandleView mStartHandle;
+ private SelectionEndHandleView mEndHandle;
// The offsets of that last touch down event. Remembered to start selection there.
private int mMinTouchOffset, mMaxTouchOffset;
- // Whether selection anchors are active
- private boolean mIsShowing;
// Double tap detection
private long mPreviousTapUpTime = 0;
- private int mPreviousTapPositionX;
- private int mPreviousTapPositionY;
+ private int mPreviousTapPositionX, mPreviousTapPositionY;
SelectionModifierCursorController() {
resetTouchOffsets();
@@ -9209,11 +9228,8 @@
}
// Lazy object creation has to be done before updatePosition() is called.
- if (mStartHandle == null) mStartHandle = new HandleView(this, HandleView.LEFT);
- if (mEndHandle == null) mEndHandle = new HandleView(this, HandleView.RIGHT);
-
- mIsShowing = true;
- updatePosition();
+ if (mStartHandle == null) mStartHandle = new SelectionStartHandleView();
+ if (mEndHandle == null) mEndHandle = new SelectionEndHandleView();
mStartHandle.show();
mEndHandle.show();
@@ -9224,82 +9240,6 @@
public void hide() {
if (mStartHandle != null) mStartHandle.hide();
if (mEndHandle != null) mEndHandle.hide();
- mIsShowing = false;
- }
-
- public boolean isShowing() {
- return mIsShowing;
- }
-
- public void updatePosition(HandleView handle, int x, int y) {
- int selectionStart = getSelectionStart();
- int selectionEnd = getSelectionEnd();
-
- int offset = getOffset(x, y);
-
- // Handle the case where start and end are swapped, making sure start <= end
- if (handle == mStartHandle) {
- if (selectionStart == offset || offset > selectionEnd) {
- return; // no change, no need to redraw;
- }
- // If the user "closes" the selection entirely they were probably trying to
- // select a single character. Help them out.
- if (offset == selectionEnd) {
- offset = selectionEnd - 1;
- }
- selectionStart = offset;
- } else {
- if (selectionEnd == offset || offset < selectionStart) {
- return; // no change, no need to redraw;
- }
- // If the user "closes" the selection entirely they were probably trying to
- // select a single character. Help them out.
- if (offset == selectionStart) {
- offset = selectionStart + 1;
- }
- selectionEnd = offset;
- }
-
- Selection.setSelection((Spannable) mText, selectionStart, selectionEnd);
- updatePosition();
- }
-
- public void updateOffset(HandleView handle, int offset) {
- int start = getSelectionStart();
- int end = getSelectionEnd();
-
- if (mStartHandle == handle) {
- start = offset;
- } else {
- end = offset;
- }
-
- Selection.setSelection((Spannable) mText, start, end);
- updatePosition();
- }
-
- public void updatePosition() {
- if (!isShowing()) {
- return;
- }
-
- final int selectionStart = getSelectionStart();
- final int selectionEnd = getSelectionEnd();
-
- if ((selectionStart < 0) || (selectionEnd < 0)) {
- // Should never happen, safety check.
- Log.w(LOG_TAG, "Update selection controller position called with no cursor");
- hide();
- return;
- }
-
- // The handles have been created since the controller isShowing().
- mStartHandle.positionAtCursor(selectionStart);
- mEndHandle.positionAtCursor(selectionEnd);
- }
-
- public int getCurrentOffset(HandleView handle) {
- return mStartHandle == handle ? getSelectionStart() : getSelectionEnd();
}
public boolean onTouchEvent(MotionEvent event) {
@@ -9390,7 +9330,10 @@
}
@Override
- public void onDetached() {}
+ public void onDetached() {
+ if (mStartHandle != null) mStartHandle.onDetached();
+ if (mEndHandle != null) mEndHandle.onDetached();
+ }
}
private void hideInsertionPointCursorController() {
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index fb2a72b..2e56996 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -68,7 +68,7 @@
protected void onCreate(Bundle savedInstanceState, Intent intent,
CharSequence title, Intent[] initialIntents, List<ResolveInfo> rList,
- boolean alwaysUseOption, boolean alwaysChoose) {
+ boolean alwaysUseOption) {
super.onCreate(savedInstanceState);
mPm = getPackageManager();
intent.setComponent(null);
@@ -91,7 +91,7 @@
}
mAdapter = new ResolveListAdapter(this, intent, initialIntents, rList);
int count = mAdapter.getCount();
- if (count > 1 || (count == 1 && alwaysChoose)) {
+ if (count > 1) {
ap.mAdapter = mAdapter;
} else if (count == 1) {
startActivity(mAdapter.intentForPosition(0));
@@ -104,12 +104,6 @@
setupAlert();
}
- protected void onCreate(Bundle savedInstanceState, Intent intent,
- CharSequence title, Intent[] initialIntents, List<ResolveInfo> rList,
- boolean alwaysUseOption) {
- onCreate(savedInstanceState, intent, title, initialIntents, rList, alwaysUseOption, false);
- }
-
public void onClick(DialogInterface dialog, int which) {
ResolveInfo ri = mAdapter.resolveInfoForPosition(which);
Intent intent = mAdapter.intentForPosition(which);
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 1cca21d..d86504d 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -1581,7 +1581,7 @@
// Update discharge amounts.
if (mOnBatteryInternal) {
- updateDischargeScreenLevels(false, true);
+ updateDischargeScreenLevelsLocked(false, true);
}
}
}
@@ -1602,7 +1602,7 @@
// Update discharge amounts.
if (mOnBatteryInternal) {
- updateDischargeScreenLevels(true, false);
+ updateDischargeScreenLevelsLocked(true, false);
}
}
}
@@ -4030,7 +4030,7 @@
clearHistoryLocked();
}
- void updateDischargeScreenLevels(boolean oldScreenOn, boolean newScreenOn) {
+ void updateDischargeScreenLevelsLocked(boolean oldScreenOn, boolean newScreenOn) {
if (oldScreenOn) {
int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel;
if (diff > 0) {
@@ -4055,69 +4055,73 @@
void setOnBattery(boolean onBattery, int oldStatus, int level) {
synchronized(this) {
- boolean doWrite = false;
- Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE);
- m.arg1 = onBattery ? 1 : 0;
- mHandler.sendMessage(m);
- mOnBattery = mOnBatteryInternal = onBattery;
+ setOnBatteryLocked(onBattery, oldStatus, level);
+ }
+ }
- long uptime = SystemClock.uptimeMillis() * 1000;
- long mSecRealtime = SystemClock.elapsedRealtime();
- long realtime = mSecRealtime * 1000;
- if (onBattery) {
- // We will reset our status if we are unplugging after the
- // battery was last full, or the level is at 100, or
- // we have gone through a significant charge (from a very low
- // level to a now very high level).
- if (oldStatus == BatteryManager.BATTERY_STATUS_FULL
- || level >= 90
- || (mDischargeCurrentLevel < 20 && level >= 80)) {
- doWrite = true;
- resetAllStatsLocked();
- mDischargeStartLevel = level;
- }
- updateKernelWakelocksLocked();
- mHistoryCur.batteryLevel = (byte)level;
- mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
- if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
- + Integer.toHexString(mHistoryCur.states));
- addHistoryRecordLocked(mSecRealtime);
- mTrackBatteryUptimeStart = uptime;
- mTrackBatteryRealtimeStart = realtime;
- mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime);
- mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime);
- mDischargeCurrentLevel = mDischargeUnplugLevel = level;
- if (mScreenOn) {
- mDischargeScreenOnUnplugLevel = level;
- mDischargeScreenOffUnplugLevel = 0;
- } else {
- mDischargeScreenOnUnplugLevel = 0;
- mDischargeScreenOffUnplugLevel = level;
- }
- mDischargeAmountScreenOn = 0;
- mDischargeAmountScreenOff = 0;
- doUnplugLocked(mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime);
- } else {
- updateKernelWakelocksLocked();
- mHistoryCur.batteryLevel = (byte)level;
- mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
- if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: "
- + Integer.toHexString(mHistoryCur.states));
- addHistoryRecordLocked(mSecRealtime);
- mTrackBatteryPastUptime += uptime - mTrackBatteryUptimeStart;
- mTrackBatteryPastRealtime += realtime - mTrackBatteryRealtimeStart;
- mDischargeCurrentLevel = level;
- if (level < mDischargeUnplugLevel) {
- mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1;
- mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level;
- }
- updateDischargeScreenLevels(mScreenOn, mScreenOn);
- doPlugLocked(getBatteryUptimeLocked(uptime), getBatteryRealtimeLocked(realtime));
+ void setOnBatteryLocked(boolean onBattery, int oldStatus, int level) {
+ boolean doWrite = false;
+ Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE);
+ m.arg1 = onBattery ? 1 : 0;
+ mHandler.sendMessage(m);
+ mOnBattery = mOnBatteryInternal = onBattery;
+
+ long uptime = SystemClock.uptimeMillis() * 1000;
+ long mSecRealtime = SystemClock.elapsedRealtime();
+ long realtime = mSecRealtime * 1000;
+ if (onBattery) {
+ // We will reset our status if we are unplugging after the
+ // battery was last full, or the level is at 100, or
+ // we have gone through a significant charge (from a very low
+ // level to a now very high level).
+ if (oldStatus == BatteryManager.BATTERY_STATUS_FULL
+ || level >= 90
+ || (mDischargeCurrentLevel < 20 && level >= 80)) {
+ doWrite = true;
+ resetAllStatsLocked();
+ mDischargeStartLevel = level;
}
- if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) {
- if (mFile != null) {
- writeAsyncLocked();
- }
+ updateKernelWakelocksLocked();
+ mHistoryCur.batteryLevel = (byte)level;
+ mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
+ + Integer.toHexString(mHistoryCur.states));
+ addHistoryRecordLocked(mSecRealtime);
+ mTrackBatteryUptimeStart = uptime;
+ mTrackBatteryRealtimeStart = realtime;
+ mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime);
+ mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime);
+ mDischargeCurrentLevel = mDischargeUnplugLevel = level;
+ if (mScreenOn) {
+ mDischargeScreenOnUnplugLevel = level;
+ mDischargeScreenOffUnplugLevel = 0;
+ } else {
+ mDischargeScreenOnUnplugLevel = 0;
+ mDischargeScreenOffUnplugLevel = level;
+ }
+ mDischargeAmountScreenOn = 0;
+ mDischargeAmountScreenOff = 0;
+ doUnplugLocked(mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime);
+ } else {
+ updateKernelWakelocksLocked();
+ mHistoryCur.batteryLevel = (byte)level;
+ mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: "
+ + Integer.toHexString(mHistoryCur.states));
+ addHistoryRecordLocked(mSecRealtime);
+ mTrackBatteryPastUptime += uptime - mTrackBatteryUptimeStart;
+ mTrackBatteryPastRealtime += realtime - mTrackBatteryRealtimeStart;
+ mDischargeCurrentLevel = level;
+ if (level < mDischargeUnplugLevel) {
+ mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1;
+ mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level;
+ }
+ updateDischargeScreenLevelsLocked(mScreenOn, mScreenOn);
+ doPlugLocked(getBatteryUptimeLocked(uptime), getBatteryRealtimeLocked(realtime));
+ }
+ if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) {
+ if (mFile != null) {
+ writeAsyncLocked();
}
}
}
@@ -4127,71 +4131,73 @@
public void setBatteryState(int status, int health, int plugType, int level,
int temp, int volt) {
- boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
- int oldStatus = mHistoryCur.batteryStatus;
- if (!mHaveBatteryLevel) {
- mHaveBatteryLevel = true;
- // We start out assuming that the device is plugged in (not
- // on battery). If our first report is now that we are indeed
- // plugged in, then twiddle our state to correctly reflect that
- // since we won't be going through the full setOnBattery().
- if (onBattery == mOnBattery) {
- if (onBattery) {
- mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
- } else {
- mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
+ synchronized(this) {
+ boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
+ int oldStatus = mHistoryCur.batteryStatus;
+ if (!mHaveBatteryLevel) {
+ mHaveBatteryLevel = true;
+ // We start out assuming that the device is plugged in (not
+ // on battery). If our first report is now that we are indeed
+ // plugged in, then twiddle our state to correctly reflect that
+ // since we won't be going through the full setOnBattery().
+ if (onBattery == mOnBattery) {
+ if (onBattery) {
+ mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
+ } else {
+ mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
+ }
+ }
+ oldStatus = status;
+ }
+ if (onBattery) {
+ mDischargeCurrentLevel = level;
+ mRecordingHistory = true;
+ }
+ if (onBattery != mOnBattery) {
+ mHistoryCur.batteryLevel = (byte)level;
+ mHistoryCur.batteryStatus = (byte)status;
+ mHistoryCur.batteryHealth = (byte)health;
+ mHistoryCur.batteryPlugType = (byte)plugType;
+ mHistoryCur.batteryTemperature = (char)temp;
+ mHistoryCur.batteryVoltage = (char)volt;
+ setOnBatteryLocked(onBattery, oldStatus, level);
+ } else {
+ boolean changed = false;
+ if (mHistoryCur.batteryLevel != level) {
+ mHistoryCur.batteryLevel = (byte)level;
+ changed = true;
+ }
+ if (mHistoryCur.batteryStatus != status) {
+ mHistoryCur.batteryStatus = (byte)status;
+ changed = true;
+ }
+ if (mHistoryCur.batteryHealth != health) {
+ mHistoryCur.batteryHealth = (byte)health;
+ changed = true;
+ }
+ if (mHistoryCur.batteryPlugType != plugType) {
+ mHistoryCur.batteryPlugType = (byte)plugType;
+ changed = true;
+ }
+ if (temp >= (mHistoryCur.batteryTemperature+10)
+ || temp <= (mHistoryCur.batteryTemperature-10)) {
+ mHistoryCur.batteryTemperature = (char)temp;
+ changed = true;
+ }
+ if (volt > (mHistoryCur.batteryVoltage+20)
+ || volt < (mHistoryCur.batteryVoltage-20)) {
+ mHistoryCur.batteryVoltage = (char)volt;
+ changed = true;
+ }
+ if (changed) {
+ addHistoryRecordLocked(SystemClock.elapsedRealtime());
}
}
- oldStatus = status;
- }
- if (onBattery) {
- mDischargeCurrentLevel = level;
- mRecordingHistory = true;
- }
- if (onBattery != mOnBattery) {
- mHistoryCur.batteryLevel = (byte)level;
- mHistoryCur.batteryStatus = (byte)status;
- mHistoryCur.batteryHealth = (byte)health;
- mHistoryCur.batteryPlugType = (byte)plugType;
- mHistoryCur.batteryTemperature = (char)temp;
- mHistoryCur.batteryVoltage = (char)volt;
- setOnBattery(onBattery, oldStatus, level);
- } else {
- boolean changed = false;
- if (mHistoryCur.batteryLevel != level) {
- mHistoryCur.batteryLevel = (byte)level;
- changed = true;
+ if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) {
+ // We don't record history while we are plugged in and fully charged.
+ // The next time we are unplugged, history will be cleared.
+ mRecordingHistory = false;
}
- if (mHistoryCur.batteryStatus != status) {
- mHistoryCur.batteryStatus = (byte)status;
- changed = true;
- }
- if (mHistoryCur.batteryHealth != health) {
- mHistoryCur.batteryHealth = (byte)health;
- changed = true;
- }
- if (mHistoryCur.batteryPlugType != plugType) {
- mHistoryCur.batteryPlugType = (byte)plugType;
- changed = true;
- }
- if (temp >= (mHistoryCur.batteryTemperature+10)
- || temp <= (mHistoryCur.batteryTemperature-10)) {
- mHistoryCur.batteryTemperature = (char)temp;
- changed = true;
- }
- if (volt > (mHistoryCur.batteryVoltage+20)
- || volt < (mHistoryCur.batteryVoltage-20)) {
- mHistoryCur.batteryVoltage = (char)volt;
- changed = true;
- }
- if (changed) {
- addHistoryRecordLocked(SystemClock.elapsedRealtime());
- }
- }
- if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) {
- // We don't record history while we are plugged in and fully charged.
- // The next time we are unplugged, history will be cleared.
- mRecordingHistory = false;
}
}
diff --git a/core/java/com/android/internal/util/AsyncChannel.java b/core/java/com/android/internal/util/AsyncChannel.java
index 101dd91..4d656c0c 100644
--- a/core/java/com/android/internal/util/AsyncChannel.java
+++ b/core/java/com/android/internal/util/AsyncChannel.java
@@ -135,6 +135,8 @@
* channel is forcibly disconnected by the system or as a reply to CMD_CHANNEL_DISCONNECT.
*
* msg.arg1 == 0 : STATUS_SUCCESSFUL
+ * 1 : STATUS_BINDING_UNSUCCESSFUL
+ * 2 : STATUS_SEND_UNSUCCESSFUL
* : All other values signify failure and the channel state is indeterminate
* msg.obj == the AsyncChannel
* msg.replyTo = messenger disconnecting or null if it was never connected.
@@ -147,6 +149,9 @@
/** Error attempting to bind on a connect */
public static final int STATUS_BINDING_UNSUCCESSFUL = 1;
+ /** Error attempting to send a message */
+ public static final int STATUS_SEND_UNSUCCESSFUL = 2;
+
/** Service connection */
private AsyncChannelConnection mConnection;
@@ -345,11 +350,7 @@
mSrcContext.unbindService(mConnection);
}
if (mSrcHandler != null) {
- Message msg = mSrcHandler.obtainMessage(CMD_CHANNEL_DISCONNECTED);
- msg.arg1 = STATUS_SUCCESSFUL;
- msg.obj = this;
- msg.replyTo = mDstMessenger;
- mSrcHandler.sendMessage(msg);
+ replyDisconnected(STATUS_SUCCESSFUL);
}
}
@@ -363,7 +364,7 @@
try {
mDstMessenger.send(msg);
} catch (RemoteException e) {
- log("TODO: handle sendMessage RemoteException" + e);
+ replyDisconnected(STATUS_SEND_UNSUCCESSFUL);
}
}
@@ -712,6 +713,7 @@
/**
* Reply to the src handler that we're half connected.
+ * see: CMD_CHANNEL_HALF_CONNECTED for message contents
*
* @param status to be stored in msg.arg1
*/
@@ -724,6 +726,21 @@
}
/**
+ * Reply to the src handler that we are disconnected
+ * see: CMD_CHANNEL_DISCONNECTED for message contents
+ *
+ * @param status to be stored in msg.arg1
+ */
+ private void replyDisconnected(int status) {
+ Message msg = mSrcHandler.obtainMessage(CMD_CHANNEL_DISCONNECTED);
+ msg.arg1 = status;
+ msg.obj = this;
+ msg.replyTo = mDstMessenger;
+ mSrcHandler.sendMessage(msg);
+ }
+
+
+ /**
* ServiceConnection to receive call backs.
*/
class AsyncChannelConnection implements ServiceConnection {
@@ -736,11 +753,7 @@
}
public void onServiceDisconnected(ComponentName className) {
- Message msg = mSrcHandler.obtainMessage(CMD_CHANNEL_DISCONNECTED);
- msg.arg1 = STATUS_SUCCESSFUL;
- msg.obj = AsyncChannel.this;
- msg.replyTo = mDstMessenger;
- mSrcHandler.sendMessage(msg);
+ replyDisconnected(STATUS_SUCCESSFUL);
}
}
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index e3a66c5..586ba87 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -43,6 +43,7 @@
import android.view.ViewParent;
import android.view.Window;
import android.widget.AdapterView;
+import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.LinearLayout;
@@ -385,7 +386,7 @@
if ((flagsChanged & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
mHomeAsUpView.setVisibility((options & ActionBar.DISPLAY_HOME_AS_UP) != 0
- ? VISIBLE : INVISIBLE);
+ ? VISIBLE : GONE);
}
if ((flagsChanged & ActionBar.DISPLAY_USE_LOGO) != 0) {
@@ -957,4 +958,60 @@
}
}
}
+
+ private static class HomeView extends FrameLayout {
+ private View mUpView;
+ private View mIconView;
+
+ public HomeView(Context context) {
+ this(context, null);
+ }
+
+ public HomeView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ mUpView = findViewById(com.android.internal.R.id.up);
+ mIconView = (ImageView) findViewById(com.android.internal.R.id.home);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ measureChildWithMargins(mUpView, widthMeasureSpec, 0, heightMeasureSpec, 0);
+ final LayoutParams upLp = (LayoutParams) mUpView.getLayoutParams();
+ int width = upLp.leftMargin + mUpView.getMeasuredWidth() + upLp.rightMargin;
+ int height = upLp.topMargin + mUpView.getMeasuredHeight() + upLp.bottomMargin;
+ measureChildWithMargins(mIconView, widthMeasureSpec, width, heightMeasureSpec, 0);
+ final LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams();
+ width += iconLp.leftMargin + mIconView.getMeasuredWidth() + iconLp.rightMargin;
+ height = Math.max(height,
+ iconLp.topMargin + mIconView.getMeasuredHeight() + iconLp.bottomMargin);
+ setMeasuredDimension(width, height);
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ final int vCenter = (b - t) / 2;
+ int width = r - l;
+ if (mUpView.getVisibility() != GONE) {
+ final LayoutParams upLp = (LayoutParams) mUpView.getLayoutParams();
+ final int upHeight = mUpView.getMeasuredHeight();
+ final int upWidth = mUpView.getMeasuredWidth();
+ final int upTop = t + vCenter - upHeight / 2;
+ mUpView.layout(l, upTop, l + upWidth, upTop + upHeight);
+ final int upOffset = upLp.leftMargin + upWidth + upLp.rightMargin;
+ width -= upOffset;
+ l += upOffset;
+ }
+ final LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams();
+ final int iconHeight = mIconView.getMeasuredHeight();
+ final int iconWidth = mIconView.getMeasuredWidth();
+ final int hCenter = (r - l) / 2;
+ final int iconLeft = l + iconLp.leftMargin + hCenter - iconWidth / 2;
+ final int iconTop = t + iconLp.topMargin + vCenter - iconHeight / 2;
+ mIconView.layout(iconLeft, iconTop, iconLeft + iconWidth, iconTop + iconHeight);
+ }
+ }
}
diff --git a/core/java/com/android/internal/widget/PointerLocationView.java b/core/java/com/android/internal/widget/PointerLocationView.java
index 5ac903d..076a1cb 100644
--- a/core/java/com/android/internal/widget/PointerLocationView.java
+++ b/core/java/com/android/internal/widget/PointerLocationView.java
@@ -23,6 +23,7 @@
import android.graphics.Paint.FontMetricsInt;
import android.util.Log;
import android.view.InputDevice;
+import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
@@ -97,7 +98,8 @@
public PointerLocationView(Context c) {
super(c);
- setFocusable(true);
+ setFocusableInTouchMode(true);
+
mVC = ViewConfiguration.get(c);
mTextPaint = new Paint();
mTextPaint.setAntiAlias(true);
@@ -505,22 +507,69 @@
@Override
public boolean onTouchEvent(MotionEvent event) {
addPointerEvent(event);
+
+ if (event.getAction() == MotionEvent.ACTION_DOWN && !isFocused()) {
+ requestFocus();
+ }
return true;
}
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
- if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+ final int source = event.getSource();
+ if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {
addPointerEvent(event);
+ } else if ((source & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
+ Log.i(TAG, "Joystick: " + event);
+ } else if ((source & InputDevice.SOURCE_CLASS_POSITION) != 0) {
+ Log.i(TAG, "Position: " + event);
+ } else {
+ Log.i(TAG, "Generic: " + event);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ if (shouldLogKey(keyCode)) {
+ final int repeatCount = event.getRepeatCount();
+ if (repeatCount == 0) {
+ Log.i(TAG, "Key Down: " + event);
+ } else {
+ Log.i(TAG, "Key Repeat #" + repeatCount + ": " + event);
+ }
return true;
}
- return super.onGenericMotionEvent(event);
+ return super.onKeyDown(keyCode, event);
+ }
+
+ @Override
+ public boolean onKeyUp(int keyCode, KeyEvent event) {
+ if (shouldLogKey(keyCode)) {
+ Log.i(TAG, "Key Up: " + event);
+ return true;
+ }
+ return super.onKeyUp(keyCode, event);
+ }
+
+ private static boolean shouldLogKey(int keyCode) {
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_DPAD_UP:
+ case KeyEvent.KEYCODE_DPAD_DOWN:
+ case KeyEvent.KEYCODE_DPAD_LEFT:
+ case KeyEvent.KEYCODE_DPAD_RIGHT:
+ case KeyEvent.KEYCODE_DPAD_CENTER:
+ return true;
+ default:
+ return KeyEvent.isGamepadButton(keyCode)
+ || KeyEvent.isModifierKey(keyCode);
+ }
}
@Override
public boolean onTrackballEvent(MotionEvent event) {
Log.i(TAG, "Trackball: " + event);
- return super.onTrackballEvent(event);
+ return true;
}
// HACK
diff --git a/core/java/com/android/internal/widget/WaveView.java b/core/java/com/android/internal/widget/WaveView.java
index d6f2e1ae..288865f 100644
--- a/core/java/com/android/internal/widget/WaveView.java
+++ b/core/java/com/android/internal/widget/WaveView.java
@@ -40,7 +40,7 @@
public class WaveView extends View implements ValueAnimator.AnimatorUpdateListener {
private static final String TAG = "WaveView";
private static final boolean DBG = false;
- private static final int WAVE_COUNT = 5; // default wave count
+ private static final int WAVE_COUNT = 20; // default wave count
private static final long VIBRATE_SHORT = 20; // msec
private static final long VIBRATE_LONG = 20; // msec
diff --git a/core/java/com/google/android/mms/pdu/PduParser.java b/core/java/com/google/android/mms/pdu/PduParser.java
old mode 100644
new mode 100755
index 8edfe52..3f185aa
--- a/core/java/com/google/android/mms/pdu/PduParser.java
+++ b/core/java/com/google/android/mms/pdu/PduParser.java
@@ -29,6 +29,8 @@
import java.util.Arrays;
import java.util.HashMap;
+import android.content.res.Resources;
+
public class PduParser {
/**
* The next are WAP values defined in WSP specification.
@@ -1557,43 +1559,55 @@
* Attachment = <Octet 129>
* Inline = <Octet 130>
*/
- int len = parseValueLength(pduDataStream);
- pduDataStream.mark(1);
- int thisStartPos = pduDataStream.available();
- int thisEndPos = 0;
- int value = pduDataStream.read();
- if (value == PduPart.P_DISPOSITION_FROM_DATA ) {
- part.setContentDisposition(PduPart.DISPOSITION_FROM_DATA);
- } else if (value == PduPart.P_DISPOSITION_ATTACHMENT) {
- part.setContentDisposition(PduPart.DISPOSITION_ATTACHMENT);
- } else if (value == PduPart.P_DISPOSITION_INLINE) {
- part.setContentDisposition(PduPart.DISPOSITION_INLINE);
- } else {
- pduDataStream.reset();
- /* Token-text */
- part.setContentDisposition(parseWapString(pduDataStream, TYPE_TEXT_STRING));
- }
+ /*
+ * some carrier mmsc servers do not support content_disposition
+ * field correctly
+ */
+ boolean contentDisposition = Resources.getSystem().getBoolean(com
+ .android.internal.R.bool.config_mms_content_disposition_support);
- /* get filename parameter and skip other parameters */
- thisEndPos = pduDataStream.available();
- if (thisStartPos - thisEndPos < len) {
- value = pduDataStream.read();
- if (value == PduPart.P_FILENAME) { //filename is text-string
- part.setFilename(parseWapString(pduDataStream, TYPE_TEXT_STRING));
+ if (contentDisposition) {
+ int len = parseValueLength(pduDataStream);
+ pduDataStream.mark(1);
+ int thisStartPos = pduDataStream.available();
+ int thisEndPos = 0;
+ int value = pduDataStream.read();
+
+ if (value == PduPart.P_DISPOSITION_FROM_DATA ) {
+ part.setContentDisposition(PduPart.DISPOSITION_FROM_DATA);
+ } else if (value == PduPart.P_DISPOSITION_ATTACHMENT) {
+ part.setContentDisposition(PduPart.DISPOSITION_ATTACHMENT);
+ } else if (value == PduPart.P_DISPOSITION_INLINE) {
+ part.setContentDisposition(PduPart.DISPOSITION_INLINE);
+ } else {
+ pduDataStream.reset();
+ /* Token-text */
+ part.setContentDisposition(parseWapString(pduDataStream
+ , TYPE_TEXT_STRING));
}
- /* skip other parameters */
+ /* get filename parameter and skip other parameters */
thisEndPos = pduDataStream.available();
if (thisStartPos - thisEndPos < len) {
- int last = len - (thisStartPos - thisEndPos);
- byte[] temp = new byte[last];
- pduDataStream.read(temp, 0, last);
- }
- }
+ value = pduDataStream.read();
+ if (value == PduPart.P_FILENAME) { //filename is text-string
+ part.setFilename(parseWapString(pduDataStream
+ , TYPE_TEXT_STRING));
+ }
- tempPos = pduDataStream.available();
- lastLen = length - (startPos - tempPos);
+ /* skip other parameters */
+ thisEndPos = pduDataStream.available();
+ if (thisStartPos - thisEndPos < len) {
+ int last = len - (thisStartPos - thisEndPos);
+ byte[] temp = new byte[last];
+ pduDataStream.read(temp, 0, last);
+ }
+ }
+
+ tempPos = pduDataStream.available();
+ lastLen = length - (startPos - tempPos);
+ }
break;
default:
if (LOCAL_LOGV) {
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 75cb06a..52fc930 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -126,6 +126,7 @@
android_hardware_Camera.cpp \
android_hardware_SensorManager.cpp \
android_hardware_UsbDevice.cpp \
+ android_hardware_UsbDeviceConnection.cpp \
android_hardware_UsbRequest.cpp \
android_debug_JNITest.cpp \
android_util_FileObserver.cpp \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 878af3d..0e071a4 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -78,6 +78,7 @@
extern int register_android_hardware_Camera(JNIEnv *env);
extern int register_android_hardware_SensorManager(JNIEnv *env);
extern int register_android_hardware_UsbDevice(JNIEnv *env);
+extern int register_android_hardware_UsbDeviceConnection(JNIEnv *env);
extern int register_android_hardware_UsbRequest(JNIEnv *env);
extern int register_android_media_AudioRecord(JNIEnv *env);
@@ -1274,6 +1275,7 @@
REG_JNI(register_android_hardware_Camera),
REG_JNI(register_android_hardware_SensorManager),
REG_JNI(register_android_hardware_UsbDevice),
+ REG_JNI(register_android_hardware_UsbDeviceConnection),
REG_JNI(register_android_hardware_UsbRequest),
REG_JNI(register_android_media_AudioRecord),
REG_JNI(register_android_media_AudioSystem),
diff --git a/core/jni/android/graphics/BitmapRegionDecoder.cpp b/core/jni/android/graphics/BitmapRegionDecoder.cpp
index f89967b..ee3e209 100644
--- a/core/jni/android/graphics/BitmapRegionDecoder.cpp
+++ b/core/jni/android/graphics/BitmapRegionDecoder.cpp
@@ -91,7 +91,7 @@
return nullObjectReturn("decoder->buildTileIndex returned false");
}
- SkBitmapRegionDecoder *bm = new SkBitmapRegionDecoder(decoder, width, height);
+ SkBitmapRegionDecoder *bm = new SkBitmapRegionDecoder(decoder, stream, width, height);
return GraphicsJNI::createBitmapRegionDecoder(env, bm);
}
diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp
index 88de94f..c4e5878 100644
--- a/core/jni/android/graphics/SurfaceTexture.cpp
+++ b/core/jni/android/graphics/SurfaceTexture.cpp
@@ -19,6 +19,7 @@
#include <stdio.h>
#include <gui/SurfaceTexture.h>
+#include <gui/SurfaceTextureClient.h>
#include <android_runtime/AndroidRuntime.h>
@@ -64,6 +65,15 @@
return surfaceTexture;
}
+sp<ANativeWindow> android_SurfaceTexture_getNativeWindow(
+ JNIEnv* env, jobject thiz)
+{
+ sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
+ sp<SurfaceTextureClient> surfaceTextureClient(surfaceTexture != NULL ?
+ new SurfaceTextureClient(surfaceTexture) : NULL);
+ return surfaceTextureClient;
+}
+
// ----------------------------------------------------------------------------
class JNISurfaceTextureContext : public SurfaceTexture::FrameAvailableListener
diff --git a/core/jni/android_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp
index 56f2646..b1ea90b 100644
--- a/core/jni/android_app_NativeActivity.cpp
+++ b/core/jni/android_app_NativeActivity.cpp
@@ -42,8 +42,6 @@
{
static struct {
- jclass clazz;
-
jmethodID dispatchUnhandledKeyEvent;
jmethodID preDispatchKeyEvent;
jmethodID finish;
@@ -1054,8 +1052,7 @@
#define FIND_CLASS(var, className) \
var = env->FindClass(className); \
- LOG_FATAL_IF(! var, "Unable to find class %s", className); \
- var = jclass(env->NewGlobalRef(var));
+ LOG_FATAL_IF(! var, "Unable to find class %s", className);
#define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
var = env->GetMethodID(clazz, methodName, fieldDescriptor); \
@@ -1064,30 +1061,30 @@
int register_android_app_NativeActivity(JNIEnv* env)
{
//LOGD("register_android_app_NativeActivity");
+ jclass clazz;
+ FIND_CLASS(clazz, kNativeActivityPathName);
- FIND_CLASS(gNativeActivityClassInfo.clazz, kNativeActivityPathName);
-
GET_METHOD_ID(gNativeActivityClassInfo.dispatchUnhandledKeyEvent,
- gNativeActivityClassInfo.clazz,
+ clazz,
"dispatchUnhandledKeyEvent", "(Landroid/view/KeyEvent;)Z");
GET_METHOD_ID(gNativeActivityClassInfo.preDispatchKeyEvent,
- gNativeActivityClassInfo.clazz,
+ clazz,
"preDispatchKeyEvent", "(Landroid/view/KeyEvent;I)V");
GET_METHOD_ID(gNativeActivityClassInfo.finish,
- gNativeActivityClassInfo.clazz,
+ clazz,
"finish", "()V");
GET_METHOD_ID(gNativeActivityClassInfo.setWindowFlags,
- gNativeActivityClassInfo.clazz,
+ clazz,
"setWindowFlags", "(II)V");
GET_METHOD_ID(gNativeActivityClassInfo.setWindowFormat,
- gNativeActivityClassInfo.clazz,
+ clazz,
"setWindowFormat", "(I)V");
GET_METHOD_ID(gNativeActivityClassInfo.showIme,
- gNativeActivityClassInfo.clazz,
+ clazz,
"showIme", "(I)V");
GET_METHOD_ID(gNativeActivityClassInfo.hideIme,
- gNativeActivityClassInfo.clazz,
+ clazz,
"hideIme", "(I)V");
return AndroidRuntime::registerNativeMethods(
diff --git a/core/jni/android_content_res_Configuration.cpp b/core/jni/android_content_res_Configuration.cpp
index 28a43ab..95b18ea 100644
--- a/core/jni/android_content_res_Configuration.cpp
+++ b/core/jni/android_content_res_Configuration.cpp
@@ -26,8 +26,6 @@
namespace android {
static struct {
- jclass clazz;
-
jfieldID mcc;
jfieldID mnc;
jfieldID locale;
@@ -75,8 +73,7 @@
#define FIND_CLASS(var, className) \
var = env->FindClass(className); \
- LOG_FATAL_IF(! var, "Unable to find class " className); \
- var = jclass(env->NewGlobalRef(var));
+ LOG_FATAL_IF(! var, "Unable to find class " className);
#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
@@ -84,31 +81,32 @@
int register_android_content_res_Configuration(JNIEnv* env)
{
- FIND_CLASS(gConfigurationClassInfo.clazz, "android/content/res/Configuration");
+ jclass clazz;
+ FIND_CLASS(clazz, "android/content/res/Configuration");
- GET_FIELD_ID(gConfigurationClassInfo.mcc, gConfigurationClassInfo.clazz,
+ GET_FIELD_ID(gConfigurationClassInfo.mcc, clazz,
"mcc", "I");
- GET_FIELD_ID(gConfigurationClassInfo.mnc, gConfigurationClassInfo.clazz,
+ GET_FIELD_ID(gConfigurationClassInfo.mnc, clazz,
"mnc", "I");
- GET_FIELD_ID(gConfigurationClassInfo.locale, gConfigurationClassInfo.clazz,
+ GET_FIELD_ID(gConfigurationClassInfo.locale, clazz,
"locale", "Ljava/util/Locale;");
- GET_FIELD_ID(gConfigurationClassInfo.screenLayout, gConfigurationClassInfo.clazz,
+ GET_FIELD_ID(gConfigurationClassInfo.screenLayout, clazz,
"screenLayout", "I");
- GET_FIELD_ID(gConfigurationClassInfo.touchscreen, gConfigurationClassInfo.clazz,
+ GET_FIELD_ID(gConfigurationClassInfo.touchscreen, clazz,
"touchscreen", "I");
- GET_FIELD_ID(gConfigurationClassInfo.keyboard, gConfigurationClassInfo.clazz,
+ GET_FIELD_ID(gConfigurationClassInfo.keyboard, clazz,
"keyboard", "I");
- GET_FIELD_ID(gConfigurationClassInfo.keyboardHidden, gConfigurationClassInfo.clazz,
+ GET_FIELD_ID(gConfigurationClassInfo.keyboardHidden, clazz,
"keyboardHidden", "I");
- GET_FIELD_ID(gConfigurationClassInfo.hardKeyboardHidden, gConfigurationClassInfo.clazz,
+ GET_FIELD_ID(gConfigurationClassInfo.hardKeyboardHidden, clazz,
"hardKeyboardHidden", "I");
- GET_FIELD_ID(gConfigurationClassInfo.navigation, gConfigurationClassInfo.clazz,
+ GET_FIELD_ID(gConfigurationClassInfo.navigation, clazz,
"navigation", "I");
- GET_FIELD_ID(gConfigurationClassInfo.navigationHidden, gConfigurationClassInfo.clazz,
+ GET_FIELD_ID(gConfigurationClassInfo.navigationHidden, clazz,
"navigationHidden", "I");
- GET_FIELD_ID(gConfigurationClassInfo.orientation, gConfigurationClassInfo.clazz,
+ GET_FIELD_ID(gConfigurationClassInfo.orientation, clazz,
"orientation", "I");
- GET_FIELD_ID(gConfigurationClassInfo.uiMode, gConfigurationClassInfo.clazz,
+ GET_FIELD_ID(gConfigurationClassInfo.uiMode, clazz,
"uiMode", "I");
return AndroidRuntime::registerNativeMethods(env, "android/content/res/Configuration", gMethods,
diff --git a/core/jni/android_content_res_ObbScanner.cpp b/core/jni/android_content_res_ObbScanner.cpp
index 3fd7985..4759e27 100644
--- a/core/jni/android_content_res_ObbScanner.cpp
+++ b/core/jni/android_content_res_ObbScanner.cpp
@@ -91,8 +91,7 @@
#define FIND_CLASS(var, className) \
var = env->FindClass(className); \
- LOG_FATAL_IF(! var, "Unable to find class " className); \
- var = jclass(env->NewGlobalRef(var));
+ LOG_FATAL_IF(! var, "Unable to find class " className);
#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
@@ -100,15 +99,16 @@
int register_android_content_res_ObbScanner(JNIEnv* env)
{
- FIND_CLASS(gObbInfoClassInfo.clazz, "android/content/res/ObbInfo");
+ jclass clazz;
+ FIND_CLASS(clazz, "android/content/res/ObbInfo");
- GET_FIELD_ID(gObbInfoClassInfo.packageName, gObbInfoClassInfo.clazz,
+ GET_FIELD_ID(gObbInfoClassInfo.packageName, clazz,
"packageName", "Ljava/lang/String;");
- GET_FIELD_ID(gObbInfoClassInfo.version, gObbInfoClassInfo.clazz,
+ GET_FIELD_ID(gObbInfoClassInfo.version, clazz,
"version", "I");
- GET_FIELD_ID(gObbInfoClassInfo.flags, gObbInfoClassInfo.clazz,
+ GET_FIELD_ID(gObbInfoClassInfo.flags, clazz,
"flags", "I");
- GET_FIELD_ID(gObbInfoClassInfo.salt, gObbInfoClassInfo.clazz,
+ GET_FIELD_ID(gObbInfoClassInfo.salt, clazz,
"salt", "[B");
return AndroidRuntime::registerNativeMethods(env, "android/content/res/ObbScanner", gMethods,
@@ -116,4 +116,3 @@
}
}; // namespace android
-
diff --git a/core/jni/android_hardware_UsbDevice.cpp b/core/jni/android_hardware_UsbDevice.cpp
index b01820c..c2950ea 100644
--- a/core/jni/android_hardware_UsbDevice.cpp
+++ b/core/jni/android_hardware_UsbDevice.cpp
@@ -24,190 +24,8 @@
#include <usbhost/usbhost.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
using namespace android;
-static jfieldID field_context;
-
-struct usb_device* get_device_from_object(JNIEnv* env, jobject javaDevice)
-{
- return (struct usb_device*)env->GetIntField(javaDevice, field_context);
-}
-
-// in android_hardware_UsbEndpoint.cpp
-extern struct usb_endpoint* get_endpoint_from_object(JNIEnv* env, jobject javaEndpoint);
-
-static jboolean
-android_hardware_UsbDevice_open(JNIEnv *env, jobject thiz, jstring deviceName,
- jobject fileDescriptor)
-{
- int fd = getParcelFileDescriptorFD(env, fileDescriptor);
- // duplicate the file descriptor, since ParcelFileDescriptor will eventually close its copy
- fd = dup(fd);
- if (fd < 0)
- return false;
-
- const char *deviceNameStr = env->GetStringUTFChars(deviceName, NULL);
- struct usb_device* device = usb_device_new(deviceNameStr, fd);
- if (device) {
- env->SetIntField(thiz, field_context, (int)device);
- } else {
- LOGE("usb_device_open failed for %s", deviceNameStr);
- close(fd);
- }
-
- env->ReleaseStringUTFChars(deviceName, deviceNameStr);
- return (device != NULL);
-}
-
-static void
-android_hardware_UsbDevice_close(JNIEnv *env, jobject thiz)
-{
- LOGD("close\n");
- struct usb_device* device = get_device_from_object(env, thiz);
- if (device) {
- usb_device_close(device);
- env->SetIntField(thiz, field_context, 0);
- }
-}
-
-static jint
-android_hardware_UsbDevice_get_fd(JNIEnv *env, jobject thiz)
-{
- struct usb_device* device = get_device_from_object(env, thiz);
- if (!device) {
- LOGE("device is closed in native_get_fd");
- return -1;
- }
- return usb_device_get_fd(device);
-}
-
-static jboolean
-android_hardware_UsbDevice_claim_interface(JNIEnv *env, jobject thiz, int interfaceID, jboolean force)
-{
- struct usb_device* device = get_device_from_object(env, thiz);
- if (!device) {
- LOGE("device is closed in native_claim_interface");
- return -1;
- }
-
- int ret = usb_device_claim_interface(device, interfaceID);
- if (ret && force && errno == EBUSY) {
- // disconnect kernel driver and try again
- usb_device_connect_kernel_driver(device, interfaceID, false);
- ret = usb_device_claim_interface(device, interfaceID);
- }
- return ret == 0;
-}
-
-static jint
-android_hardware_UsbDevice_release_interface(JNIEnv *env, jobject thiz, int interfaceID)
-{
- struct usb_device* device = get_device_from_object(env, thiz);
- if (!device) {
- LOGE("device is closed in native_release_interface");
- return -1;
- }
- int ret = usb_device_release_interface(device, interfaceID);
- if (ret == 0) {
- // allow kernel to reconnect its driver
- usb_device_connect_kernel_driver(device, interfaceID, true);
- }
- return ret;
-}
-
-static jint
-android_hardware_UsbDevice_control_request(JNIEnv *env, jobject thiz,
- jint requestType, jint request, jint value, jint index,
- jbyteArray buffer, jint length, jint timeout)
-{
- struct usb_device* device = get_device_from_object(env, thiz);
- if (!device) {
- LOGE("device is closed in native_control_request");
- return -1;
- }
-
- jbyte* bufferBytes = NULL;
- if (buffer) {
- if (env->GetArrayLength(buffer) < length) {
- env->ThrowNew(env->FindClass("java/lang/ArrayIndexOutOfBoundsException"), NULL);
- return -1;
- }
- bufferBytes = env->GetByteArrayElements(buffer, 0);
- }
-
- jint result = usb_device_control_transfer(device, requestType, request,
- value, index, bufferBytes, length, timeout);
-
- if (bufferBytes)
- env->ReleaseByteArrayElements(buffer, bufferBytes, 0);
-
- return result;
-}
-
-static jint
-android_hardware_UsbDevice_bulk_request(JNIEnv *env, jobject thiz,
- jint endpoint, jbyteArray buffer, jint length, jint timeout)
-{
- struct usb_device* device = get_device_from_object(env, thiz);
- if (!device) {
- LOGE("device is closed in native_control_request");
- return -1;
- }
-
- jbyte* bufferBytes = NULL;
- if (buffer) {
- if (env->GetArrayLength(buffer) < length) {
- env->ThrowNew(env->FindClass("java/lang/ArrayIndexOutOfBoundsException"), NULL);
- return -1;
- }
- bufferBytes = env->GetByteArrayElements(buffer, 0);
- }
-
- jint result = usb_device_bulk_transfer(device, endpoint, bufferBytes, length, timeout);
-
- if (bufferBytes)
- env->ReleaseByteArrayElements(buffer, bufferBytes, 0);
-
- return result;
-}
-
-static jobject
-android_hardware_UsbDevice_request_wait(JNIEnv *env, jobject thiz)
-{
- struct usb_device* device = get_device_from_object(env, thiz);
- if (!device) {
- LOGE("device is closed in native_request_wait");
- return NULL;
- }
-
- struct usb_request* request = usb_request_wait(device);
- if (request)
- return (jobject)request->client_data;
- else
- return NULL;
-}
-
-static jstring
-android_hardware_UsbDevice_get_serial(JNIEnv *env, jobject thiz)
-{
- struct usb_device* device = get_device_from_object(env, thiz);
- if (!device) {
- LOGE("device is closed in native_request_wait");
- return NULL;
- }
- char* serial = usb_device_get_serial(device);
- if (!serial)
- return NULL;
- jstring result = env->NewStringUTF(serial);
- free(serial);
- return result;
-}
-
static jint
android_hardware_UsbDevice_get_device_id(JNIEnv *env, jobject clazz, jstring name)
{
@@ -227,21 +45,6 @@
}
static JNINativeMethod method_table[] = {
- {"native_open", "(Ljava/lang/String;Ljava/io/FileDescriptor;)Z",
- (void *)android_hardware_UsbDevice_open},
- {"native_close", "()V", (void *)android_hardware_UsbDevice_close},
- {"native_get_fd", "()I", (void *)android_hardware_UsbDevice_get_fd},
- {"native_claim_interface", "(IZ)Z",(void *)android_hardware_UsbDevice_claim_interface},
- {"native_release_interface","(I)Z", (void *)android_hardware_UsbDevice_release_interface},
- {"native_control_request", "(IIII[BII)I",
- (void *)android_hardware_UsbDevice_control_request},
- {"native_bulk_request", "(I[BII)I",
- (void *)android_hardware_UsbDevice_bulk_request},
- {"native_request_wait", "()Landroid/hardware/usb/UsbRequest;",
- (void *)android_hardware_UsbDevice_request_wait},
- { "native_get_serial", "()Ljava/lang/String;",
- (void*)android_hardware_UsbDevice_get_serial },
-
// static methods
{ "native_get_device_id", "(Ljava/lang/String;)I",
(void*)android_hardware_UsbDevice_get_device_id },
@@ -256,11 +59,6 @@
LOGE("Can't find android/hardware/usb/UsbDevice");
return -1;
}
- field_context = env->GetFieldID(clazz, "mNativeContext", "I");
- if (field_context == NULL) {
- LOGE("Can't find UsbDevice.mNativeContext");
- return -1;
- }
return AndroidRuntime::registerNativeMethods(env, "android/hardware/usb/UsbDevice",
method_table, NELEM(method_table));
diff --git a/core/jni/android_hardware_UsbDeviceConnection.cpp b/core/jni/android_hardware_UsbDeviceConnection.cpp
new file mode 100644
index 0000000..ec36a38
--- /dev/null
+++ b/core/jni/android_hardware_UsbDeviceConnection.cpp
@@ -0,0 +1,242 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "UsbDeviceConnectionJNI"
+
+#include "utils/Log.h"
+
+#include "jni.h"
+#include "JNIHelp.h"
+#include "android_runtime/AndroidRuntime.h"
+
+#include <usbhost/usbhost.h>
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+using namespace android;
+
+static jfieldID field_context;
+
+struct usb_device* get_device_from_object(JNIEnv* env, jobject connection)
+{
+ return (struct usb_device*)env->GetIntField(connection, field_context);
+}
+
+static jboolean
+android_hardware_UsbDeviceConnection_open(JNIEnv *env, jobject thiz, jstring deviceName,
+ jobject fileDescriptor)
+{
+ int fd = getParcelFileDescriptorFD(env, fileDescriptor);
+ // duplicate the file descriptor, since ParcelFileDescriptor will eventually close its copy
+ fd = dup(fd);
+ if (fd < 0)
+ return false;
+
+ const char *deviceNameStr = env->GetStringUTFChars(deviceName, NULL);
+ struct usb_device* device = usb_device_new(deviceNameStr, fd);
+ if (device) {
+ env->SetIntField(thiz, field_context, (int)device);
+ } else {
+ LOGE("usb_device_open failed for %s", deviceNameStr);
+ close(fd);
+ }
+
+ env->ReleaseStringUTFChars(deviceName, deviceNameStr);
+ return (device != NULL);
+}
+
+static void
+android_hardware_UsbDeviceConnection_close(JNIEnv *env, jobject thiz)
+{
+ LOGD("close\n");
+ struct usb_device* device = get_device_from_object(env, thiz);
+ if (device) {
+ usb_device_close(device);
+ env->SetIntField(thiz, field_context, 0);
+ }
+}
+
+static jint
+android_hardware_UsbDeviceConnection_get_fd(JNIEnv *env, jobject thiz)
+{
+ struct usb_device* device = get_device_from_object(env, thiz);
+ if (!device) {
+ LOGE("device is closed in native_get_fd");
+ return -1;
+ }
+ return usb_device_get_fd(device);
+}
+
+static jboolean
+android_hardware_UsbDeviceConnection_claim_interface(JNIEnv *env, jobject thiz,
+ int interfaceID, jboolean force)
+{
+ struct usb_device* device = get_device_from_object(env, thiz);
+ if (!device) {
+ LOGE("device is closed in native_claim_interface");
+ return -1;
+ }
+
+ int ret = usb_device_claim_interface(device, interfaceID);
+ if (ret && force && errno == EBUSY) {
+ // disconnect kernel driver and try again
+ usb_device_connect_kernel_driver(device, interfaceID, false);
+ ret = usb_device_claim_interface(device, interfaceID);
+ }
+ return ret == 0;
+}
+
+static jint
+android_hardware_UsbDeviceConnection_release_interface(JNIEnv *env, jobject thiz, int interfaceID)
+{
+ struct usb_device* device = get_device_from_object(env, thiz);
+ if (!device) {
+ LOGE("device is closed in native_release_interface");
+ return -1;
+ }
+ int ret = usb_device_release_interface(device, interfaceID);
+ if (ret == 0) {
+ // allow kernel to reconnect its driver
+ usb_device_connect_kernel_driver(device, interfaceID, true);
+ }
+ return ret;
+}
+
+static jint
+android_hardware_UsbDeviceConnection_control_request(JNIEnv *env, jobject thiz,
+ jint requestType, jint request, jint value, jint index,
+ jbyteArray buffer, jint length, jint timeout)
+{
+ struct usb_device* device = get_device_from_object(env, thiz);
+ if (!device) {
+ LOGE("device is closed in native_control_request");
+ return -1;
+ }
+
+ jbyte* bufferBytes = NULL;
+ if (buffer) {
+ if (env->GetArrayLength(buffer) < length) {
+ env->ThrowNew(env->FindClass("java/lang/ArrayIndexOutOfBoundsException"), NULL);
+ return -1;
+ }
+ bufferBytes = env->GetByteArrayElements(buffer, 0);
+ }
+
+ jint result = usb_device_control_transfer(device, requestType, request,
+ value, index, bufferBytes, length, timeout);
+
+ if (bufferBytes)
+ env->ReleaseByteArrayElements(buffer, bufferBytes, 0);
+
+ return result;
+}
+
+static jint
+android_hardware_UsbDeviceConnection_bulk_request(JNIEnv *env, jobject thiz,
+ jint endpoint, jbyteArray buffer, jint length, jint timeout)
+{
+ struct usb_device* device = get_device_from_object(env, thiz);
+ if (!device) {
+ LOGE("device is closed in native_control_request");
+ return -1;
+ }
+
+ jbyte* bufferBytes = NULL;
+ if (buffer) {
+ if (env->GetArrayLength(buffer) < length) {
+ env->ThrowNew(env->FindClass("java/lang/ArrayIndexOutOfBoundsException"), NULL);
+ return -1;
+ }
+ bufferBytes = env->GetByteArrayElements(buffer, 0);
+ }
+
+ jint result = usb_device_bulk_transfer(device, endpoint, bufferBytes, length, timeout);
+
+ if (bufferBytes)
+ env->ReleaseByteArrayElements(buffer, bufferBytes, 0);
+
+ return result;
+}
+
+static jobject
+android_hardware_UsbDeviceConnection_request_wait(JNIEnv *env, jobject thiz)
+{
+ struct usb_device* device = get_device_from_object(env, thiz);
+ if (!device) {
+ LOGE("device is closed in native_request_wait");
+ return NULL;
+ }
+
+ struct usb_request* request = usb_request_wait(device);
+ if (request)
+ return (jobject)request->client_data;
+ else
+ return NULL;
+}
+
+static jstring
+android_hardware_UsbDeviceConnection_get_serial(JNIEnv *env, jobject thiz)
+{
+ struct usb_device* device = get_device_from_object(env, thiz);
+ if (!device) {
+ LOGE("device is closed in native_request_wait");
+ return NULL;
+ }
+ char* serial = usb_device_get_serial(device);
+ if (!serial)
+ return NULL;
+ jstring result = env->NewStringUTF(serial);
+ free(serial);
+ return result;
+}
+
+static JNINativeMethod method_table[] = {
+ {"native_open", "(Ljava/lang/String;Ljava/io/FileDescriptor;)Z",
+ (void *)android_hardware_UsbDeviceConnection_open},
+ {"native_close", "()V", (void *)android_hardware_UsbDeviceConnection_close},
+ {"native_get_fd", "()I", (void *)android_hardware_UsbDeviceConnection_get_fd},
+ {"native_claim_interface", "(IZ)Z",(void *)android_hardware_UsbDeviceConnection_claim_interface},
+ {"native_release_interface","(I)Z", (void *)android_hardware_UsbDeviceConnection_release_interface},
+ {"native_control_request", "(IIII[BII)I",
+ (void *)android_hardware_UsbDeviceConnection_control_request},
+ {"native_bulk_request", "(I[BII)I",
+ (void *)android_hardware_UsbDeviceConnection_bulk_request},
+ {"native_request_wait", "()Landroid/hardware/usb/UsbRequest;",
+ (void *)android_hardware_UsbDeviceConnection_request_wait},
+ { "native_get_serial", "()Ljava/lang/String;",
+ (void*)android_hardware_UsbDeviceConnection_get_serial },
+};
+
+int register_android_hardware_UsbDeviceConnection(JNIEnv *env)
+{
+ jclass clazz = env->FindClass("android/hardware/usb/UsbDeviceConnection");
+ if (clazz == NULL) {
+ LOGE("Can't find android/hardware/usb/UsbDeviceConnection");
+ return -1;
+ }
+ field_context = env->GetFieldID(clazz, "mNativeContext", "I");
+ if (field_context == NULL) {
+ LOGE("Can't find UsbDeviceConnection.mNativeContext");
+ return -1;
+ }
+
+ return AndroidRuntime::registerNativeMethods(env, "android/hardware/usb/UsbDeviceConnection",
+ method_table, NELEM(method_table));
+}
+
diff --git a/core/jni/android_hardware_UsbRequest.cpp b/core/jni/android_hardware_UsbRequest.cpp
index b497adb..6bd67d1 100644
--- a/core/jni/android_hardware_UsbRequest.cpp
+++ b/core/jni/android_hardware_UsbRequest.cpp
@@ -35,8 +35,8 @@
return (struct usb_request*)env->GetIntField(java_request, field_context);
}
-// in android_hardware_UsbDevice.cpp
-extern struct usb_device* get_device_from_object(JNIEnv* env, jobject java_device);
+// in android_hardware_UsbDeviceConnection.cpp
+extern struct usb_device* get_device_from_object(JNIEnv* env, jobject connection);
static jboolean
android_hardware_UsbRequest_init(JNIEnv *env, jobject thiz, jobject java_device,
@@ -107,7 +107,7 @@
}
return false;
} else {
- // save a reference to ourselves so UsbDevice.waitRequest() can find us
+ // save a reference to ourselves so UsbDeviceConnection.waitRequest() can find us
request->client_data = (void *)env->NewGlobalRef(thiz);
return true;
}
@@ -155,7 +155,7 @@
request->buffer = NULL;
return false;
} else {
- // save a reference to ourselves so UsbDevice.waitRequest() can find us
+ // save a reference to ourselves so UsbDeviceConnection.waitRequest() can find us
// we also need this to make sure our native buffer is not deallocated
// while IO is active
request->client_data = (void *)env->NewGlobalRef(thiz);
@@ -187,7 +187,7 @@
}
static JNINativeMethod method_table[] = {
- {"native_init", "(Landroid/hardware/usb/UsbDevice;IIII)Z",
+ {"native_init", "(Landroid/hardware/usb/UsbDeviceConnection;IIII)Z",
(void *)android_hardware_UsbRequest_init},
{"native_close", "()V", (void *)android_hardware_UsbRequest_close},
{"native_queue_array", "([BIZ)Z", (void *)android_hardware_UsbRequest_queue_array},
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index f78f83c..b6619ab 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -315,7 +315,11 @@
}
// get the pointer to where we'll record the audio
- recordBuff = (jbyte *)env->GetPrimitiveArrayCritical(javaAudioData, NULL);
+ // NOTE: We may use GetPrimitiveArrayCritical() when the JNI implementation changes in such
+ // a way that it becomes much more efficient. When doing so, we will have to prevent the
+ // AudioSystem callback to be called while in critical section (in case of media server
+ // process crash for instance)
+ recordBuff = (jbyte *)env->GetByteArrayElements(javaAudioData, NULL);
if (recordBuff == NULL) {
LOGE("Error retrieving destination for recorded audio data, can't record");
@@ -327,7 +331,7 @@
ssize_t readSize = lpRecorder->read(recordBuff + offsetInBytes,
sizeInBytes > (jint)recorderBuffSize ?
(jint)recorderBuffSize : sizeInBytes );
- env->ReleasePrimitiveArrayCritical(javaAudioData, recordBuff, 0);
+ env->ReleaseByteArrayElements(javaAudioData, recordBuff, 0);
return (jint) readSize;
}
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 8409adc..44d2a52 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -530,8 +530,12 @@
}
// get the pointer for the audio data from the java array
+ // NOTE: We may use GetPrimitiveArrayCritical() when the JNI implementation changes in such
+ // a way that it becomes much more efficient. When doing so, we will have to prevent the
+ // AudioSystem callback to be called while in critical section (in case of media server
+ // process crash for instance)
if (javaAudioData) {
- cAudioData = (jbyte *)env->GetPrimitiveArrayCritical(javaAudioData, NULL);
+ cAudioData = (jbyte *)env->GetByteArrayElements(javaAudioData, NULL);
if (cAudioData == NULL) {
LOGE("Error retrieving source of audio data to play, can't play");
return 0; // out of memory or no data to load
@@ -543,7 +547,7 @@
jint written = writeToTrack(lpTrack, javaAudioFormat, cAudioData, offsetInBytes, sizeInBytes);
- env->ReleasePrimitiveArrayCritical(javaAudioData, cAudioData, 0);
+ env->ReleaseByteArrayElements(javaAudioData, cAudioData, 0);
//LOGV("write wrote %d (tried %d) bytes in the native AudioTrack with offset %d",
// (int)written, (int)(sizeInBytes), (int)offsetInBytes);
diff --git a/core/jni/android_os_MessageQueue.cpp b/core/jni/android_os_MessageQueue.cpp
index d2e5462..12a77d5 100644
--- a/core/jni/android_os_MessageQueue.cpp
+++ b/core/jni/android_os_MessageQueue.cpp
@@ -27,8 +27,6 @@
// ----------------------------------------------------------------------------
static struct {
- jclass clazz;
-
jfieldID mPtr; // native object attached to the DVM MessageQueue
} gMessageQueueClassInfo;
@@ -135,8 +133,7 @@
#define FIND_CLASS(var, className) \
var = env->FindClass(className); \
- LOG_FATAL_IF(! var, "Unable to find class " className); \
- var = jclass(env->NewGlobalRef(var));
+ LOG_FATAL_IF(! var, "Unable to find class " className);
#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
@@ -147,9 +144,10 @@
gMessageQueueMethods, NELEM(gMessageQueueMethods));
LOG_FATAL_IF(res < 0, "Unable to register native methods.");
- FIND_CLASS(gMessageQueueClassInfo.clazz, "android/os/MessageQueue");
+ jclass clazz;
+ FIND_CLASS(clazz, "android/os/MessageQueue");
- GET_FIELD_ID(gMessageQueueClassInfo.mPtr, gMessageQueueClassInfo.clazz,
+ GET_FIELD_ID(gMessageQueueClassInfo.mPtr, clazz,
"mPtr", "I");
return 0;
diff --git a/core/jni/android_os_Power.cpp b/core/jni/android_os_Power.cpp
index a46c2dd..5cfb9b1 100644
--- a/core/jni/android_os_Power.cpp
+++ b/core/jni/android_os_Power.cpp
@@ -20,7 +20,7 @@
#include "android_runtime/AndroidRuntime.h"
#include <utils/misc.h>
#include <hardware_legacy/power.h>
-#include <sys/reboot.h>
+#include <cutils/android_reboot.h>
namespace android
{
@@ -77,25 +77,26 @@
static void android_os_Power_shutdown(JNIEnv *env, jobject clazz)
{
- sync();
#ifdef HAVE_ANDROID_OS
- reboot(RB_POWER_OFF);
+ android_reboot(ANDROID_RB_POWEROFF, 0, 0);
+#else
+ sync();
#endif
}
static void android_os_Power_reboot(JNIEnv *env, jobject clazz, jstring reason)
{
- sync();
#ifdef HAVE_ANDROID_OS
if (reason == NULL) {
- reboot(RB_AUTOBOOT);
+ android_reboot(ANDROID_RB_RESTART, 0, 0);
} else {
const char *chars = env->GetStringUTFChars(reason, NULL);
- __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
- LINUX_REBOOT_CMD_RESTART2, (char*) chars);
+ android_reboot(ANDROID_RB_RESTART2, 0, (char *) chars);
env->ReleaseStringUTFChars(reason, chars); // In case it fails.
}
jniThrowIOException(env, errno);
+#else
+ sync();
#endif
}
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 5deed1e..9e00a7d 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -44,6 +44,13 @@
//#undef LOGV
//#define LOGV(...) fprintf(stderr, __VA_ARGS__)
+#define DEBUG_DEATH 0
+#if DEBUG_DEATH
+#define LOGDEATH LOGD
+#else
+#define LOGDEATH LOGV
+#endif
+
using namespace android;
// ----------------------------------------------------------------------------
@@ -363,6 +370,7 @@
Mutex mLock;
public:
+ DeathRecipientList();
~DeathRecipientList();
void add(const sp<JavaDeathRecipient>& recipient);
@@ -380,6 +388,7 @@
{
// These objects manage their own lifetimes so are responsible for final bookkeeping.
// The list holds a strong reference to this object.
+ LOGDEATH("Adding JDR %p to DRL %p", this, list.get());
list->add(this);
android_atomic_inc(&gNumDeathRefs);
@@ -390,7 +399,7 @@
{
JNIEnv* env = javavm_to_jnienv(mVM);
- LOGV("Receiving binderDied() on JavaDeathRecipient %p\n", this);
+ LOGDEATH("Receiving binderDied() on JavaDeathRecipient %p\n", this);
env->CallStaticVoidMethod(gBinderProxyOffsets.mClass,
gBinderProxyOffsets.mSendDeathNotice, mObject);
@@ -399,15 +408,16 @@
report_exception(env, excep,
"*** Uncaught exception returned from death notification!");
}
-
- clearReference();
}
void clearReference()
{
sp<DeathRecipientList> list = mList.promote();
if (list != NULL) {
+ LOGDEATH("Removing JDR %p from DRL %p", this, list.get());
list->remove(this);
+ } else {
+ LOGDEATH("clearReference() on JDR %p but DRL wp purged", this);
}
}
@@ -433,7 +443,12 @@
// ----------------------------------------------------------------------------
+DeathRecipientList::DeathRecipientList() {
+ LOGDEATH("New DRL @ %p", this);
+}
+
DeathRecipientList::~DeathRecipientList() {
+ LOGDEATH("Destroy DRL @ %p", this);
AutoMutex _l(mLock);
// Should never happen -- the JavaDeathRecipient objects that have added themselves
@@ -447,6 +462,7 @@
void DeathRecipientList::add(const sp<JavaDeathRecipient>& recipient) {
AutoMutex _l(mLock);
+ LOGDEATH("DRL @ %p : add JDR %p", this, recipient.get());
mList.push_back(recipient);
}
@@ -456,6 +472,7 @@
List< sp<JavaDeathRecipient> >::iterator iter;
for (iter = mList.begin(); iter != mList.end(); iter++) {
if (*iter == recipient) {
+ LOGDEATH("DRL @ %p : remove JDR %p", this, recipient.get());
mList.erase(iter);
return;
}
@@ -518,7 +535,7 @@
object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
if (object != NULL) {
- LOGV("objectForBinder %p: created new proxy %p !\n", val.get(), object);
+ LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
// The proxy holds a reference to the native object.
env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get());
val->incStrong(object);
@@ -1030,7 +1047,7 @@
assert(false);
}
- LOGV("linkToDeath: binder=%p recipient=%p\n", target, recipient);
+ LOGDEATH("linkToDeath: binder=%p recipient=%p\n", target, recipient);
if (!target->localBinder()) {
DeathRecipientList* list = (DeathRecipientList*)
@@ -1062,7 +1079,7 @@
return JNI_FALSE;
}
- LOGV("unlinkToDeath: binder=%p recipient=%p\n", target, recipient);
+ LOGDEATH("unlinkToDeath: binder=%p recipient=%p\n", target, recipient);
if (!target->localBinder()) {
status_t err = NAME_NOT_FOUND;
@@ -1071,6 +1088,7 @@
DeathRecipientList* list = (DeathRecipientList*)
env->GetIntField(obj, gBinderProxyOffsets.mOrgue);
sp<JavaDeathRecipient> origJDR = list->find(recipient);
+ LOGDEATH(" unlink found list %p and JDR %p", list, origJDR.get());
if (origJDR != NULL) {
wp<IBinder::DeathRecipient> dr;
err = target->unlinkToDeath(origJDR, NULL, flags, &dr);
@@ -1101,7 +1119,7 @@
DeathRecipientList* drl = (DeathRecipientList*)
env->GetIntField(obj, gBinderProxyOffsets.mOrgue);
- LOGV("Destroying BinderProxy %p: binder=%p drl=%p\n", obj, b, drl);
+ LOGDEATH("Destroying BinderProxy %p: binder=%p drl=%p\n", obj, b, drl);
env->SetIntField(obj, gBinderProxyOffsets.mObject, 0);
env->SetIntField(obj, gBinderProxyOffsets.mOrgue, 0);
drl->decStrong((void*)javaObjectForIBinder);
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 7a609a5..26c915f 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -35,7 +35,6 @@
#include <DisplayListRenderer.h>
#include <LayerRenderer.h>
-#include <OpenGLDebugRenderer.h>
#include <OpenGLRenderer.h>
#include <SkiaShader.h>
#include <SkiaColorFilter.h>
@@ -60,7 +59,6 @@
// Debug
#define DEBUG_RENDERER 0
-#define PROFILE_RENDERER 0
// Debug
#if DEBUG_RENDERER
@@ -72,7 +70,6 @@
// ----------------------------------------------------------------------------
static struct {
- jclass clazz;
jmethodID set;
} gRectClassInfo;
@@ -99,11 +96,7 @@
static OpenGLRenderer* android_view_GLES20Canvas_createRenderer(JNIEnv* env, jobject clazz) {
RENDERER_LOGD("Create OpenGLRenderer");
-#if PROFILE_RENDERER
- return new OpenGLDebugRenderer;
-#else
return new OpenGLRenderer;
-#endif
}
static void android_view_GLES20Canvas_destroyRenderer(JNIEnv* env, jobject clazz,
@@ -139,7 +132,8 @@
static bool android_view_GLES20Canvas_callDrawGLFunction(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, Functor *functor) {
- return renderer->callDrawGLFunction(functor);
+ android::uirenderer::Rect dirty;
+ return renderer->callDrawGLFunction(functor, dirty);
}
// ----------------------------------------------------------------------------
@@ -503,8 +497,14 @@
}
static bool android_view_GLES20Canvas_drawDisplayList(JNIEnv* env,
- jobject clazz, OpenGLRenderer* renderer, DisplayList* displayList) {
- return renderer->drawDisplayList(displayList);
+ jobject clazz, OpenGLRenderer* renderer, DisplayList* displayList, jobject dirty) {
+ android::uirenderer::Rect bounds;
+ bool redraw = renderer->drawDisplayList(displayList, bounds);
+ if (redraw && dirty != NULL) {
+ env->CallVoidMethod(dirty, gRectClassInfo.set,
+ int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom));
+ }
+ return redraw;
}
// ----------------------------------------------------------------------------
@@ -663,7 +663,8 @@
{ "nGetDisplayList", "(I)I", (void*) android_view_GLES20Canvas_getDisplayList },
{ "nDestroyDisplayList", "(I)V", (void*) android_view_GLES20Canvas_destroyDisplayList },
{ "nGetDisplayListRenderer", "(I)I", (void*) android_view_GLES20Canvas_getDisplayListRenderer },
- { "nDrawDisplayList", "(II)Z", (void*) android_view_GLES20Canvas_drawDisplayList },
+ { "nDrawDisplayList", "(IILandroid/graphics/Rect;)Z",
+ (void*) android_view_GLES20Canvas_drawDisplayList },
{ "nInterrupt", "(I)V", (void*) android_view_GLES20Canvas_interrupt },
{ "nResume", "(I)V", (void*) android_view_GLES20Canvas_resume },
@@ -681,9 +682,8 @@
#ifdef USE_OPENGL_RENDERER
#define FIND_CLASS(var, className) \
var = env->FindClass(className); \
- LOG_FATAL_IF(! var, "Unable to find class " className); \
- var = jclass(env->NewGlobalRef(var));
-
+ LOG_FATAL_IF(! var, "Unable to find class " className);
+
#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
var = env->GetMethodID(clazz, methodName, methodDescriptor); \
LOG_FATAL_IF(! var, "Unable to find method " methodName);
@@ -693,8 +693,9 @@
#endif
int register_android_view_GLES20Canvas(JNIEnv* env) {
- FIND_CLASS(gRectClassInfo.clazz, "android/graphics/Rect");
- GET_METHOD_ID(gRectClassInfo.set, gRectClassInfo.clazz, "set", "(IIII)V");
+ jclass clazz;
+ FIND_CLASS(clazz, "android/graphics/Rect");
+ GET_METHOD_ID(gRectClassInfo.set, clazz, "set", "(IIII)V");
return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
}
diff --git a/core/jni/android_view_KeyCharacterMap.cpp b/core/jni/android_view_KeyCharacterMap.cpp
index bfeec4f..aba3a72 100644
--- a/core/jni/android_view_KeyCharacterMap.cpp
+++ b/core/jni/android_view_KeyCharacterMap.cpp
@@ -30,8 +30,6 @@
} gKeyEventClassInfo;
static struct {
- jclass clazz;
-
jfieldID keyCode;
jfieldID metaState;
} gFallbackActionClassInfo;
@@ -165,8 +163,7 @@
#define FIND_CLASS(var, className) \
var = env->FindClass(className); \
- LOG_FATAL_IF(! var, "Unable to find class " className); \
- var = jclass(env->NewGlobalRef(var));
+ LOG_FATAL_IF(! var, "Unable to find class " className);
#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
@@ -175,13 +172,15 @@
int register_android_text_KeyCharacterMap(JNIEnv* env)
{
FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
+ gKeyEventClassInfo.clazz = jclass(env->NewGlobalRef(gKeyEventClassInfo.clazz));
- FIND_CLASS(gFallbackActionClassInfo.clazz, "android/view/KeyCharacterMap$FallbackAction");
+ jclass clazz;
+ FIND_CLASS(clazz, "android/view/KeyCharacterMap$FallbackAction");
- GET_FIELD_ID(gFallbackActionClassInfo.keyCode, gFallbackActionClassInfo.clazz,
+ GET_FIELD_ID(gFallbackActionClassInfo.keyCode, clazz,
"keyCode", "I");
- GET_FIELD_ID(gFallbackActionClassInfo.metaState, gFallbackActionClassInfo.clazz,
+ GET_FIELD_ID(gFallbackActionClassInfo.metaState, clazz,
"metaState", "I");
return AndroidRuntime::registerNativeMethods(env,
diff --git a/core/jni/android_view_MotionEvent.cpp b/core/jni/android_view_MotionEvent.cpp
index 97cba23..68ebfe7 100644
--- a/core/jni/android_view_MotionEvent.cpp
+++ b/core/jni/android_view_MotionEvent.cpp
@@ -42,8 +42,6 @@
} gMotionEventClassInfo;
static struct {
- jclass clazz;
-
jfieldID mPackedAxisBits;
jfieldID mPackedAxisValues;
jfieldID x;
@@ -734,8 +732,7 @@
#define FIND_CLASS(var, className) \
var = env->FindClass(className); \
- LOG_FATAL_IF(! var, "Unable to find class " className); \
- var = jclass(env->NewGlobalRef(var));
+ LOG_FATAL_IF(! var, "Unable to find class " className);
#define GET_STATIC_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
var = env->GetStaticMethodID(clazz, methodName, fieldDescriptor); \
@@ -755,6 +752,7 @@
LOG_FATAL_IF(res < 0, "Unable to register native methods.");
FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
+ gMotionEventClassInfo.clazz = jclass(env->NewGlobalRef(gMotionEventClassInfo.clazz));
GET_STATIC_METHOD_ID(gMotionEventClassInfo.obtain, gMotionEventClassInfo.clazz,
"obtain", "()Landroid/view/MotionEvent;");
@@ -763,29 +761,30 @@
GET_FIELD_ID(gMotionEventClassInfo.mNativePtr, gMotionEventClassInfo.clazz,
"mNativePtr", "I");
- FIND_CLASS(gPointerCoordsClassInfo.clazz, "android/view/MotionEvent$PointerCoords");
+ jclass clazz;
+ FIND_CLASS(clazz, "android/view/MotionEvent$PointerCoords");
- GET_FIELD_ID(gPointerCoordsClassInfo.mPackedAxisBits, gPointerCoordsClassInfo.clazz,
+ GET_FIELD_ID(gPointerCoordsClassInfo.mPackedAxisBits, clazz,
"mPackedAxisBits", "J");
- GET_FIELD_ID(gPointerCoordsClassInfo.mPackedAxisValues, gPointerCoordsClassInfo.clazz,
+ GET_FIELD_ID(gPointerCoordsClassInfo.mPackedAxisValues, clazz,
"mPackedAxisValues", "[F");
- GET_FIELD_ID(gPointerCoordsClassInfo.x, gPointerCoordsClassInfo.clazz,
+ GET_FIELD_ID(gPointerCoordsClassInfo.x, clazz,
"x", "F");
- GET_FIELD_ID(gPointerCoordsClassInfo.y, gPointerCoordsClassInfo.clazz,
+ GET_FIELD_ID(gPointerCoordsClassInfo.y, clazz,
"y", "F");
- GET_FIELD_ID(gPointerCoordsClassInfo.pressure, gPointerCoordsClassInfo.clazz,
+ GET_FIELD_ID(gPointerCoordsClassInfo.pressure, clazz,
"pressure", "F");
- GET_FIELD_ID(gPointerCoordsClassInfo.size, gPointerCoordsClassInfo.clazz,
+ GET_FIELD_ID(gPointerCoordsClassInfo.size, clazz,
"size", "F");
- GET_FIELD_ID(gPointerCoordsClassInfo.touchMajor, gPointerCoordsClassInfo.clazz,
+ GET_FIELD_ID(gPointerCoordsClassInfo.touchMajor, clazz,
"touchMajor", "F");
- GET_FIELD_ID(gPointerCoordsClassInfo.touchMinor, gPointerCoordsClassInfo.clazz,
+ GET_FIELD_ID(gPointerCoordsClassInfo.touchMinor, clazz,
"touchMinor", "F");
- GET_FIELD_ID(gPointerCoordsClassInfo.toolMajor, gPointerCoordsClassInfo.clazz,
+ GET_FIELD_ID(gPointerCoordsClassInfo.toolMajor, clazz,
"toolMajor", "F");
- GET_FIELD_ID(gPointerCoordsClassInfo.toolMinor, gPointerCoordsClassInfo.clazz,
+ GET_FIELD_ID(gPointerCoordsClassInfo.toolMinor, clazz,
"toolMinor", "F");
- GET_FIELD_ID(gPointerCoordsClassInfo.orientation, gPointerCoordsClassInfo.clazz,
+ GET_FIELD_ID(gPointerCoordsClassInfo.orientation, clazz,
"orientation", "F");
return 0;
diff --git a/core/jni/com_google_android_gles_jni_EGLImpl.cpp b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
index e7ea8c8..3d24bee 100644
--- a/core/jni/com_google_android_gles_jni_EGLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
@@ -400,7 +400,7 @@
}
static jint jni_eglGetCurrentSurface(JNIEnv *_env, jobject _this, jint readdraw) {
- if (!(readdraw == EGL_READ) || (readdraw == EGL_DRAW)) {
+ if ((readdraw != EGL_READ) && (readdraw != EGL_DRAW)) {
doThrow(_env, "java/lang/IllegalArgumentException");
return 0;
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 0ad174f..c684e7e 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1379,12 +1379,6 @@
android:excludeFromRecents="true">
</activity>
- <activity android:name="com.android.server.usb.UsbResolverActivity"
- android:theme="@style/Theme.Holo.Dialog.Alert"
- android:finishOnCloseSystemDialogs="true"
- android:excludeFromRecents="true">
- </activity>
-
<service android:name="com.android.server.LoadAverageService"
android:exported="true" />
diff --git a/core/res/res/drawable-hdpi/ic_ab_back_holo_dark.png b/core/res/res/drawable-hdpi/ic_ab_back_holo_dark.png
index 52fccf8..7855cda 100644
--- a/core/res/res/drawable-hdpi/ic_ab_back_holo_dark.png
+++ b/core/res/res/drawable-hdpi/ic_ab_back_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_ab_back_holo_light.png b/core/res/res/drawable-hdpi/ic_ab_back_holo_light.png
index 0354599..c062773 100644
--- a/core/res/res/drawable-hdpi/ic_ab_back_holo_light.png
+++ b/core/res/res/drawable-hdpi/ic_ab_back_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_notify_call_mute.png b/core/res/res/drawable-hdpi/stat_notify_call_mute.png
index 048f56e..9887faa 100755
--- a/core/res/res/drawable-hdpi/stat_notify_call_mute.png
+++ b/core/res/res/drawable-hdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_notify_car_mode.png b/core/res/res/drawable-hdpi/stat_notify_car_mode.png
index 76dd2ae..94f288c 100644
--- a/core/res/res/drawable-hdpi/stat_notify_car_mode.png
+++ b/core/res/res/drawable-hdpi/stat_notify_car_mode.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_notify_chat.png b/core/res/res/drawable-hdpi/stat_notify_chat.png
index d7c1545..bddea50 100644
--- a/core/res/res/drawable-hdpi/stat_notify_chat.png
+++ b/core/res/res/drawable-hdpi/stat_notify_chat.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_notify_disk_full.png b/core/res/res/drawable-hdpi/stat_notify_disk_full.png
index 9956fad..b44ce58 100755
--- a/core/res/res/drawable-hdpi/stat_notify_disk_full.png
+++ b/core/res/res/drawable-hdpi/stat_notify_disk_full.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_notify_email_generic.png b/core/res/res/drawable-hdpi/stat_notify_email_generic.png
index 4ea619c..8d60237 100644
--- a/core/res/res/drawable-hdpi/stat_notify_email_generic.png
+++ b/core/res/res/drawable-hdpi/stat_notify_email_generic.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_notify_error.png b/core/res/res/drawable-hdpi/stat_notify_error.png
index 598094f..6942871 100755
--- a/core/res/res/drawable-hdpi/stat_notify_error.png
+++ b/core/res/res/drawable-hdpi/stat_notify_error.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_notify_gmail.png b/core/res/res/drawable-hdpi/stat_notify_gmail.png
index 7028ea7..bf8582a 100644
--- a/core/res/res/drawable-hdpi/stat_notify_gmail.png
+++ b/core/res/res/drawable-hdpi/stat_notify_gmail.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_notify_missed_call.png b/core/res/res/drawable-hdpi/stat_notify_missed_call.png
index b0f7a6e..6df57ff3 100644
--- a/core/res/res/drawable-hdpi/stat_notify_missed_call.png
+++ b/core/res/res/drawable-hdpi/stat_notify_missed_call.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_notify_sdcard.png b/core/res/res/drawable-hdpi/stat_notify_sdcard.png
index a916488..0857774 100755
--- a/core/res/res/drawable-hdpi/stat_notify_sdcard.png
+++ b/core/res/res/drawable-hdpi/stat_notify_sdcard.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_notify_sdcard_prepare.png b/core/res/res/drawable-hdpi/stat_notify_sdcard_prepare.png
index e267700..3880496 100755
--- a/core/res/res/drawable-hdpi/stat_notify_sdcard_prepare.png
+++ b/core/res/res/drawable-hdpi/stat_notify_sdcard_prepare.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_notify_sdcard_usb.png b/core/res/res/drawable-hdpi/stat_notify_sdcard_usb.png
index 233e438..ac984ef 100755
--- a/core/res/res/drawable-hdpi/stat_notify_sdcard_usb.png
+++ b/core/res/res/drawable-hdpi/stat_notify_sdcard_usb.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_notify_sim_toolkit.png b/core/res/res/drawable-hdpi/stat_notify_sim_toolkit.png
index 42101077..b7ba4ba 100755
--- a/core/res/res/drawable-hdpi/stat_notify_sim_toolkit.png
+++ b/core/res/res/drawable-hdpi/stat_notify_sim_toolkit.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_notify_sync.png b/core/res/res/drawable-hdpi/stat_notify_sync.png
index 2076c55..76319b0 100755
--- a/core/res/res/drawable-hdpi/stat_notify_sync.png
+++ b/core/res/res/drawable-hdpi/stat_notify_sync.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_notify_sync_anim0.png b/core/res/res/drawable-hdpi/stat_notify_sync_anim0.png
index 2076c55..863c3d7 100755
--- a/core/res/res/drawable-hdpi/stat_notify_sync_anim0.png
+++ b/core/res/res/drawable-hdpi/stat_notify_sync_anim0.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_notify_sync_error.png b/core/res/res/drawable-hdpi/stat_notify_sync_error.png
index bade508..0083c3f 100755
--- a/core/res/res/drawable-hdpi/stat_notify_sync_error.png
+++ b/core/res/res/drawable-hdpi/stat_notify_sync_error.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_notify_voicemail.png b/core/res/res/drawable-hdpi/stat_notify_voicemail.png
index 43fe530..499325b 100755
--- a/core/res/res/drawable-hdpi/stat_notify_voicemail.png
+++ b/core/res/res/drawable-hdpi/stat_notify_voicemail.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_notify_wifi_in_range.png b/core/res/res/drawable-hdpi/stat_notify_wifi_in_range.png
index 5c42e53..8d80709 100644
--- a/core/res/res/drawable-hdpi/stat_notify_wifi_in_range.png
+++ b/core/res/res/drawable-hdpi/stat_notify_wifi_in_range.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_adb.png b/core/res/res/drawable-hdpi/stat_sys_adb.png
index af713e8..877e731 100755
--- a/core/res/res/drawable-hdpi/stat_sys_adb.png
+++ b/core/res/res/drawable-hdpi/stat_sys_adb.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_bluetooth.png b/core/res/res/drawable-hdpi/stat_sys_data_bluetooth.png
index 42a774e..526fbfa 100644
--- a/core/res/res/drawable-hdpi/stat_sys_data_bluetooth.png
+++ b/core/res/res/drawable-hdpi/stat_sys_data_bluetooth.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_usb.png b/core/res/res/drawable-hdpi/stat_sys_data_usb.png
index 6987b09..606ef80 100755
--- a/core/res/res/drawable-hdpi/stat_sys_data_usb.png
+++ b/core/res/res/drawable-hdpi/stat_sys_data_usb.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_download_anim0.png b/core/res/res/drawable-hdpi/stat_sys_download_anim0.png
index 943e620..0510128 100644
--- a/core/res/res/drawable-hdpi/stat_sys_download_anim0.png
+++ b/core/res/res/drawable-hdpi/stat_sys_download_anim0.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_download_anim1.png b/core/res/res/drawable-hdpi/stat_sys_download_anim1.png
index 28edae1..631622b 100644
--- a/core/res/res/drawable-hdpi/stat_sys_download_anim1.png
+++ b/core/res/res/drawable-hdpi/stat_sys_download_anim1.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_download_anim2.png b/core/res/res/drawable-hdpi/stat_sys_download_anim2.png
index 556a46f..e300245 100644
--- a/core/res/res/drawable-hdpi/stat_sys_download_anim2.png
+++ b/core/res/res/drawable-hdpi/stat_sys_download_anim2.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_download_anim3.png b/core/res/res/drawable-hdpi/stat_sys_download_anim3.png
index 422d72b..fd220e3 100644
--- a/core/res/res/drawable-hdpi/stat_sys_download_anim3.png
+++ b/core/res/res/drawable-hdpi/stat_sys_download_anim3.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_download_anim4.png b/core/res/res/drawable-hdpi/stat_sys_download_anim4.png
index 24a0db5..a1ea9e3 100644
--- a/core/res/res/drawable-hdpi/stat_sys_download_anim4.png
+++ b/core/res/res/drawable-hdpi/stat_sys_download_anim4.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_download_anim5.png b/core/res/res/drawable-hdpi/stat_sys_download_anim5.png
index 97e5a6b..7804a29 100644
--- a/core/res/res/drawable-hdpi/stat_sys_download_anim5.png
+++ b/core/res/res/drawable-hdpi/stat_sys_download_anim5.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_gps_on.png b/core/res/res/drawable-hdpi/stat_sys_gps_on.png
index 0d6f622..542ebb0 100644
--- a/core/res/res/drawable-hdpi/stat_sys_gps_on.png
+++ b/core/res/res/drawable-hdpi/stat_sys_gps_on.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_secure.png b/core/res/res/drawable-hdpi/stat_sys_secure.png
index 8d24990..c4a17de 100755
--- a/core/res/res/drawable-hdpi/stat_sys_secure.png
+++ b/core/res/res/drawable-hdpi/stat_sys_secure.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_speakerphone.png b/core/res/res/drawable-hdpi/stat_sys_speakerphone.png
index 82c06a9..a9a2b2e 100755
--- a/core/res/res/drawable-hdpi/stat_sys_speakerphone.png
+++ b/core/res/res/drawable-hdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_throttled.png b/core/res/res/drawable-hdpi/stat_sys_throttled.png
index bd8323a..99ae4ac 100755
--- a/core/res/res/drawable-hdpi/stat_sys_throttled.png
+++ b/core/res/res/drawable-hdpi/stat_sys_throttled.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_upload_anim0.png b/core/res/res/drawable-hdpi/stat_sys_upload_anim0.png
index 45f3c7b..48ba735 100644
--- a/core/res/res/drawable-hdpi/stat_sys_upload_anim0.png
+++ b/core/res/res/drawable-hdpi/stat_sys_upload_anim0.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_upload_anim1.png b/core/res/res/drawable-hdpi/stat_sys_upload_anim1.png
index f4d5a72..cbb06a5 100644
--- a/core/res/res/drawable-hdpi/stat_sys_upload_anim1.png
+++ b/core/res/res/drawable-hdpi/stat_sys_upload_anim1.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_upload_anim2.png b/core/res/res/drawable-hdpi/stat_sys_upload_anim2.png
index b7448c8..e4edda9 100644
--- a/core/res/res/drawable-hdpi/stat_sys_upload_anim2.png
+++ b/core/res/res/drawable-hdpi/stat_sys_upload_anim2.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_upload_anim3.png b/core/res/res/drawable-hdpi/stat_sys_upload_anim3.png
index dfbd726..c2a9b03 100644
--- a/core/res/res/drawable-hdpi/stat_sys_upload_anim3.png
+++ b/core/res/res/drawable-hdpi/stat_sys_upload_anim3.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_upload_anim4.png b/core/res/res/drawable-hdpi/stat_sys_upload_anim4.png
index c4513bf..23f2f9d 100644
--- a/core/res/res/drawable-hdpi/stat_sys_upload_anim4.png
+++ b/core/res/res/drawable-hdpi/stat_sys_upload_anim4.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_upload_anim5.png b/core/res/res/drawable-hdpi/stat_sys_upload_anim5.png
index cc21de2..3fd8b7f 100644
--- a/core/res/res/drawable-hdpi/stat_sys_upload_anim5.png
+++ b/core/res/res/drawable-hdpi/stat_sys_upload_anim5.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_warning.png b/core/res/res/drawable-hdpi/stat_sys_warning.png
index 2783d89..0d1a33c 100755
--- a/core/res/res/drawable-hdpi/stat_sys_warning.png
+++ b/core/res/res/drawable-hdpi/stat_sys_warning.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/text_cursor_holo_dark.9.png b/core/res/res/drawable-hdpi/text_cursor_holo_dark.9.png
index b9435b6..ae77fa0 100644
--- a/core/res/res/drawable-hdpi/text_cursor_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/text_cursor_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/text_cursor_holo_light.9.png b/core/res/res/drawable-hdpi/text_cursor_holo_light.9.png
index 477d820c..c6bdfcc 100644
--- a/core/res/res/drawable-hdpi/text_cursor_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/text_cursor_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_default_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_search_default_holo_dark.9.png
index 5b62564..62e3274 100644
--- a/core/res/res/drawable-hdpi/textfield_search_default_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/textfield_search_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_default_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_search_default_holo_light.9.png
index 881edeb..b7512fa 100644
--- a/core/res/res/drawable-hdpi/textfield_search_default_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/textfield_search_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_right_default_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_search_right_default_holo_dark.9.png
new file mode 100644
index 0000000..bfc6f83
--- /dev/null
+++ b/core/res/res/drawable-hdpi/textfield_search_right_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_right_default_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_search_right_default_holo_light.9.png
new file mode 100644
index 0000000..708ba90
--- /dev/null
+++ b/core/res/res/drawable-hdpi/textfield_search_right_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_right_selected_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_search_right_selected_holo_dark.9.png
new file mode 100644
index 0000000..0da1e9c
--- /dev/null
+++ b/core/res/res/drawable-hdpi/textfield_search_right_selected_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_right_selected_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_search_right_selected_holo_light.9.png
new file mode 100644
index 0000000..2e93557
--- /dev/null
+++ b/core/res/res/drawable-hdpi/textfield_search_right_selected_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_selected_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_search_selected_holo_dark.9.png
index cb3f35b..7aeaad6 100644
--- a/core/res/res/drawable-hdpi/textfield_search_selected_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/textfield_search_selected_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_selected_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_search_selected_holo_light.9.png
index 742b137..cf46f32 100644
--- a/core/res/res/drawable-hdpi/textfield_search_selected_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/textfield_search_selected_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_ab_back_holo_dark.png b/core/res/res/drawable-mdpi/ic_ab_back_holo_dark.png
index 959b4e4..ae3e6bf 100644
--- a/core/res/res/drawable-mdpi/ic_ab_back_holo_dark.png
+++ b/core/res/res/drawable-mdpi/ic_ab_back_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_ab_back_holo_light.png b/core/res/res/drawable-mdpi/ic_ab_back_holo_light.png
index 41333b8..c61e3fa 100644
--- a/core/res/res/drawable-mdpi/ic_ab_back_holo_light.png
+++ b/core/res/res/drawable-mdpi/ic_ab_back_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_call_mute.png b/core/res/res/drawable-mdpi/stat_notify_call_mute.png
index be26065..845ec86 100644
--- a/core/res/res/drawable-mdpi/stat_notify_call_mute.png
+++ b/core/res/res/drawable-mdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_car_mode.png b/core/res/res/drawable-mdpi/stat_notify_car_mode.png
index 60d9202..dfd2e0a 100644
--- a/core/res/res/drawable-mdpi/stat_notify_car_mode.png
+++ b/core/res/res/drawable-mdpi/stat_notify_car_mode.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_chat.png b/core/res/res/drawable-mdpi/stat_notify_chat.png
index 36ac850..e4464c2 100644
--- a/core/res/res/drawable-mdpi/stat_notify_chat.png
+++ b/core/res/res/drawable-mdpi/stat_notify_chat.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_disk_full.png b/core/res/res/drawable-mdpi/stat_notify_disk_full.png
index 4e198ef..69b513c 100755
--- a/core/res/res/drawable-mdpi/stat_notify_disk_full.png
+++ b/core/res/res/drawable-mdpi/stat_notify_disk_full.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_email_generic.png b/core/res/res/drawable-mdpi/stat_notify_email_generic.png
index a01485e..42d518d 100644
--- a/core/res/res/drawable-mdpi/stat_notify_email_generic.png
+++ b/core/res/res/drawable-mdpi/stat_notify_email_generic.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_error.png b/core/res/res/drawable-mdpi/stat_notify_error.png
index 69c02d7..ddf0a2f 100644
--- a/core/res/res/drawable-mdpi/stat_notify_error.png
+++ b/core/res/res/drawable-mdpi/stat_notify_error.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_gmail.png b/core/res/res/drawable-mdpi/stat_notify_gmail.png
index 55bae33..516e865 100644
--- a/core/res/res/drawable-mdpi/stat_notify_gmail.png
+++ b/core/res/res/drawable-mdpi/stat_notify_gmail.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_missed_call.png b/core/res/res/drawable-mdpi/stat_notify_missed_call.png
index 58030fd..d2e3631 100644
--- a/core/res/res/drawable-mdpi/stat_notify_missed_call.png
+++ b/core/res/res/drawable-mdpi/stat_notify_missed_call.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_sdcard.png b/core/res/res/drawable-mdpi/stat_notify_sdcard.png
index 0071bf4..8f64201 100644
--- a/core/res/res/drawable-mdpi/stat_notify_sdcard.png
+++ b/core/res/res/drawable-mdpi/stat_notify_sdcard.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_sdcard_prepare.png b/core/res/res/drawable-mdpi/stat_notify_sdcard_prepare.png
index c04d70d..fc051fa 100644
--- a/core/res/res/drawable-mdpi/stat_notify_sdcard_prepare.png
+++ b/core/res/res/drawable-mdpi/stat_notify_sdcard_prepare.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_sdcard_usb.png b/core/res/res/drawable-mdpi/stat_notify_sdcard_usb.png
index 2880934..b936f45 100644
--- a/core/res/res/drawable-mdpi/stat_notify_sdcard_usb.png
+++ b/core/res/res/drawable-mdpi/stat_notify_sdcard_usb.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_sim_toolkit.png b/core/res/res/drawable-mdpi/stat_notify_sim_toolkit.png
index ee7b10c..87327b4 100755
--- a/core/res/res/drawable-mdpi/stat_notify_sim_toolkit.png
+++ b/core/res/res/drawable-mdpi/stat_notify_sim_toolkit.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_sync.png b/core/res/res/drawable-mdpi/stat_notify_sync.png
index ef9d4eb..4876b8e 100644
--- a/core/res/res/drawable-mdpi/stat_notify_sync.png
+++ b/core/res/res/drawable-mdpi/stat_notify_sync.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_sync_anim0.png b/core/res/res/drawable-mdpi/stat_notify_sync_anim0.png
index ef9d4eb..8372756 100644
--- a/core/res/res/drawable-mdpi/stat_notify_sync_anim0.png
+++ b/core/res/res/drawable-mdpi/stat_notify_sync_anim0.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_sync_error.png b/core/res/res/drawable-mdpi/stat_notify_sync_error.png
index f55bf58..2725549 100644
--- a/core/res/res/drawable-mdpi/stat_notify_sync_error.png
+++ b/core/res/res/drawable-mdpi/stat_notify_sync_error.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_voicemail.png b/core/res/res/drawable-mdpi/stat_notify_voicemail.png
index b72a07a..67a0f91 100644
--- a/core/res/res/drawable-mdpi/stat_notify_voicemail.png
+++ b/core/res/res/drawable-mdpi/stat_notify_voicemail.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_wifi_in_range.png b/core/res/res/drawable-mdpi/stat_notify_wifi_in_range.png
index 90dd76e..de63297 100644
--- a/core/res/res/drawable-mdpi/stat_notify_wifi_in_range.png
+++ b/core/res/res/drawable-mdpi/stat_notify_wifi_in_range.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_adb.png b/core/res/res/drawable-mdpi/stat_sys_adb.png
index 2c4d2b5..e259ca5 100644
--- a/core/res/res/drawable-mdpi/stat_sys_adb.png
+++ b/core/res/res/drawable-mdpi/stat_sys_adb.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_data_bluetooth.png b/core/res/res/drawable-mdpi/stat_sys_data_bluetooth.png
index f7f554e..46f6901 100644
--- a/core/res/res/drawable-mdpi/stat_sys_data_bluetooth.png
+++ b/core/res/res/drawable-mdpi/stat_sys_data_bluetooth.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_data_usb.png b/core/res/res/drawable-mdpi/stat_sys_data_usb.png
index 6cdfab7..44860bf 100644
--- a/core/res/res/drawable-mdpi/stat_sys_data_usb.png
+++ b/core/res/res/drawable-mdpi/stat_sys_data_usb.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_download_anim0.png b/core/res/res/drawable-mdpi/stat_sys_download_anim0.png
index c6f2f4e..9c77ecb 100644
--- a/core/res/res/drawable-mdpi/stat_sys_download_anim0.png
+++ b/core/res/res/drawable-mdpi/stat_sys_download_anim0.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_download_anim1.png b/core/res/res/drawable-mdpi/stat_sys_download_anim1.png
index 429ebd7..4bf5e6c 100644
--- a/core/res/res/drawable-mdpi/stat_sys_download_anim1.png
+++ b/core/res/res/drawable-mdpi/stat_sys_download_anim1.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_download_anim2.png b/core/res/res/drawable-mdpi/stat_sys_download_anim2.png
index b3de461..2211810 100644
--- a/core/res/res/drawable-mdpi/stat_sys_download_anim2.png
+++ b/core/res/res/drawable-mdpi/stat_sys_download_anim2.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_download_anim3.png b/core/res/res/drawable-mdpi/stat_sys_download_anim3.png
index 195498e..7db3096 100644
--- a/core/res/res/drawable-mdpi/stat_sys_download_anim3.png
+++ b/core/res/res/drawable-mdpi/stat_sys_download_anim3.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_download_anim4.png b/core/res/res/drawable-mdpi/stat_sys_download_anim4.png
index 8fc3e86..894dd63 100644
--- a/core/res/res/drawable-mdpi/stat_sys_download_anim4.png
+++ b/core/res/res/drawable-mdpi/stat_sys_download_anim4.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_download_anim5.png b/core/res/res/drawable-mdpi/stat_sys_download_anim5.png
index c6f2f4e..889c01e 100644
--- a/core/res/res/drawable-mdpi/stat_sys_download_anim5.png
+++ b/core/res/res/drawable-mdpi/stat_sys_download_anim5.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_gps_on.png b/core/res/res/drawable-mdpi/stat_sys_gps_on.png
index ab59f7c..e0b9d6e 100644
--- a/core/res/res/drawable-mdpi/stat_sys_gps_on.png
+++ b/core/res/res/drawable-mdpi/stat_sys_gps_on.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_secure.png b/core/res/res/drawable-mdpi/stat_sys_secure.png
index db73d06..7167c3a 100644
--- a/core/res/res/drawable-mdpi/stat_sys_secure.png
+++ b/core/res/res/drawable-mdpi/stat_sys_secure.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_speakerphone.png b/core/res/res/drawable-mdpi/stat_sys_speakerphone.png
index 0673060..25fef560 100644
--- a/core/res/res/drawable-mdpi/stat_sys_speakerphone.png
+++ b/core/res/res/drawable-mdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_throttled.png b/core/res/res/drawable-mdpi/stat_sys_throttled.png
index 28a293b..2cbe7f4 100644
--- a/core/res/res/drawable-mdpi/stat_sys_throttled.png
+++ b/core/res/res/drawable-mdpi/stat_sys_throttled.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_upload_anim0.png b/core/res/res/drawable-mdpi/stat_sys_upload_anim0.png
index f804e5e..6a05585e 100644
--- a/core/res/res/drawable-mdpi/stat_sys_upload_anim0.png
+++ b/core/res/res/drawable-mdpi/stat_sys_upload_anim0.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_upload_anim1.png b/core/res/res/drawable-mdpi/stat_sys_upload_anim1.png
index 0cbb85c..af492c8 100644
--- a/core/res/res/drawable-mdpi/stat_sys_upload_anim1.png
+++ b/core/res/res/drawable-mdpi/stat_sys_upload_anim1.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_upload_anim2.png b/core/res/res/drawable-mdpi/stat_sys_upload_anim2.png
index cfa74f3..4ba150c8 100644
--- a/core/res/res/drawable-mdpi/stat_sys_upload_anim2.png
+++ b/core/res/res/drawable-mdpi/stat_sys_upload_anim2.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_upload_anim3.png b/core/res/res/drawable-mdpi/stat_sys_upload_anim3.png
index de5c314..cbcf280 100644
--- a/core/res/res/drawable-mdpi/stat_sys_upload_anim3.png
+++ b/core/res/res/drawable-mdpi/stat_sys_upload_anim3.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_upload_anim4.png b/core/res/res/drawable-mdpi/stat_sys_upload_anim4.png
index 8847949..cb8628c 100644
--- a/core/res/res/drawable-mdpi/stat_sys_upload_anim4.png
+++ b/core/res/res/drawable-mdpi/stat_sys_upload_anim4.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_upload_anim5.png b/core/res/res/drawable-mdpi/stat_sys_upload_anim5.png
index f804e5e..e7a5376 100644
--- a/core/res/res/drawable-mdpi/stat_sys_upload_anim5.png
+++ b/core/res/res/drawable-mdpi/stat_sys_upload_anim5.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_warning.png b/core/res/res/drawable-mdpi/stat_sys_warning.png
index 494c96a..2a764fa 100644
--- a/core/res/res/drawable-mdpi/stat_sys_warning.png
+++ b/core/res/res/drawable-mdpi/stat_sys_warning.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/text_cursor_holo_dark.9.png b/core/res/res/drawable-mdpi/text_cursor_holo_dark.9.png
index b9435b6..ae77fa0 100644
--- a/core/res/res/drawable-mdpi/text_cursor_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/text_cursor_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/text_cursor_holo_light.9.png b/core/res/res/drawable-mdpi/text_cursor_holo_light.9.png
index 477d820c..c6bdfcc 100644
--- a/core/res/res/drawable-mdpi/text_cursor_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/text_cursor_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_default_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_search_default_holo_dark.9.png
index 3549948..b7413b3 100644
--- a/core/res/res/drawable-mdpi/textfield_search_default_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/textfield_search_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_default_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_search_default_holo_light.9.png
index 6db03cb..82e7a03 100644
--- a/core/res/res/drawable-mdpi/textfield_search_default_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/textfield_search_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_right_default_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_search_right_default_holo_dark.9.png
new file mode 100644
index 0000000..4b0ea21
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_search_right_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_right_default_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_search_right_default_holo_light.9.png
new file mode 100644
index 0000000..e87591c
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_search_right_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_dark.9.png
new file mode 100644
index 0000000..14f69b1
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_light.9.png
new file mode 100644
index 0000000..85329ca
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_selected_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_search_selected_holo_dark.9.png
index 670439a..7e130d9 100644
--- a/core/res/res/drawable-mdpi/textfield_search_selected_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/textfield_search_selected_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_selected_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_search_selected_holo_light.9.png
index 90e26e2..050d1c0 100644
--- a/core/res/res/drawable-mdpi/textfield_search_selected_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/textfield_search_selected_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-hdpi/stat_sys_battery_charge_anim0.png b/core/res/res/drawable-xlarge-hdpi/stat_sys_battery_charge_anim0.png
index f8063d1..a526fcf 100644
--- a/core/res/res/drawable-xlarge-hdpi/stat_sys_battery_charge_anim0.png
+++ b/core/res/res/drawable-xlarge-hdpi/stat_sys_battery_charge_anim0.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/stat_sys_battery_charge_anim0.png b/core/res/res/drawable-xlarge-mdpi/stat_sys_battery_charge_anim0.png
index 577f7cc..3640f55 100644
--- a/core/res/res/drawable-xlarge-mdpi/stat_sys_battery_charge_anim0.png
+++ b/core/res/res/drawable-xlarge-mdpi/stat_sys_battery_charge_anim0.png
Binary files differ
diff --git a/core/res/res/drawable/textfield_searchview_holo_dark.xml b/core/res/res/drawable/textfield_searchview_holo_dark.xml
new file mode 100644
index 0000000..1396f83
--- /dev/null
+++ b/core/res/res/drawable/textfield_searchview_holo_dark.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_focused="true"
+ android:drawable="@drawable/textfield_search_selected_holo_dark" />
+ <item android:drawable="@drawable/textfield_search_default_holo_dark" />
+</selector>
+
diff --git a/core/res/res/drawable/textfield_searchview_holo_light.xml b/core/res/res/drawable/textfield_searchview_holo_light.xml
new file mode 100644
index 0000000..5198f9c
--- /dev/null
+++ b/core/res/res/drawable/textfield_searchview_holo_light.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_focused="true"
+ android:drawable="@drawable/textfield_search_selected_holo_light" />
+ <item android:drawable="@drawable/textfield_search_default_holo_light" />
+</selector>
+
diff --git a/core/res/res/drawable/textfield_searchview_right_holo_dark.xml b/core/res/res/drawable/textfield_searchview_right_holo_dark.xml
new file mode 100644
index 0000000..b4f1ca1
--- /dev/null
+++ b/core/res/res/drawable/textfield_searchview_right_holo_dark.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_focused="true"
+ android:drawable="@drawable/textfield_search_right_selected_holo_dark" />
+ <item android:drawable="@drawable/textfield_search_right_default_holo_dark" />
+</selector>
+
diff --git a/core/res/res/drawable/textfield_searchview_right_holo_light.xml b/core/res/res/drawable/textfield_searchview_right_holo_light.xml
new file mode 100644
index 0000000..e521bf6
--- /dev/null
+++ b/core/res/res/drawable/textfield_searchview_right_holo_light.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_focused="true"
+ android:drawable="@drawable/textfield_search_right_selected_holo_light" />
+ <item android:drawable="@drawable/textfield_search_right_default_holo_light" />
+</selector>
+
diff --git a/core/res/res/layout/action_bar_home.xml b/core/res/res/layout/action_bar_home.xml
index e8b5637..c82f91d 100644
--- a/core/res/res/layout/action_bar_home.xml
+++ b/core/res/res/layout/action_bar_home.xml
@@ -14,16 +14,18 @@
limitations under the License.
-->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:background="?android:attr/selectableItemBackground">
+<view xmlns:android="http://schemas.android.com/apk/res/android"
+ class="com.android.internal.widget.ActionBarView$HomeView"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:background="?android:attr/selectableItemBackground" >
<ImageView android:id="@android:id/up"
android:src="?android:attr/homeAsUpIndicator"
- android:layout_gravity="top|left"
- android:visibility="invisible"
+ android:layout_gravity="center_vertical|left"
+ android:visibility="gone"
android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
+ android:layout_height="wrap_content"
+ android:layout_marginRight="-12dip" />
<ImageView android:id="@android:id/home"
android:layout_width="wrap_content"
android:layout_height="match_parent"
@@ -31,4 +33,4 @@
android:paddingRight="16dip"
android:layout_gravity="center"
android:scaleType="center" />
-</FrameLayout>
+</view>
diff --git a/core/res/res/layout/media_controller.xml b/core/res/res/layout/media_controller.xml
index f4a701e..582101a 100644
--- a/core/res/res/layout/media_controller.xml
+++ b/core/res/res/layout/media_controller.xml
@@ -59,7 +59,7 @@
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dip"
android:layout_weight="1"
- android:layout_height="30dip"
+ android:layout_height="32dip"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true" />
diff --git a/core/res/res/layout/search_view.xml b/core/res/res/layout/search_view.xml
index c41c2de..c52b73f 100644
--- a/core/res/res/layout/search_view.xml
+++ b/core/res/res/layout/search_view.xml
@@ -54,6 +54,10 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_vertical"
+ android:layout_marginLeft="4dip"
+ android:layout_marginRight="4dip"
+ android:layout_marginTop="4dip"
+ android:layout_marginBottom="4dip"
android:orientation="horizontal">
<!-- Inner layout contains the app icon, button(s) and EditText -->
@@ -64,7 +68,7 @@
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:orientation="horizontal"
- android:background="?android:attr/editTextBackground">
+ android:background="?android:attr/searchViewTextField">
<ImageView
android:id="@+id/search_app_icon"
@@ -91,7 +95,7 @@
android:inputType="text|textAutoComplete"
android:imeOptions="actionSearch"
android:dropDownHeight="wrap_content"
- android:dropDownAnchor="@id/search_plate"
+ android:dropDownAnchor="@id/search_edit_frame"
android:dropDownVerticalOffset="0dip"
android:dropDownHorizontalOffset="0dip"
/>
@@ -110,38 +114,39 @@
</LinearLayout>
- </LinearLayout>
-
- <LinearLayout
- android:id="@+id/submit_area"
- android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="match_parent">
-
- <ImageView
- android:id="@+id/search_go_btn"
+ <LinearLayout
+ android:id="@+id/submit_area"
+ android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:layout_gravity="center_vertical"
- android:paddingLeft="16dip"
- android:paddingRight="16dip"
- android:background="?android:attr/selectableItemBackground"
- android:src="?android:attr/searchViewGoIcon"
- android:visibility="gone"
- android:focusable="true"
- />
-
- <ImageView
- android:id="@+id/search_voice_btn"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_gravity="center_vertical"
- android:paddingLeft="16dip"
- android:paddingRight="16dip"
- android:src="?android:attr/searchViewVoiceIcon"
- android:background="?android:attr/selectableItemBackground"
- android:visibility="gone"
- android:focusable="true"
- />
+ android:background="?android:attr/searchViewTextFieldRight">
+
+ <ImageView
+ android:id="@+id/search_go_btn"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_gravity="center_vertical"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip"
+ android:background="?android:attr/selectableItemBackground"
+ android:src="?android:attr/searchViewGoIcon"
+ android:visibility="gone"
+ android:focusable="true"
+ />
+
+ <ImageView
+ android:id="@+id/search_voice_btn"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_gravity="center_vertical"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip"
+ android:src="?android:attr/searchViewVoiceIcon"
+ android:background="?android:attr/selectableItemBackground"
+ android:visibility="gone"
+ android:focusable="true"
+ />
+ </LinearLayout>
</LinearLayout>
+
</LinearLayout>
diff --git a/core/res/res/raw-xlarge/incognito_mode_start_page.html b/core/res/res/raw-xlarge/incognito_mode_start_page.html
new file mode 100644
index 0000000..492658d
--- /dev/null
+++ b/core/res/res/raw-xlarge/incognito_mode_start_page.html
@@ -0,0 +1,24 @@
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
+ <title>New incognito tab</title>
+ </head>
+ <body>
+ <p><strong>You've gone incognito</strong>. Pages you view in this tab
+ won't appear in your browser history or search history, and they won't
+ leave other traces, like cookies, on your device after you close the
+ incognito tab. Any files you download or bookmarks you create will be
+ preserved, however.</p>
+
+ <p><strong>Going incognito doesn't affect the behavior of other people,
+ servers, or software. Be wary of:</strong></p>
+
+ <ul>
+ <li>Websites that collect or share information about you</li>
+ <li>Internet service providers or employers that track the pages you visit</li>
+ <li>Malicious software that tracks your keystrokes in exchange for free smileys</li>
+ <li>Surveillance by secret agents</li>
+ <li>People standing behind you</li>
+ </ul>
+ </body>
+</html>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index f363bd3..71a8b2a 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -729,6 +729,10 @@
<attr name="searchViewEditQuery" format="reference" />
<!-- SearchView query refinement icon background -->
<attr name="searchViewEditQueryBackground" format="reference" />
+ <!-- SearchView text field background for the left section -->
+ <attr name="searchViewTextField" format="reference" />
+ <!-- SearchView text field background for the right section -->
+ <attr name="searchViewTextFieldRight" format="reference" />
<!-- Specifies a drawable to use for the 'home as up' indicator. -->
<attr name="homeAsUpIndicator" format="reference" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
old mode 100644
new mode 100755
index c815758..56bc1d3
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -138,9 +138,9 @@
<item>"mobile_mms,2,0,2"</item>
<item>"mobile_supl,3,0,2"</item>
<item>"mobile_hipri,5,0,3"</item>
- <item>"mobile_fota,8,0,2"</item>
- <item>"mobile_ims,9,0,2"</item>
- <item>"mobile_cbs,10,0,2"</item>
+ <item>"mobile_fota,10,0,2"</item>
+ <item>"mobile_ims,11,0,2"</item>
+ <item>"mobile_cbs,12,0,2"</item>
</string-array>
<!-- This string array should be overridden by the device to present a list of radio
@@ -544,6 +544,9 @@
which typically is /data/data/com.android.providers.downloads/files -->
<integer name="config_downloadDataDirSize">100</integer>
+ <!-- Max number of downloads allowed to proceed concurrently -->
+ <integer name="config_MaxConcurrentDownloadsAllowed">5</integer>
+
<!-- When the free space available in DownloadManager's data dir falls
below the percentage value specified by this param, DownloadManager
starts removing files to try to make percentage of available
@@ -571,4 +574,27 @@
<!-- The VoiceMail default value is displayed to my own number if it is true -->
<bool name="config_telephony_use_own_number_for_voicemail">false</bool>
+
+ <!-- If this value is true, Sms encoded as octet is decoded by utf8 decoder.
+ If false, decoded by Latin decoder. -->
+ <bool name="config_sms_utf8_support">false</bool>
+
+ <!-- If this value is true, The mms content-disposition field is supported correctly.
+ If false, Content-disposition fragments are ignored -->
+ <bool name="config_mms_content_disposition_support">true</bool>
+
+ <!-- If this value is true, the carrier supports sms delivery reports.
+ If false, sms delivery reports are not supported and the preference
+ option to enable/disable delivery reports is removed in the Messaging app. -->
+ <bool name="config_sms_delivery_reports_support">true</bool>
+
+ <!-- If this value is true, the carrier supports mms delivery reports.
+ If false, mms delivery reports are not supported and the preference
+ option to enable/disable delivery reports is removed in the Messaging app. -->
+ <bool name="config_mms_delivery_reports_support">true</bool>
+
+ <!-- If this value is true, the carrier supports mms read reports.
+ If false, mms read reports are not supported and the preference
+ option to enable/disable read reports is removed in the Messaging app. -->
+ <bool name="config_mms_read_reports_support">true</bool>
</resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 41ee55a..11c3916 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -982,7 +982,7 @@
<eat-comment />
<style name="MediaButton">
- <item name="android:background">@android:drawable/media_button_background</item>
+ <item name="android:background">@null</item>
<item name="android:layout_width">71dip</item>
<item name="android:layout_height">52dip</item>
</style>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index b7cc7f98..5f4ea32 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -285,6 +285,8 @@
<!-- SearchView attributes -->
<item name="searchDropdownBackground">@android:drawable/spinner_dropdown_background</item>
+ <item name="searchViewTextField">@drawable/textfield_searchview_holo_dark</item>
+ <item name="searchViewTextFieldRight">@drawable/textfield_searchview_right_holo_dark</item>
<item name="searchViewCloseIcon">@android:drawable/ic_clear</item>
<item name="searchViewSearchIcon">@android:drawable/ic_search</item>
<item name="searchViewGoIcon">@android:drawable/ic_go</item>
@@ -393,6 +395,8 @@
<!-- SearchView attributes -->
<item name="searchDropdownBackground">@android:drawable/search_dropdown_light</item>
+ <item name="searchViewTextField">@drawable/textfield_searchview_holo_light</item>
+ <item name="searchViewTextFieldRight">@drawable/textfield_searchview_right_holo_light</item>
<item name="searchViewCloseIcon">@android:drawable/ic_clear_holo_light</item>
<item name="searchViewSearchIcon">@android:drawable/ic_search_api_holo_light</item>
<item name="searchViewGoIcon">@android:drawable/ic_go_search_api_holo_light</item>
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java
index 5b76e39..d23dfd3 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java
@@ -19,6 +19,7 @@
import android.os.Bundle;
import android.test.InstrumentationTestRunner;
import android.test.InstrumentationTestSuite;
+
import com.android.connectivitymanagertest.stress.WifiApStress;
import com.android.connectivitymanagertest.stress.WifiStressTest;
@@ -44,8 +45,13 @@
@Override
public TestSuite getAllTests() {
TestSuite suite = new InstrumentationTestSuite(this);
- suite.addTestSuite(WifiApStress.class);
- suite.addTestSuite(WifiStressTest.class);
+ if (!UtilHelper.isWifiOnly()) {
+ suite.addTestSuite(WifiApStress.class);
+ suite.addTestSuite(WifiStressTest.class);
+ } else {
+ // only the wifi stress tests
+ suite.addTestSuite(WifiStressTest.class);
+ }
return suite;
}
@@ -57,11 +63,13 @@
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
- String valueStr = (String) icicle.get("softap_iterations");
- if (valueStr != null) {
- int iteration = Integer.parseInt(valueStr);
- if (iteration > 0) {
- mSoftapIterations = iteration;
+ if (!UtilHelper.isWifiOnly()) {
+ String valueStr = (String) icicle.get("softap_iterations");
+ if (valueStr != null) {
+ int iteration = Integer.parseInt(valueStr);
+ if (iteration > 0) {
+ mSoftapIterations = iteration;
+ }
}
}
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java
index 3d4dc3d..20aae47 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java
@@ -19,7 +19,7 @@
import android.os.Bundle;
import android.test.InstrumentationTestRunner;
import android.test.InstrumentationTestSuite;
-import android.util.Log;
+
import com.android.connectivitymanagertest.functional.ConnectivityManagerMobileTest;
import com.android.connectivitymanagertest.functional.WifiConnectionTest;
@@ -35,10 +35,24 @@
*/
public class ConnectivityManagerTestRunner extends InstrumentationTestRunner {
+ public String TEST_SSID = null;
+
@Override
public TestSuite getAllTests() {
TestSuite suite = new InstrumentationTestSuite(this);
- suite.addTestSuite(ConnectivityManagerMobileTest.class);
+ if (!UtilHelper.isWifiOnly()) {
+ suite.addTestSuite(ConnectivityManagerMobileTest.class);
+ } else {
+ // create a new test suite
+ suite.setName("ConnectivityManagerWifiOnlyFunctionalTests");
+ String[] methodNames = {"testConnectToWifi", "testConnectToWifWithKnownAP",
+ "testDisconnectWifi", "testDataConnectionOverAMWithWifi",
+ "testDataConnectionWithWifiToAMToWifi", "testWifiStateChange"};
+ Class<ConnectivityManagerMobileTest> testClass = ConnectivityManagerMobileTest.class;
+ for (String method: methodNames) {
+ suite.addTest(TestSuite.createTest(testClass, method));
+ }
+ }
suite.addTestSuite(WifiConnectionTest.class);
return suite;
}
@@ -56,6 +70,4 @@
TEST_SSID = testSSID;
}
}
-
- public String TEST_SSID = null;
}
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/UtilHelper.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/UtilHelper.java
new file mode 100644
index 0000000..1b966bf
--- /dev/null
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/UtilHelper.java
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ * 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 com.android.connectivitymanagertest;
+
+import android.os.SystemProperties;
+
+public class UtilHelper {
+ public static boolean isWifiOnly() {
+ return "wifi-only".equals(SystemProperties.get("ro.carrier"));
+ }
+
+
+}
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
index b87021a..d9b770a 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
@@ -17,6 +17,7 @@
package com.android.connectivitymanagertest.functional;
import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
+import com.android.connectivitymanagertest.UtilHelper;
import android.content.Intent;
import android.content.Context;
@@ -48,7 +49,7 @@
private WakeLock wl;
public ConnectivityManagerMobileTest() {
- super(PKG_NAME, ConnectivityManagerTestActivity.class);
+ super(ConnectivityManagerTestActivity.class);
}
@Override
@@ -68,13 +69,15 @@
Log.v(LOG_TAG, "airplane is not disabled, disable it.");
cmActivity.setAirplaneMode(getInstrumentation().getContext(), false);
}
- if (!cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
- ConnectivityManagerTestActivity.LONG_TIMEOUT)) {
- // Note: When the test fails in setUp(), tearDown is not called. In that case,
- // the activity is destroyed which blocks the next test at "getActivity()".
- // tearDown() is called here to avoid that situation.
- tearDown();
- fail("Device is not connected to Mobile, setUp failed");
+ if (!UtilHelper.isWifiOnly()) {
+ if (!cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
+ ConnectivityManagerTestActivity.LONG_TIMEOUT)) {
+ // Note: When the test fails in setUp(), tearDown is not called. In that case,
+ // the activity is destroyed which blocks the next test at "getActivity()".
+ // tearDown() is called here to avoid that situation.
+ tearDown();
+ fail("Device is not connected to Mobile, setUp failed");
+ }
}
}
@@ -128,8 +131,8 @@
// As Wifi stays in DISCONNETED, Mobile statys in CONNECTED,
// the connectivity manager will not broadcast any network connectivity event for Wifi
NetworkInfo networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
- cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE, networkInfo.getState(),
- NetworkState.DO_NOTHING, State.CONNECTED);
+ cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
+ networkInfo.getState(), NetworkState.DO_NOTHING, State.CONNECTED);
networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
NetworkState.DO_NOTHING, State.DISCONNECTED);
@@ -162,10 +165,13 @@
@LargeTest
public void testConnectToWifi() {
assertNotNull("SSID is null", TEST_ACCESS_POINT);
- //Prepare for connectivity verification
- NetworkInfo networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
- cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE, networkInfo.getState(),
- NetworkState.TO_DISCONNECTION, State.DISCONNECTED);
+ NetworkInfo networkInfo;
+ if (!UtilHelper.isWifiOnly()) {
+ //Prepare for connectivity verification
+ networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+ cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
+ networkInfo.getState(), NetworkState.TO_DISCONNECTION, State.DISCONNECTED);
+ }
networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
NetworkState.TO_CONNECTION, State.CONNECTED);
@@ -179,8 +185,10 @@
Log.v(LOG_TAG, "wifi state is enabled");
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
ConnectivityManagerTestActivity.LONG_TIMEOUT));
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.DISCONNECTED,
- ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ if (!UtilHelper.isWifiOnly()) {
+ assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
+ State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ }
// validate states
if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
@@ -189,11 +197,13 @@
cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
assertTrue(false);
}
- if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
- Log.v(LOG_TAG, "Mobile state transition validation failed.");
- Log.v(LOG_TAG, "reason: " +
- cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
- assertTrue(false);
+ if (!UtilHelper.isWifiOnly()) {
+ if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
+ Log.v(LOG_TAG, "Mobile state transition validation failed.");
+ Log.v(LOG_TAG, "reason: " +
+ cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
+ assertTrue(false);
+ }
}
}
@@ -225,16 +235,21 @@
// Wait for the Wifi state to be DISABLED
assertTrue(cmActivity.waitForWifiState(WifiManager.WIFI_STATE_DISABLED,
ConnectivityManagerTestActivity.LONG_TIMEOUT));
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
- ConnectivityManagerTestActivity.LONG_TIMEOUT));
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
- ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI,
+ State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ if (!UtilHelper.isWifiOnly()) {
+ assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
+ State.CONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ }
- //Prepare for connectivity state verification
- NetworkInfo networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
- cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
- networkInfo.getState(), NetworkState.DO_NOTHING,
- State.DISCONNECTED);
+ NetworkInfo networkInfo;
+ if (!UtilHelper.isWifiOnly()) {
+ //Prepare for connectivity state verification
+ networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+ cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
+ networkInfo.getState(), NetworkState.DO_NOTHING,
+ State.DISCONNECTED);
+ }
networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
NetworkState.TO_CONNECTION, State.CONNECTED);
@@ -246,8 +261,10 @@
// Wait for Wifi to be connected and mobile to be disconnected
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
ConnectivityManagerTestActivity.LONG_TIMEOUT));
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.DISCONNECTED,
- ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ if (!UtilHelper.isWifiOnly()) {
+ assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
+ State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ }
// validate wifi states
if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
@@ -277,11 +294,14 @@
Log.v(LOG_TAG, "exception: " + e.toString());
}
- NetworkInfo networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
- cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
- networkInfo.getState(),
- NetworkState.TO_CONNECTION,
- State.CONNECTED);
+ NetworkInfo networkInfo;
+ if (!UtilHelper.isWifiOnly()) {
+ networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+ cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
+ networkInfo.getState(),
+ NetworkState.TO_CONNECTION,
+ State.CONNECTED);
+ }
networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
NetworkState.TO_DISCONNECTION, State.DISCONNECTED);
@@ -291,8 +311,10 @@
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
ConnectivityManagerTestActivity.LONG_TIMEOUT));
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
- ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ if (!UtilHelper.isWifiOnly()) {
+ assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
+ State.CONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ }
// validate states
if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
@@ -301,11 +323,13 @@
cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
assertTrue(false);
}
- if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
- Log.v(LOG_TAG, "Mobile state transition validation failed.");
- Log.v(LOG_TAG, "reason: " +
- cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
- assertTrue(false);
+ if (!UtilHelper.isWifiOnly()) {
+ if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
+ Log.v(LOG_TAG, "Mobile state transition validation failed.");
+ Log.v(LOG_TAG, "reason: " +
+ cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
+ assertTrue(false);
+ }
}
}
@@ -377,14 +401,16 @@
// Eanble airplane mode
cmActivity.setAirplaneMode(getInstrumentation().getContext(), true);
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.DISCONNECTED,
- ConnectivityManagerTestActivity.LONG_TIMEOUT));
-
- NetworkInfo networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
- cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
- networkInfo.getState(),
- NetworkState.DO_NOTHING,
- State.DISCONNECTED);
+ NetworkInfo networkInfo;
+ if (!UtilHelper.isWifiOnly()) {
+ assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
+ State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+ cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
+ networkInfo.getState(),
+ NetworkState.DO_NOTHING,
+ State.DISCONNECTED);
+ }
networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
NetworkState.TO_CONNECTION, State.CONNECTED);
@@ -402,11 +428,13 @@
cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
assertTrue("State validation failed", false);
}
- if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
- Log.v(LOG_TAG, "state validation for Mobile failed");
- Log.v(LOG_TAG, "reason: " +
- cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
- assertTrue("state validation failed", false);
+ if (!UtilHelper.isWifiOnly()) {
+ if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
+ Log.v(LOG_TAG, "state validation for Mobile failed");
+ Log.v(LOG_TAG, "reason: " +
+ cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
+ assertTrue("state validation failed", false);
+ }
}
cmActivity.setAirplaneMode(getInstrumentation().getContext(), false);
}
@@ -452,8 +480,10 @@
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
ConnectivityManagerTestActivity.LONG_TIMEOUT));
- assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.DISCONNECTED,
- ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ if (!UtilHelper.isWifiOnly()) {
+ assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
+ State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ }
// validate the state transition
if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
index 2f2a283..7578e67 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
@@ -18,6 +18,7 @@
import com.android.connectivitymanagertest.ConnectivityManagerStressTestRunner;
import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
+import com.android.connectivitymanagertest.UtilHelper;
import android.content.Context;
import android.net.ConnectivityManager;
@@ -264,18 +265,22 @@
assertTrue("Wait for Wi-Fi to idle timeout",
mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
6 * ConnectivityManagerTestActivity.SHORT_TIMEOUT));
- // use long timeout as the pppd startup may take several retries.
- assertTrue("Wait for cellular connection timeout",
- mAct.waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
- ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ if (!UtilHelper.isWifiOnly()) {
+ // use long timeout as the pppd startup may take several retries.
+ assertTrue("Wait for cellular connection timeout",
+ mAct.waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
+ ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ }
sleep(mWifiSleepTime + WIFI_IDLE_DELAY, "Interrupted while device is in sleep mode");
// Verify the wi-fi is still off and data connection is on
assertEquals("Wi-Fi is reconnected", State.DISCONNECTED,
mAct.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState());
- assertEquals("Cellular connection is down", State.CONNECTED,
- mAct.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState());
- assertTrue("Mobile is connected, but no data connection.", mAct.pingTest(null));
+ if (!UtilHelper.isWifiOnly()) {
+ assertEquals("Cellular connection is down", State.CONNECTED,
+ mAct.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState());
+ assertTrue("Mobile is connected, but no data connection.", mAct.pingTest(null));
+ }
// Turn screen on again
mAct.turnScreenOn();
diff --git a/core/tests/coretests/src/android/text/TextUtilsTest.java b/core/tests/coretests/src/android/text/TextUtilsTest.java
index e111662..e8e56de 100644
--- a/core/tests/coretests/src/android/text/TextUtilsTest.java
+++ b/core/tests/coretests/src/android/text/TextUtilsTest.java
@@ -16,28 +16,20 @@
package android.text;
-import android.graphics.Paint;
+import com.google.android.collect.Lists;
+
+import android.test.MoreAsserts;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.SmallTest;
-import android.text.Spannable;
-import android.text.SpannableString;
-import android.text.Spanned;
-import android.text.SpannedString;
-import android.text.TextPaint;
-import android.text.TextUtils;
import android.text.style.StyleSpan;
import android.text.util.Rfc822Token;
import android.text.util.Rfc822Tokenizer;
-import android.test.MoreAsserts;
-import com.google.android.collect.Lists;
-import com.google.android.collect.Maps;
+import java.util.ArrayList;
+import java.util.List;
import junit.framework.TestCase;
-import java.util.List;
-import java.util.Map;
-
/**
* TextUtilsTest tests {@link TextUtils}.
*/
@@ -354,6 +346,7 @@
return mString.charAt(off);
}
+ @Override
public String toString() {
return mString.toString();
}
@@ -362,4 +355,104 @@
return new Wrapper(mString.subSequence(start, end));
}
}
+
+ @LargeTest
+ public void testRemoveEmptySpans() {
+ MockSpanned spanned = new MockSpanned();
+
+ spanned.test();
+ spanned.addSpan().test();
+ spanned.addSpan().test();
+ spanned.addSpan().test();
+ spanned.addEmptySpan().test();
+ spanned.addSpan().test();
+ spanned.addEmptySpan().test();
+ spanned.addEmptySpan().test();
+ spanned.addSpan().test();
+
+ spanned.clear();
+ spanned.addEmptySpan().test();
+ spanned.addEmptySpan().test();
+ spanned.addEmptySpan().test();
+ spanned.addSpan().test();
+ spanned.addEmptySpan().test();
+ spanned.addSpan().test();
+
+ spanned.clear();
+ spanned.addSpan().test();
+ spanned.addEmptySpan().test();
+ spanned.addSpan().test();
+ spanned.addEmptySpan().test();
+ spanned.addSpan().test();
+ spanned.addSpan().test();
+ }
+
+ protected static class MockSpanned implements Spanned {
+
+ private List<Object> allSpans = new ArrayList<Object>();
+ private List<Object> nonEmptySpans = new ArrayList<Object>();
+
+ public void clear() {
+ allSpans.clear();
+ nonEmptySpans.clear();
+ }
+
+ public MockSpanned addSpan() {
+ Object o = new Object();
+ allSpans.add(o);
+ nonEmptySpans.add(o);
+ return this;
+ }
+
+ public MockSpanned addEmptySpan() {
+ Object o = new Object();
+ allSpans.add(o);
+ return this;
+ }
+
+ public void test() {
+ Object[] nonEmpty = TextUtils.removeEmptySpans(allSpans.toArray(), this, Object.class);
+ assertEquals("Mismatched array size", nonEmptySpans.size(), nonEmpty.length);
+ for (int i=0; i<nonEmpty.length; i++) {
+ assertEquals("Span differ", nonEmptySpans.get(i), nonEmpty[i]);
+ }
+ }
+
+ public char charAt(int arg0) {
+ return 0;
+ }
+
+ public int length() {
+ return 0;
+ }
+
+ public CharSequence subSequence(int arg0, int arg1) {
+ return null;
+ }
+
+ @Override
+ public <T> T[] getSpans(int start, int end, Class<T> type) {
+ return null;
+ }
+
+ @Override
+ public int getSpanStart(Object tag) {
+ return 0;
+ }
+
+ @Override
+ public int getSpanEnd(Object tag) {
+ return nonEmptySpans.contains(tag) ? 1 : 0;
+ }
+
+ @Override
+ public int getSpanFlags(Object tag) {
+ return 0;
+ }
+
+ @Override
+ public int nextSpanTransition(int start, int limit, Class type) {
+ return 0;
+ }
+ }
}
diff --git a/core/tests/coretests/src/android/util/LruCacheTest.java b/core/tests/coretests/src/android/util/LruCacheTest.java
index 7e46e26..5a97158 100644
--- a/core/tests/coretests/src/android/util/LruCacheTest.java
+++ b/core/tests/coretests/src/android/util/LruCacheTest.java
@@ -183,20 +183,15 @@
* Replacing the value for a key doesn't cause an eviction but it does bring
* the replaced entry to the front of the queue.
*/
- public void testPutDoesNotCauseEviction() {
- final List<String> evictionLog = new ArrayList<String>();
- List<String> expectedEvictionLog = new ArrayList<String>();
- LruCache<String, String> cache = new LruCache<String, String>(3) {
- @Override protected void entryEvicted(String key, String value) {
- evictionLog.add(key + "=" + value);
- }
- };
+ public void testPutCauseEviction() {
+ List<String> log = new ArrayList<String>();
+ LruCache<String, String> cache = newRemovalLogCache(log);
cache.put("a", "A");
cache.put("b", "B");
cache.put("c", "C");
cache.put("b", "B2");
- assertEquals(expectedEvictionLog, evictionLog);
+ assertEquals(Arrays.asList("b=B>B2"), log);
assertSnapshot(cache, "a", "A", "c", "C", "b", "B2");
}
diff --git a/core/tests/systemproperties/AndroidManifest.xml b/core/tests/systemproperties/AndroidManifest.xml
index ad0abf4..1608788 100644
--- a/core/tests/systemproperties/AndroidManifest.xml
+++ b/core/tests/systemproperties/AndroidManifest.xml
@@ -24,7 +24,7 @@
</application>
<instrumentation android:name="android.test.InstrumentationTestRunner"
- android:targetPackage="com.android.frameworks.coretests"
- android:label="Frameworks Core Tests" />
+ android:targetPackage="com.android.frameworks.coretests.systemproperties"
+ android:label="Frameworks SystemProperties Core Tests" />
</manifest>
diff --git a/core/tests/systemproperties/run_core_systemproperties_test.sh b/core/tests/systemproperties/run_core_systemproperties_test.sh
index 48880f3..d39adbb 100755
--- a/core/tests/systemproperties/run_core_systemproperties_test.sh
+++ b/core/tests/systemproperties/run_core_systemproperties_test.sh
@@ -16,6 +16,9 @@
if [[ $rebuild == true ]]; then
make -j4 FrameworksCoreSystemPropertiesTests
TESTAPP=${ANDROID_PRODUCT_OUT}/data/app/FrameworksCoreSystemPropertiesTests.apk
+ COMMAND="adb install -r $TESTAPP"
+ echo $COMMAND
+ $COMMAND
fi
adb shell am instrument -w -e class android.os.SystemPropertiesTest com.android.frameworks.coretests.systemproperties/android.test.InstrumentationTestRunner
diff --git a/data/keyboards/Generic.kl b/data/keyboards/Generic.kl
index 33947e7..68a158e 100644
--- a/data/keyboards/Generic.kl
+++ b/data/keyboards/Generic.kl
@@ -426,6 +426,10 @@
axis 0x03 RX
axis 0x04 RY
axis 0x05 RZ
+axis 0x06 THROTTLE
+axis 0x07 RUDDER
+axis 0x08 WHEEL
+axis 0x09 GAS
+axis 0x0a BRAKE
axis 0x10 HAT_X
axis 0x11 HAT_Y
-
\ No newline at end of file
diff --git a/data/keyboards/Vendor_045e_Product_028e.kl b/data/keyboards/Vendor_045e_Product_028e.kl
new file mode 100644
index 0000000..99f046a
--- /dev/null
+++ b/data/keyboards/Vendor_045e_Product_028e.kl
@@ -0,0 +1,46 @@
+# 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.
+
+#
+# XBox 360 USB Controller
+#
+
+key 304 BUTTON_A
+key 305 BUTTON_B
+key 307 BUTTON_X
+key 308 BUTTON_Y
+key 310 BUTTON_L1
+key 311 BUTTON_R1
+key 314 BUTTON_SELECT
+key 315 BUTTON_START
+key 316 BUTTON_MODE
+key 317 BUTTON_THUMBL
+key 318 BUTTON_THUMBR
+
+# Left and right stick.
+# The reported value for flat is 128 out of a range from -32767 to 32768, which is absurd.
+# This confuses applications that rely on the flat value because the joystick actually
+# settles in a flat range of +/- 4096 or so.
+axis 0x00 X flat 4096
+axis 0x01 Y flat 4096
+axis 0x03 Z flat 4096
+axis 0x04 RZ flat 4096
+
+# Triggers.
+axis 0x02 LTRIGGER
+axis 0x05 RTRIGGER
+
+# Hat.
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
diff --git a/data/keyboards/Vendor_046d_Product_c294.kl b/data/keyboards/Vendor_046d_Product_c294.kl
new file mode 100644
index 0000000..5492f49
--- /dev/null
+++ b/data/keyboards/Vendor_046d_Product_c294.kl
@@ -0,0 +1,53 @@
+# 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.
+
+#
+# Logitech G25 Racing Wheel (in Compatibility Mode)
+#
+
+# 4 way buttons above hat
+key 0x121 BUTTON_A
+key 0x123 BUTTON_B
+key 0x120 BUTTON_X
+key 0x122 BUTTON_Y
+
+# Row of buttons under hat
+key 0x12b BUTTON_1
+key 0x128 BUTTON_2
+key 0x129 BUTTON_3
+key 0x12a BUTTON_4
+
+# Gear shift positions
+# 0x12a top-left gear (aliased as BUTTON_4)
+# 0x12b bottom-left gear (aliased as BUTTON_1)
+
+# Buttons on wheel
+key 0x127 BUTTON_L1
+key 0x126 BUTTON_R1
+
+# Toggles under wheel
+key 0x125 BUTTON_L2
+key 0x124 BUTTON_R2
+
+# Hat
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+
+# Steering Wheel
+axis 0x00 WHEEL
+
+# Accelerator / Brake
+# 00..7e : accelerator
+# 80..ff : brake
+axis 0x01 split 0x7f GAS BRAKE
diff --git a/data/keyboards/Vendor_046d_Product_c299.kl b/data/keyboards/Vendor_046d_Product_c299.kl
new file mode 100644
index 0000000..d42963d
--- /dev/null
+++ b/data/keyboards/Vendor_046d_Product_c299.kl
@@ -0,0 +1,62 @@
+# 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.
+
+#
+# Logitech G25 Racing Wheel (in Native Mode)
+#
+
+# 4 way buttons above hat
+key 0x121 BUTTON_A
+key 0x123 BUTTON_B
+key 0x120 BUTTON_X
+key 0x122 BUTTON_Y
+
+# Row of buttons under hat
+key 0x12b BUTTON_1
+key 0x128 BUTTON_2
+key 0x129 BUTTON_3
+key 0x12a BUTTON_4
+
+# Gear shift positions
+key 0x12c BUTTON_5
+key 0x12d BUTTON_6
+key 0x12e BUTTON_7
+key 0x12f BUTTON_8
+key 0x2d0 BUTTON_9
+key 0x2d1 BUTTON_10
+key 0x2d2 BUTTON_11
+
+# Buttons on wheel
+key 0x127 BUTTON_L1
+key 0x126 BUTTON_R1
+
+# Toggles under wheel
+key 0x125 BUTTON_L2
+key 0x124 BUTTON_R2
+
+# Hat
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+
+# Steering Wheel
+axis 0x00 WHEEL
+
+# Clutch
+axis 0x01 invert GENERIC_1
+
+# Accelerator
+axis 0x02 invert GAS
+
+# Brake
+axis 0x05 invert BRAKE
diff --git a/data/keyboards/common.mk b/data/keyboards/common.mk
index 5b367b9..335298c 100644
--- a/data/keyboards/common.mk
+++ b/data/keyboards/common.mk
@@ -19,7 +19,10 @@
Generic.kl \
AVRCP.kl \
qwerty.kl \
+ Vendor_045e_Product_028e.kl \
Vendor_046d_Product_c216.kl \
+ Vendor_046d_Product_c294.kl \
+ Vendor_046d_Product_c299.kl \
Vendor_046d_Product_c532.kl \
Vendor_054c_Product_0268.kl \
Vendor_05ac_Product_0239.kl \
diff --git a/docs/html/guide/appendix/faq/commontasks.jd b/docs/html/guide/appendix/faq/commontasks.jd
index 4747379..b0c96b1 100644
--- a/docs/html/guide/appendix/faq/commontasks.jd
+++ b/docs/html/guide/appendix/faq/commontasks.jd
@@ -1,821 +1,8 @@
-page.title=Common Tasks and How to Do Them in Android
-parent.title=FAQs, Tips, and How-to
-parent.link=index.html
@jd:body
-<ul>
- <li><a href="#neweclipseandroidproject">Creating an Android Application using
- the Eclipse plugin</a></li>
- <li><a href="#newandroidprojectnoeclipse">Creating an Android Application without
- the Eclipse plugin</a></li>
- <li><a href="#addexternallibrary">Adding an External Library (.jar) using Eclipse</a></li>
- <li><a href="#implementcallbacks">Implementing Activity callbacks</a> (Android
- calls your activity at various key moments in its life cycle. You must know
- how to handle each of these to draw your screen, initialize class members,
- and acquire data.)</li>
- <li><a href="#opennewscreen">Opening a new screen</a></li>
- <li><a href="#listening">Listening for button clicks </a></li>
- <li><a href="#configurewindowproperties">Configuring general window properties </a></li>
- <li><a href="#localhostalias">Referring to localhost from the emulated environment</a></li>
- <li><a href="#appstate">Storing and retrieving state</a></li>
- <li><a href="{@docRoot}guide/topics/data/data-storage.html#preferences">Storing and retrieving preferences</a></li>
- <li><a href="#storingandretrieving">Storing and retrieving larger or more complex
- persistent data</a> (files and data) </li>
- <li><a href="#playback">Playing audio, video, still, or other media files</a></li>
- <li><a href="#broadcastreceivers">Listening for and broadcasting global messages
- and setting alarms</a></li>
- <li><a href="#alerts">Displaying alerts </a></li>
- <li><a href="#progressbar">Displaying a progress bar</a> </li>
- <li><a href="#addmenuitems">Adding items to the screen menu</a> </li>
- <li><a href="#webpage">Display a web page</a> </li>
- <li><a href="#binding">Binding to data</a></li>
- <li><a href="#handle">Getting a Handle to a Screen Element</a></li>
- <li><a href="#captureimages">Capture images from the phone camera </a></li>
- <li><a href="#threading">Handling expensive operations in the UI thread</a></li>
- <li><a href="#selectingtext">Selecting, highlighting, or styling portions of
- text</a></li>
- <li><a href="#querymap">Utilizing attributes in a Map query</a></li>
- <li><a href="#filelist">List of files for an Android application</a></li>
- <li><a href="#logging">Print messages to a log file</a></li>
-</ul>
-<p>The ApiDemos sample application includes many, many examples of common
-tasks and UI features. See the code inside
-<code><sdk>samples/ApiDemos</code> and the other sample applications
-under the <code>samples/</code> folder in the SDK.</p>
+<script type="text/javascript">
+ document.location=toRoot+"resources/faq/commontasks.html"
+</script>
-
-<h2 id="neweclipseandroidproject">Creating an Android Application using the Eclipse Plugin</h2>
-
-<p>Using the Android Eclipse plugin is the fastest and easiest way
-to start creating a new Android application. The plugin automatically generates
-the correct project structure for your application, and keeps the resources
-compiled for you automatically.</p>
-
-<p>It is still a good idea to know what is going on though. Take a look at <a
-href="{@docRoot}guide/topics/fundamentals.html">Application Fundamentals</a>
-to understand the basics of how an Android application works.</p>
-
-<p>You should also take a look at the ApiDemos application and the other sample
-applications included in the SDK, in the <code><sdk>/samples/</code>
-folder in the SDK.</p>
-
-<p>Finally, a great way to started with Android development in Eclipse is to
-follow both the <a href="{@docRoot}resources/tutorials/hello-world.html">Hello,
-World</a> and <a
-href="{@docRoot}resources/tutorials/notepad/index.html">Notepad</a> code
-tutorials. In particular, the start of the Hello Android tutorial is an
-excellent introduction to creating a new Android application in Eclipse.</p>
-
-<h2 id="newandroidprojectnoeclipse">Creating an Android Application without the Eclipse Plugin</h2>
-
-<p>This topic describes the manual steps in creating an Android application.
-Before reading this, you should read <a
-href="{@docRoot}guide/topics/fundamentals.html">Application Fundamentals</a>
-to understand the basics of how an Android application works. You might also
-want to look at the sample code included with the Android SDK, in the
-<code><sdk>/samples/</code> directory. </p>
-
-<p>Here is a list of the basic steps in building an application.</p>
-<ol>
- <li><strong>Create your required resource files</strong> This includes
- the AndroidManifest.xml global description file, string files that your application
- needs, and layout files describing your user interface. A full list of optional
- and required files and syntax details for each is given in <a href="#filelist">File
- List for an Android Application</a>. </li>
- <li><strong>Design your user interface</strong> See <a
- href="{@docRoot}guide/topics/ui/index.html">User Interface</a> for
- details on elements of the Android screen. </li>
- <li><strong>Implement your Activity </strong>(this page)<strong> </strong> You
- will create one class/file for each screen in your application. Screens will
- inherit from an {@link android.app android.app} class, typically {@link android.app.Activity
- android.app.Activity} for basic screens, {@link android.app.ListActivity
- android.app.ListActivity} for list screens, or {@link android.app.Dialog
- android.app.Dialog} for dialog boxes. You will implement the required callbacks
- that let you draw your screen, query data, and commit changes, and also perform
- any required tasks such as opening additional screens or reading data from
- the device. Common tasks, such as opening a new screen or reading data from
- the device, are described below.
- The list of files you'll need for your application are described in <a href="#filelist">List
- of Files for an Android Application</a>. </li>
- <li><strong><a href="{@docRoot}guide/developing/other-ide.html#buildingwithant">Build and install your
- package</a>.</strong> The Android SDK has some nice tools for generating
- projects and debugging code. </li>
-</ol>
-
-<h2 id="addexternallibrary">Adding an External Library (.jar) using Eclipse</h2>
-<p>
-You can use a third party JAR in your application by adding it to your Eclipse project as follows:
-</p>
-<ol>
-<li>
-In the <strong>Package Explorer</strong> panel, right-click on your project and select <strong>Properties</strong>.
-<li>
-Select <strong>Java Build Path</strong>, then the tab <strong>Libraries</strong>.
-<li>
-Press the <strong>Add External JARs...</strong> button and select the JAR file.
-</ol>
-<p>
-Alternatively, if you want to include third party JARs with your package, create a new directory for them within your project and select <strong>Add Library...</strong> instead.</p>
-<p>
-It is not necessary to put external JARs in the assets folder.
-</p>
-
-<a name="implementcallbacks" id="implementcallbacks"></a>
-<h2>Implementing Activity Callbacks</h2>
-<p>Android calls a number of callbacks to let you draw your screen, store data before
- pausing, and refresh data after closing. You must implement at least some of
- these methods. See the <a
-href="{@docRoot}guide/topics/fundamentals/activites.html#Lifecycle">Activities</a>
- document to learn when and in what order these methods
- are called. Here are some of the standard types of screen classes that Android provides:</p>
-<ul>
- <li>{@link android.app.Activity android.app.Activity} - This is a standard screen,
- with no specialization.</li>
- <li>{@link android.app.ListActivity android.app.ListActivity} - This is a screen
- that is used to display a list of something. It hosts a ListView object,
- and exposes methods to let you identify the selected item, receive callbacks
- when the selected item changes, and perform other list-related actions. </li>
- <li>{@link android.app.Dialog android.app.Dialog} - This is a small, popup dialog-style
- window that isn't intended to remain in the history stack. (It is not resizeable
- or moveable by the user.)</li>
-</ul>
-
-<a name="opennewscreen" id="opennewscreen"></a><h2>Opening a New Screen</h2>
-<p>Your Activity will often need to open another Activity screen as it progresses.
- This new screen can be part of the same application or part of another application,
- the new screen can be floating or full screen, it can return a result, and you
- can decide whether to close this screen and remove it from the history stack
- when you are done with it, or to keep the screen open in history. These next
- sections describe all these options. </p>
-<h3>Floating or full?<a name="floatingorfull" id="floatingorfull"></a></h3>
-<p>When you open a new screen you can decide whether to make it transparent or floating,
- or full-screen. The choice of new screen affects the event sequence of events
- in the old screen (if the new screen obscures the old screen, a different
- series of events is called in the old screen). See the <a
- href="{@docRoot}guide/topics/fundamentals/activities.html#Lifecycle">Activities</a> document for
-details. </p>
-<p>Transparent or floating windows are implemented in three
- standard ways: </p>
-<ul>
- <li>Create an {@link android.app.Dialog app.Dialog} class </li>
- <li>Create an {@link android.app.AlertDialog app.AlertDialog} class </li>
- <li>Set the {@link android.R.style#Theme_Dialog} <em>theme</em> attribute to <code>@android:style/Theme.Dialog</code>
- in your AndroidManifest.xml file. For example:
- <pre><activity class="AddRssItem" android:label="Add an item" android:theme="@android:style/Theme.Dialog"/>
-</pre></li>
-</ul>
-<p>Calling startActivity() or startActivityForResult() will open a new screen in whatever
- way it defines itself (if it uses a floating theme it will be floating,
- otherwise it will be full screen). </p>
-<h3>Opening a Screen </h3>
-<p>When you want to open a new screen, you can either explicitly specify the activity
- class to open, or you can let the operating system decide which screen to open,
- based upon the data and various parameters you pass in. A screen is opened by
- calling {@link android.app.Activity#startActivity(android.content.Intent) startActivity}
- and passing in an {@link android.content.Intent Intent} object, which specifies
- the criteria for the handling screen. To specify a specific screen, call Intent.setClass
- or setClassName with the exact activity class to open. Otherwise, set a variety
- of values and data, and let Android decide which screen is appropriate to open.
- Android will find one or zero Activities that match the specified requirements;
- it will never open multiple activities for a single request. More information
- on Intents and how Android resolves them to a specific class is given in the
- {@link android.content.Intent Intent} topic. </p>
-<a name="intentexamples" id="intentexamples"></a><h3>Some Intent examples </h3>
-<p>The following snippet loads the com.android.samples.Animation1 class, and
- passes it some arbitrary data.:</p>
-<pre>Intent myIntent = new Intent();
-myIntent.setClassName("com.android.samples", "com.android.samples.Animation1");
-myIntent.putExtra("com.android.samples.SpecialValue", "Hello, Joe!"); // key/value pair, where key needs current package prefix.
-startActivity(myIntent); </pre>
-<p>The next snippet requests that a Web page be opened by specifying the VIEW action,
- and a URI data string starting with "http://" schema:</p>
-<pre>Intent myIntent = new Intent(Intent.VIEW_ACTION, Uri.parse("http://www.google.com"));</pre>
-<p>Here is the intent filter from the AndroidManifest.xml file for com.android.browser:</p>
-<pre><intent-filter>
- <action android:name="android.intent.action.VIEW" />
- <category android:name="android.intent.category.DEFAULT" />
- <scheme android:name="http" />
- <scheme android:name="https" />
- <scheme android:name="file" />
-</intent-filter> </pre>
-<p>Android defines a number of standard values, for instance the action constants
- defined by {@link android.content.Intent}. You can define custom values, but
- both the caller and handler must use them. See the <intent-filter>
- tag description in <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">The AndroidManifest.xml
- File</a> for more information on the manifest syntax for the handling
- application. </p>
-<a name="returningaresult" id="returningaresult"></a><h3>Returning a Result from a Screen</h3>
-<p>A window can return a result after it closes. This result will be passed back
- into the calling Activity's {@link android.app.Activity#onActivityResult(int,int,android.content.Intent)
- onActivityResult()} method, which can supply an Intent containing arbitrary data, along with
- the request code passed to startActivityForResult(). Note that you must call the {@link
- android.app.Activity#startActivityForResult(android.content.Intent,int) startActivityForResult()}
- method that accepts a request code parameter to get this callback. The following
- code demonstrates opening a new screen and retrieving a result. </p>
-<pre>// Open the new screen.
-public void onClick(View v){
- // Start the activity whose result we want to retrieve. The
- // result will come back with request code GET_CODE.
- Intent intent = new Intent(this, com.example.app.ChooseYourBoxer.class);
- startActivityForResult(intent, CHOOSE_FIGHTER);
-}
-
-// Listen for results.
-protected void onActivityResult(int requestCode, int resultCode, Intent data){
- // See which child activity is calling us back.
- switch (resultCode) {
- case CHOOSE_FIGHTER:
- // This is the standard resultCode that is sent back if the
- // activity crashed or didn't doesn't supply an explicit result.
- if (resultCode == RESULT_CANCELED){
- myMessageboxFunction("Fight cancelled");
- }
- else {
- myFightFunction(data);
- }
- default:
- break;
- }
-}
-
-// Class SentResult
-// Temporary screen to let the user choose something.
- private OnClickListener mLincolnListener = new OnClickListener(){
- public void onClick(View v) {
- Bundle stats = new Bundle();
- stats.putString("height","6\'4\"");
- stats.putString("weight", "190 lbs");
- stats.putString("reach", "74\"");
- setResult(RESULT_OK, "Lincoln", stats);
- finish();
- }
- };
-
- private OnClickListener mWashingtonListener = new OnClickListener() {
- public void onClick(View v){
- Bundle stats = new Bundle();
- stats.putString("height","6\'2\"");
- stats.putString("weight", "190 lbs");
- stats.putString("reach", "73\"");
- setResult(RESULT_OK, "Washington", Bundle);
- finish();
- }
- };
- </pre>
-<h3>Lifetime of the new screen </h3>
-<p>An activity can remove itself from the history stack by calling {@link android.app.Activity#finish()
- Activity.finish()} on itself, or the activity that opened the screen can call
- {@link android.app.Activity#finishActivity(int) Activity.finishActivity()}
- on any screens that it opens to close them. </p>
-<a name="listening" id="listening"></a><h2>Listening for Button Clicks</h2>
-<p>Button click and other UI event capturing are covered in <a href="{@docRoot}guide/topics/ui/ui-events.html">Handling UI Events</a> on the UI Design page.</p>
-<a name="configurewindowproperties" id="configurewindowproperties"></a><h2>Configuring General Window Properties</h2>
-<p>You can set a number of general window properties, such as whether to display
- a title, whether the window is floating, and whether it displays an icon, by
- calling methods on the {@link android.view.Window Window} member
- of the underlying View object for the window. Examples include calling {@link
- android.app.Activity#getWindow() getWindow().requestFeature()} (or the convenience
- method {@link android.app.Activity#requestWindowFeature(int) requestWindowFeature(<em>some_feature</em>)})
- to hide the title. Here is an example of hiding the title bar:</p>
-<pre>//Hide the title bar
-requestWindowFeature(Window.FEATURE_NO_TITLE);
-</pre>
-<p>A better way to achieve the same end is to specify a theme in your Android
-Manifest file:</p>
-<pre><application android:icon="@drawable/icon" android:theme="@android:style/Theme.NoTitleBar">
-</pre>
-<p>This is preferable because it tells the system not to show a title bar while
-your application is starting up. With the explicit method call, your application
-will have a title bar visible to the user until <code>onCreate</code> runs.</p>
-<p>(Note that this can be applied to either the <code><application></code>
-tag or to individual <code><activity></code> tags.)</p>
-<a name="localhostalias" id="localhostalias"></a><h2>Referring to localhost from the emulated environment</h2>
-<p>
-If you need to refer to your host computer's <em>localhost</em>, such as when you
-want the emulator client to contact a server running on the same host, use the alias
-<code>10.0.2.2</code> to refer to the host computer's loopback interface.
-From the emulator's perspective, localhost (<code>127.0.0.1</code>) refers to its own
-loopback interface.
-</p>
-<a name="appstate" id="appstate"></a><h2>Storing and Retrieving State</h2>
-<p>If your application is dumped from memory because of space concerns, it will lose
- all user interface state information such as checkbox state and text box values
- as well as class member values. Android calls {@link android.app.Activity#onSaveInstanceState(android.os.Bundle)
- Activity.onSaveInstanceState} before it pauses the application. This method hands in a {@link
- android.os.Bundle Bundle} that can be used to store name/value pairs that will
- persist and be handed back to the application even if it is dropped from memory.
- Android will pass this Bundle back to you when it calls {@link android.app.Activity#onCreate(android.os.Bundle)
- onCreate()}. This Bundle only exists while the application is still in the history
- stack (whether or not it has been removed from memory) and will be lost when
- the application is finalized. See the topics for {@link android.app.Activity#onSaveInstanceState} and
- {@link android.app.Activity#onCreate} for
- examples of storing and retrieving state.</p>
-<p>Read more about the lifecycle of an activity in <a
-href="{@docRoot}guide/topics/fundamentals/activities.html">Activities</a> document.</p>
-<h3>Storing and Retrieving Larger or More Complex Persistent Data<a name="storingandretrieving" id="storingandretrieving"></a></h3>
-<p>Your application can store files or complex collection objects, and reserve them
- for private use by itself or other activities in the application, or it can expose
- its data to all other applications on the device. See <a href="{@docRoot}guide/topics/data/data-storage.html">Storing,
- Retrieving, and Exposing Data</a> to learn how to store and retrieve private data,
- how to store and retrieve common data from the device, and how to expose your
- private data to other applications.</p>
-<a name="playback" id="playback"></a><h2>Playing Media Files</h2>
-<p>Please see the document <a href="{@docRoot}guide/topics/media/index.html">Audio and Video</a> for more details.</p>
-<a name="broadcastreceivers" id="broadcastreceivers"></a><h2>Listening For and Broadcasting Global Messages, and Setting Alarms</h2>
-<p>You can create a listening class that can be notified or even instantiated whenever
- a specific type of system message is sent.
-</p>
-<p>The listening classes, called broadcast receivers, extend {@link android.content.BroadcastReceiver
- BroadcastReceiver}. If you want Android to instantiate the object whenever an appropriate
- intent notification is sent, define the receiver with a <code><receiver></code> element
- in the AndroidManifest.xml file. If the caller is expected to instantiate the
- object in preparation to receive a message, this is not required. The receiver
- will get a call to their {@link android.content.BroadcastReceiver#onReceive(android.content.Context,android.content.Intent)
- BroadcastReceiver.onReceive()} method. A receiver can define an <code><intent-filter></code> tag
- that describes the types of messages it will receive. Just as Android's IntentResolver
- will look for appropriate Activity matches for a startActivity() call, it will
- look for any matching Receivers (but it will send the message to all matching
- receivers, not to the "best" match). </p>
-<p>To send a notification, the caller creates an {@link android.content.Intent Intent}
- object and calls {@link android.app.Activity#sendBroadcast(android.content.Intent)
- Context.sendBroadcast()} with that Intent. Multiple recipients can receive
- the same message. You can broadcast an Intent message to an intent receiver in
- any application, not only your own. If the receiving class is not registered
- using <code><receiver></code> in its manifest, you can dynamically instantiate
- and register a receiver by calling {@link android.content.Context#registerReceiver(android.content.BroadcastReceiver,android.content.IntentFilter)
- Context.registerReceiver()}. </p>
-<p>Receivers can include intent filters to specify what kinds of intents they are
- listening for. Alternatively, if you expect a single known caller to contact
- a single known receiver, the receiver does not specify an intent filter, and
- the caller specifies the receiver's class name in the Intent by calling {@link
- android.content.Intent#setClassName(java.lang.String, java.lang.String) Intent.setClassName()}
- with the recipient's class name. The recipient receives a {@link android.content.Context
- Context} object that refers to its own package, not to the package of the sender.</p>
-<p><em><strong>Note:</strong></em> If a receiver or broadcaster
- enforces permissions, your application might need to request permission
- to send or receive messages from that object. You can request permission by using
- the <uses-permission> tag in the manifest. </p>
-<p>Here is a code snippet of a sender and receiver. This example does not demonstrate
- registering receivers dynamically. For a full code example, see the AlarmService
- class in the ApiDemos project.</p>
-<h3>Sending the message</h3>
-<pre>// We are sending this to a specific recipient, so we will
-// only specify the recipient class name.
-Intent intent = new Intent(this, AlarmReceiver.class);
-intent.putExtra("message","Wake up.");
-sendBroadcast(intent);
-</pre>
-<h3>Receiving the message</h3>
-<p><strong>Receiver AndroidManifest.xml </strong>(because there is no intent filter
- child, this class will only receive a broadcast when the receiver class is specified
- by name, as is done in this example):</p>
-<pre>
-<receiver class=".AlarmReceiver" /></pre>
-<p><strong>Receiver Java code: </strong></p>
-<pre>
-public class AlarmReceiver extends BroadcastReceiver{
- // Display an alert that we've received a message.
- @Override
- public void onReceive(Context context, Intent intent){
- // Send a text notification to the screen.
- NotificationManager nm = (NotificationManager)
- context.getSystemService(Context.NOTIFICATION_SERVICE);
- nm.notifyWithText(R.id.alarm,
- "Alarm!!!",
- NotificationManager.LENGTH_SHORT,
- null);
- }
-} </pre>
-<h3>Other system messages</h3>
-<p>You can listen for other system messages sent by Android as well, such as USB
- connection/removal messages, SMS arrival messages, and timezone changes. See
- {@link android.content.Intent} for a list of broadcast messages to listen for.
- Messages are marked "Broadcast Action" in the documentation. </p>
-<h3>Listening for phone events<a name="phoneevents" id="phoneevents"></a></h3>
-<p>The {@link android.telephony android.telephony} package overview page describes how to
- register to listen for phone events. </p>
-<a name="alarms" id="alarms"></a><h3>Setting Alarms </h3>
-<p>Android provides an {@link android.app.AlarmManager AlarmManager} service that
- will let you specify an Intent to send at a designated time. This intent is typically
- used to start an application at a preset time. (Note: If you want to send
- a notification to a sleeping or running application, use {@link android.os.Handler
- Handler} instead.)</p>
-<a name="alerts" id="alerts"></a><h2>Displaying Alerts</h2>
-<p>There are two major kinds of alerts that you may display to the user:
-(1) Normal alerts are displayed in response to a user action, such as
-trying to perform an action that is not allowed. (2) Out-of-band alerts,
-called notifications, are
-displayed as a result of something happening in the background, such as the
-user receiving new e-mail.</p>
-
-<a name="dialogsandalerts" id="dialogsandalerts"></a><h3>Normal Alerts</h3>
-
-<p>Android provides a number of ways for you to show popup notifications to your
- user as they interact with your application. </p>
-<table width="100%" border="1">
- <tr>
- <th scope="col">Class</th>
- <th scope="col">Description</th>
- </tr>
- <tr>
- <td>{@link android.app.Dialog app.Dialog}</td>
- <td>A generic floating dialog box with a layout that you design. </td>
- </tr>
- <tr>
- <td><p>{@link android.app.AlertDialog app.AlertDialog}</p></td>
- <td>A popup alert dialog with two buttons (typically OK and Cancel) that
- take callback handlers. See the section after this table for more details. </td>
- </tr>
- <tr>
- <td>{@link android.app.ProgressDialog ProgressDialog} </td>
- <td>A dialog box used to indicate progress of an operation with a known progress
- value or an indeterminate length (setProgress(bool)). See <strong>Views</strong> > <strong>Progress Bar</strong> in
- ApiDemos for examples. </td>
- </tr>
- <tr>
- <td>Activity</td>
- <td>By setting the theme of an activity to
- {@link android.R.style#Theme_Dialog
- android:theme="@android:style/Theme.Dialog"},
- your activity will take on
- the appearance of a normal dialog, floating on top of whatever was
- underneath it. You usually set the theme through the
- {@link android.R.attr#theme android:theme} attribute in your AndroidManifest.xml.
- The advantage of this
- over Dialog and AlertDialog is that Application has a much better managed
- life cycle than dialogs: if a dialog goes to the background and is killed,
- you cannot recapture state, whereas Application exposes a {@link android.os.Bundle
- Bundle} of saved values in <code>onCreate()</code> to help you maintain state.</td>
- </tr>
-</table>
-<h3>AlertDialog</h3>
-<p>This is a basic warning dialog box that lets you configure a message, button text,
- and callback. You can create one by calling using the {@link
- android.app.AlertDialog.Builder} class, as shown here. </p>
-<pre>private Handler mHandler = new Handler() {
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case ACCEPT_CALL:
- answer(msg.obj);
- break;
-
- case BOUNCE_TO_VOICEMAIL:
- voicemail(msg.obj);
- break;
-
- }
- }
-};
-
-
-private void IncomingMotherInLawCall(Connection c) {
- String Text;
-
- // "Answer" callback.
- Message acceptMsg = Message.obtain();
- acceptMsg.target = mHandler;
- acceptMsg.what = ACCEPT_CALL;
- acceptMsg.obj = c.getCall();
-
- // "Cancel" callback.
- final Message rejectMsg = Message.obtain();
- rejectMsg.target = mHandler;
- rejectMsg.what = BOUNCE_TO_VOICEMAIL;
- rejectMsg.obj = c.getCall();
-
- new AlertDialog.Builder(this)
- .setMessage("Phyllis is calling")
- .setPositiveButton("Answer", acceptMsg)
- .setOnCancelListener(new OnCancelListener() {
- public void onCancel(DialogInterface dialog) {
- rejectMsg.sendToTarget();
- }});
- .show();
-} </pre>
-
-<h3>Notifications</h3>
-
-<p>Out-of-band alerts should always be displayed using the
-{@link android.app.NotificationManager}, which allows you to tell the user
-about something they may be interested in without disrupting what they are
-currently doing. A notification can be anything from a brief pop-up box
-informing the user of the new information, through displaying a persistent
-icon in the status bar, to vibrating, playing sounds, or flashing lights to
-get the user's attention. In all cases, the user must explicitly shift their
-focus to the notification before they can interact with it.</p>
-
-<p>The following code demonstrates using NotificationManager to display a basic text
- popup when a new SMS message arrives in a listening service, and provides the
- current message count. You can see several more examples in the ApiDemos application,
- under app/ (named <em>notification</em>*.java).</p>
-<pre>static void setNewMessageIndicator(Context context, int messageCount){
- // Get the static global NotificationManager object.
- NotificationManager nm = NotificationManager.getDefault();</p>
-
- // If we're being called because a new message has been received,
- // then display an icon and a count. Otherwise, delete the persistent
- // message.
- if (messageCount > 0) {
- nm.notifyWithText(myApp.NOTIFICATION_GUID, // ID for this notification.
- messageCount + " new message" + messageCount > 1 ? "s":"", // Text to display.
- NotificationManager.LENGTH_SHORT); // Show it for a short time only.
- }
-}</pre>
-<p>To display a notification in the status bar and have it launch an intent when
- the user selects it (such as the new text message notification does), call {@link
- android.app.NotificationManager#notify(int, android.app.Notification) NotificationManager.notify()},
- and pass in vibration patterns, status bar icons, or Intents to associate with
- the notification. </p>
-<a name="progressbar" id="progressbar"></a><h2>Displaying a Progress Bar</h2>
-<p>An activity can display a progress bar to notify the user that something is happening.
- To display a progress bar in a screen, call {@link android.app.Activity#requestWindowFeature(int)
- Activity.requestWindowFeature(Window.FEATURE_PROGRESS)}. To set the value
- of the progress bar, call {@link android.view.Window#setFeatureInt(int,int)
- Activity.getWindow().setFeatureInt(Window.FEATURE_PROGRESS, <em>level</em>)}.
- Progress bar values are from 0 to 9,999, or set the value to 10,000 to make the
- progress bar invisible. </p>
-<p>You can also use the {@link android.app.ProgressDialog ProgressDialog} class,
- which enables a dialog box with an embedded progress bar to send a "I'm working
- on it" notification to the user. </p>
-<a name="addmenuitems" id="addmenuitems"></a><h2>Adding Items to the Screen Menu</h2>
-<p>See <a href="{@docRoot}guide/topics/ui/menus.html">Creating Menus</a>.</p>
-
-<a name="webpage" id="webpage"></a><h2>Display a Web Page</h2>
-<p>Use the {@link android.webkit.WebView webkit.WebView} object. </p>
-<a name="binding" id="binding"></a><h2>Binding to Data</h2>
-<p>You can bind a ListView to a set of underlying data by using a shim class called
- {@link android.widget.ListAdapter ListAdapter} (or a subclass). ListAdapter subclasses
- bind to a variety of data sources, and expose a common set of methods such as
- getItem() and getView(), and uses them to pick View items to display in its list.
- You can extend ListAdapter and override getView() to create your own custom list
- items. There are essentially only two steps you need to perform to bind to data: </p>
-<ol>
- <li>Create a ListAdapter object and specify its data source</li>
- <li>Give the ListAdapter to your ListView object.</li>
-</ol>
-<p>That's it!</p>
-<p>Here's an example of binding a ListActivity screen to the results from a cursor
- query. (Note that the setListAdapter() method shown is a convenience method that
- gets the page's ListView object and calls setAdapter() on it.)</p>
-<pre>// Run a query and get a Cursor pointing to the results.
-Cursor c = People.query(this.getContentResolver(), null);
-startManagingCursor(c);
-
-// Create the ListAdapter. A SimpleCursorAdapter lets you specify two interesting things:
-// an XML template for your list item, and
-// The column to map to a specific item, by ID, in your template.
-ListAdapter adapter = new SimpleCursorAdapter(this,
- android.R.layout.simple_list_item_1, // Use a template that displays a text view
- c, // Give the cursor to the list adapter
- new String[] {People.NAME} , // Map the NAME column in the people database to...
- new String[] {"text1"}); // The "text1" view defined in the XML template
-setListAdapter(adapter);</pre>
-<p>See view/List4 in the ApiDemos project for an example of extending ListAdapter
- for a new data type. </p>
-
-<a name="handle"></a>
-
-<h2>Getting a Handle to a Screen Element</h2>
-<p>You can get a handle to a screen element by calling {@link
-android.app.Activity#findViewById(int) Activity.findViewById}. You can then use
-the handle to set or retrieve any values exposed by the object. </p>
-<a name="captureimages" id="captureimages"></a><h2>Capture Images from the Phone Camera</h2>
-<p>You can hook into the device's camera onto your own Canvas object by using the
- {@link android.hardware.Camera Camera} class. See that class's documentation,
- and the ApiDemos project's Camera Preview application (Graphics/Camera Preview)
- for example code. </p>
-
-
-<a name="threading" id="threading"></a><h2>Handling Expensive Operations in the UI Thread</h2>
-<p>Avoid performing long-running operations (such as network I/O) directly in the UI thread —
-the main thread of an application where the UI is run — or your application may be blocked
-and become unresponsive. Here is a brief summary of the recommended approach for handling expensive operations:</p>
-<ol>
-<li>Create a Handler object in your UI thread</li>
-<li>Spawn off worker threads to perform any required expensive operations</li>
-<li>Post results from a worker thread back to the UI thread's handler either through a Runnable or a {@link android.os.Message}</li>
-<li>Update the views on the UI thread as needed</li>
-</ol>
-
-<p>The following outline illustrates a typical implementation:</p>
-
-<pre>
-public class MyActivity extends Activity {
-
- [ . . . ]
- // Need handler for callbacks to the UI thread
- final Handler mHandler = new Handler();
-
- // Create runnable for posting
- final Runnable mUpdateResults = new Runnable() {
- public void run() {
- updateResultsInUi();
- }
- };
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- [ . . . ]
- }
-
- protected void startLongRunningOperation() {
-
- // Fire off a thread to do some work that we shouldn't do directly in the UI thread
- Thread t = new Thread() {
- public void run() {
- mResults = doSomethingExpensive();
- mHandler.post(mUpdateResults);
- }
- };
- t.start();
- }
-
- private void updateResultsInUi() {
-
- // Back in the UI thread -- update our UI elements based on the data in mResults
- [ . . . ]
- }
-}
-</pre>
-
-<p>For further discussions on this topic, see
-<a href="{@docRoot}guide/practices/design/responsiveness.html">Designing for Responsiveness</a>
-and the {@link android.os.Handler} documentation.</p>
-
-<a name="selectingtext" id="selectingtext"></a><h2>Selecting, Highlighting, or Styling Portions of Text</h2>
-<p>You can highlight or style the formatting of strings or substrings of text in
- a TextView object. There are two ways to do this:</p>
-<ul>
- <li>If you use a <a href="{@docRoot}guide/topics/resources/available-resources.html#stringresources">string resource</a>,
- you can add some simple styling, such as bold or italic using HTML notation.
- The currently supported tags are: <code>B</code> (bold),
- <code>I</code> (italic), <code>U</code> (underline),
- <code>TT</code> (monospace), <code>BIG</code>, <code>SMALL</code>,
- <code>SUP</code> (superscript), <code>SUB</code> (subscript),
- and <code>STRIKE</code> (strikethrough).
- So, for example, in res/values/strings.xml you could declare this:<br />
- <code><resource><br />
- <string id="@+id/styled_welcome_message">We
- are <b><i>so</i></b> glad to see you.</string><br />
- </resources></code></li>
- <li>To style text on the fly, or to add highlighting or more complex styling,
- you must use the Spannable object as described next. </li>
-</ul>
-<p>To style text on the fly, you must make sure the TextView is using {@link android.text.Spannable}
- storage for the text (this will always be true if the TextView is an EditText),
- retrieve its text with {@link android.widget.TextView#getText}, and call {@link
- android.text.Spannable#setSpan}, passing in a new style class from the {@link
- android.text.style} package and the selection range. </p>
-<p>The following code snippet demonstrates creating a string with a highlighted section,
- italic section, and bold section, and adding it to an EditText object. </p>
-<pre>// Get our EditText object.
-EditText vw = (EditText)findViewById(R.id.text);
-
-// Set the EditText's text.
-vw.setText("Italic, highlighted, bold.");
-
-// If this were just a TextView, we could do:
-// vw.setText("Italic, highlighted, bold.", TextView.BufferType.SPANNABLE);
-// to force it to use Spannable storage so styles can be attached.
-// Or we could specify that in the XML.
-
-// Get the EditText's internal text storage
-Spannable str = vw.getText();
-
-// Create our span sections, and assign a format to each.
-str.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), 0, 7, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
-str.setSpan(new BackgroundColorSpan(0xFFFFFF00), 8, 19, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
-str.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 21, str.length() - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
-</pre>
-
-<a name="querymap" id="querymap"></a><h2>Utilizing attributes in a Map query</h2>
-<p>
-When using a search intent to ask the Maps activity to search for something, the Maps activity responds to the following attributes in the optional context bundle:
-</p>
-<pre>
- float "centerLatitude" default 0.0f
- float "centerLongitude" default 0.0f
- float "latitudeSpan" default 0.0f
- float "longitudeSpan" default 0.0f
- int "zoomLevel" default 10
-</pre>
-<p>
-This context information is used to center the search result in a particular area, and is equivalent to adjusting the Map activity to the described location and zoom level before issuing the query.
-</p>
-<p>
-If the latitudeSpan, longitudeSpan, and zoomLevel attributes are not consistent, then it is undefined which one takes precedence.
-</p>
-
-<a name="filelist" id="filelist"></a><h2>List of Files for an Android Application</h2>
-<p>The following list describes the structure and files of an Android application.
- Many of these files can be built for you (or stubbed out) by the android tool
- shipped in the tools/ menu of the SDK. </p>
-<table width="100%" border="0">
- <tr>
- <td width="28%" valign="top">MyApp/<br /></td>
- <td width="72%" valign="top"> </td>
- </tr>
- <tr>
- <td valign="top"> AndroidManifest.xml</td>
- <td valign="top">(<em>required</em>) Advertises the screens that this application provides,
- where they can be launched (from the main program menu or elsewhere),
- any content providers it implements and what kind of data they handle,
- where the implementation classes are, and other application-wide
- information. Syntax details for this file are described in <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">The AndroidManifest.xml File</a>.</td>
- </tr>
- <tr>
- <td valign="top"> src/<br />
- /<em>myPackagePath</em>/.../<em>MyClass</em>.java</td>
- <td valign="top">(<em>required</em>) This folder holds all the source code files for your
- application, inside the appropriate package subfolders. </td>
- </tr>
- <tr>
- <td valign="top"> res/</td>
- <td valign="top">(<em>required</em>) This folder holds all the <em>resources</em> for
- your application. Resources are external data files or description files
- that are compiled into your code at build time. Files in different folders
- are compiled differently, so you must put the proper resource into the
- proper folder. (See <a href="{@docRoot}guide/topics/resources/resources-i18n.html">Resources</a> for details.)</td>
- </tr>
- <tr>
- <td valign="top"> anim/<br />
- <em>animation1</em>.xml<br />
- <em>...</em></td>
- <td valign="top">(<em>optional</em>) Holds any animation XML description files that the
- application uses. The format of these files is described in <a href="{@docRoot}guide/topics/resources/resources-i18n.html">Resources</a>. </td>
- </tr>
- <tr>
- <td valign="top"> drawable/<br />
- <em>some_picture</em>.png<br />
- <em>some_stretchable</em>.9.png<br />
- <em>some_background</em>.xml<br />
- ...</td>
- <td valign="top">(<em>optional</em>) Zero or more files that will be compiled to {@link
- android.graphics.drawable android.graphics.drawable} resources. Files
- can be image files (png, gif, or other) or XML files describing other
- graphics such as bitmaps, stretchable bitmaps, or gradients. Supported
- bitmap file formats are PNG (preferred), JPG, and GIF (discouraged),
- as well as the custom 9-patch stretchable bitmap format. These formats
- are described in <a href="{@docRoot}guide/topics/resources/resources-i18n.html">Resources</a>. </td>
- </tr>
- <tr>
- <td valign="top"> layout/<br />
- <em>screen_1_layout</em>.xml<br />
- ...<br /></td>
- <td valign="top">(<em>optional</em>) Holds all the XML files describing screens or parts
- of screens. Although you could create a screen in Java, defining them
- in XML files is typically easier. A layout file is similar in concept
- to an HTML file that describes the screen layout and components. See <a href="{@docRoot}guide/topics/ui/index.html">User Interface</a> for more information about designing screens, and <a href="{@docRoot}guide/topics/resources/available-resources.html#layoutresources">Available Resource Types</a> for the syntax of these files.</td>
- </tr>
- <tr>
- <td valign="top"> values/<br />
- arrays<br />
- classes.xml<br />
- colors.xml<br />
- dimens.xml<br />
- strings.xml<br />
- styles.xml<br />
- values.xml<br /></td>
- <td valign="top"><p>(<em>optional</em>) XML files describing additional resources
- such as strings, colors, and styles. The naming, quantity, and number
- of these files are not enforced--any XML file is compiled, but these
- are the standard names given to these files. However, the syntax
- of these files is prescribed by Android, and described in <a href="{@docRoot}guide/topics/resources/resources-i18n.html">Resources</a>. </p>
- </td>
- </tr>
- <tr>
- <td valign="top"> xml/</td>
- <td valign="top">(<em>optional</em>) XML files that can be read at run time on the device. </td>
- </tr>
- <tr>
- <td valign="top"> raw/</td>
- <td valign="top">(<em>optional</em>) Any files to be copied directly to the device. </td>
- </tr>
-</table>
-
-
-<a name="logging" ></a>
-<h2>Print Messages to a Log File</h2>
-
-<p>To write log messages from your application:</p>
-<ol><li>Import <code>android.util.Log</code>.</li>
- <li>Use <code>Log.v()</code>, <code>Log.d()</code>, <code>Log.i()</code>,
- <code>Log.w()</code>, or <code>Log.e()</code> to log messages.
- (See the {@link android.util.Log} class.)<br/> E.g.,
- <code>Log.e(this.toString(), "error: " + err.toString())</code></li>
- <li>Launch <a href="{@docRoot}guide/developing/tools/ddms.html">DDMS</a> from a terminal
- by executing <code>ddms</code> in your Android SDK <code>/tools</code> path.</li>
- <li>Run your application in the Android emulator.</li>
- <li>From the DDMS application, select the emulator
- (e.g., "emulator-5554") and click <b>Device > Run logcat...</b>
- to view all the log data.</li>
-</ol>
-<p class="note"><strong>Note:</strong> If you are running Eclipse and
-encounter a warning about the VM debug port when opening DDMS, you can ignore it
-if you're only interested in logs. However, if you want to further inspect and
-control your processes from DDMS, then you should close Eclipse before launching DDMS so that
-it may use the VM debugging port.</p>
-
-
+<p>You should have already been redirected by your browser. Please follow
+<a href="{@docRoot}resources/faq/commontasks.html">this link</a>.</p>
\ No newline at end of file
diff --git a/docs/html/guide/appendix/faq/framework.jd b/docs/html/guide/appendix/faq/framework.jd
index 33b69ac..a79686e 100644
--- a/docs/html/guide/appendix/faq/framework.jd
+++ b/docs/html/guide/appendix/faq/framework.jd
@@ -1,197 +1,8 @@
-page.title=Android Application Framework FAQ
-parent.title=FAQs, Tips, and How-to
-parent.link=index.html
@jd:body
-<ul>
- <li><a href="#1">Do all the Activities and Services of an
- application run in a single process?</a></li>
- <li><a href="#2">Do all Activities run in the main thread of
- an application process?</a></li>
- <li><a href="#3">How do I pass complicated data structures
- from one Activity/Service to another?</a></li>
- <li><a href="#4">How can I check if an Activity is already
- running before starting it?</a></li>
- <li><a href="#5">If an Activity starts a remote service, is
- there any way for the Service to pass a message back to the Activity?</a></li>
- <li><a href="#6">How to avoid getting the Application not
- responding dialog?</a></li>
- <li><a href="#7">How does an application know if a package is
- added or removed?</a></li>
-</ul>
+<script type="text/javascript">
+ document.location=toRoot+"resources/faq/framework.html"
+</script>
-
-<a name="1" id="1"></a>
-
-<h2>Do all the Activities and Services of an application run in a
-single process?</h2>
-
-<p>All Activities and Services in an application run in a single process by
-default. If needed, you can declare an <code>android:process</code> attribute
-in your manifest file, to explicitly place a component (Activity/Service) in
-another process.</p>
-
-
-
-<a name="2" id="2"></a>
-
-<h2>Do all Activities run in the main thread of an application
-process?</h2>
-
-<p>By default, all of the application code in a single process runs
-in the main UI thread. This is the same thread
-that also handles UI events. The only exception is the code that handles
-IPC calls coming in from other processes. The system maintains a
-separate pool of transaction threads in each process to dispatch all
-incoming IPC calls. The developer should create separate threads for any
-long-running code, to avoid blocking the main UI thread.</p>
-
-
-
-<a name="3" id="3"></a>
-
-<h2>How do I pass data between Activities/Services within a single
-application?</h2>
-
-<p>It depends on the type of data that you want to share:</p>
-
-<h3>Primitive Data Types</h3>
-
-<p>To share primitive data between Activities/Services in an
-application, use Intent.putExtras(). For passing primitive data that
-needs to persist use the
-<a href="{@docRoot}guide/topics/data/data-storage.html#preferences">
-Preferences</a> storage mechanism.</p>
-
-<h3>Non-Persistent Objects</h3>
-
-<p>For sharing complex non-persistent user-defined objects for short
-duration, the following approaches are recommended:
-</p>
- <h4>The android.app.Application class</h4>
- <p>The android.app.Application is a base class for those who need to
-maintain global application state. It can be accessed via
-getApplication() from any Activity or Service. It has a couple of
-life-cycle methods and will be instantiated by Android automatically if
-your register it in AndroidManifest.xml.</p>
-
- <h4>A public static field/method</h4>
- <p>An alternate way to make data accessible across Activities/Services is to use <em>public static</em>
-fields and/or methods. You can access these static fields from any other
-class in your application. To share an object, the activity which creates your object sets a
-static field to point to this object and any other activity that wants to use
-this object just accesses this static field.</p>
-
- <h4>A HashMap of WeakReferences to Objects</h4>
- <p>You can also use a HashMap of WeakReferences to Objects with Long
-keys. When an activity wants to pass an object to another activity, it
-simply puts the object in the map and sends the key (which is a unique
-Long based on a counter or time stamp) to the recipient activity via
-intent extras. The recipient activity retrieves the object using this
-key.</p>
-
- <h4>A Singleton class</h4>
- <p>There are advantages to using a static Singleton, such as you can
-refer to them without casting getApplication() to an
-application-specific class, or going to the trouble of hanging an
-interface on all your Application subclasses so that your various
-modules can refer to that interface instead. </p>
-<p>But, the life cycle of a static is not well under your control; so
-to abide by the life-cycle model, the application class should initiate and
-tear down these static objects in the onCreate() and onTerminate() methods
-of the Application Class</p>
-</p>
-
-<h3>Persistent Objects</h3>
-
-<p>Even while an application appears to continue running, the system
-may choose to kill its process and restart it later. If you have data
-that you need to persist from one activity invocation to the next, you
-need to represent that data as state that gets saved by an activity when
-it is informed that it might go away.</p>
-
-<p>For sharing complex persistent user-defined objects, the
-following approaches are recommended:
-<ul>
- <li>Application Preferences</li>
- <li>Files</li>
- <li>contentProviders</li>
- <li>SQLite DB</li>
-</ul>
-</p>
-
-<p>If the shared data needs to be retained across points where the application
-process can be killed, then place that data in persistent storage like
-Application Preferences, SQLite DB, Files or ContentProviders. Please refer to
-the <a href="{@docRoot}guide/topics/data/data-storage.html">Data Storage</a>
-for further details on how to use these components.</p>
-
-
-
-
-<a name="4" id="4"></a>
-
-<h2>How can I check if an Activity is already running before starting
-it?</h2>
-
-<p>The general mechanism to start a new activity if its not running—
-or to bring the activity stack to the front if is already running in the
-background— is the to use the NEW_TASK_LAUNCH flag in the startActivity()
-call.</p>
-
-
-
-<a name="5" id="5"></a>
-
-<h2>If an Activity starts a remote service, is there any way for the
-Service to pass a message back to the Activity?</h2>
-
-<p>The remote service can define a callback interface and register it with the
-clients to callback into the clients. The
-{@link android.os.RemoteCallbackList RemoteCallbackList} class provides methods to
-register and unregister clients with the service, and send and receive
-messages.</p>
-
-<p>The sample code for remote service callbacks is given in <a
-href="{@docRoot}guide/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html">ApiDemos/RemoteService</a></p>
-
-
-
-<a name="6" id="6"></a>
-
-<h2>How to avoid getting the Application not responding dialog?</h2>
-
-<p>Please read the <a href="{@docRoot}guide/practices/design/responsiveness.html">Designing for Responsiveness</a>
-document.</p>
-
-
-
-
-<a name="7" id="7"></a>
-
-<h2>How does an application know if a package is added or removed?
-</h2>
-
-<p>Whenever a package is added, an intent with PACKAGE_ADDED action
-is broadcast by the system. Similarly when a package is removed, an
-intent with PACKAGE_REMOVED action is broadcast. To receive these
-intents, you should write something like this:
-<pre>
- <receiver android:name ="com.android.samples.app.PackageReceiver">
- <intent-filter>
- <action android:name="android.intent.action.PACKAGE_ADDED"/>
- <action android:name="android.intent.action.PACKAGE_REMOVED"/>
-
- <data android:scheme="package" />
- </intent-filter>
- </receiver>
- </pre>
- <br>
-Here PackageReceiver is a BroadcastReceiver class.Its onReceive()
-method is invoked, every time an application package is installed or
-removed.
-
-</p>
-
-
-
+<p>You should have already been redirected by your browser. Please follow
+<a href="{@docRoot}resources/faq/framework.html">this link</a>.</p>
\ No newline at end of file
diff --git a/docs/html/guide/appendix/faq/index.jd b/docs/html/guide/appendix/faq/index.jd
index 90415ae..4194663 100644
--- a/docs/html/guide/appendix/faq/index.jd
+++ b/docs/html/guide/appendix/faq/index.jd
@@ -1,15 +1,8 @@
-page.title=FAQs, Tips, and How-to
@jd:body
-<dl>
- <dt><a href="commontasks.html">Common Development Tasks and How To Do Them</a></dt>
- <dd>Quick and to the point — how-to's for a variety of development tasks you are likely to use.</dd>
- <dt><a href="framework.html">Application Framework FAQ</a></dt>
- <dd>Common questions about the Android Application Framework.</dd>
- <dt><a href="troubleshooting.html">Troubleshooting Tips</a></dt>
- <dd>Answers to help you troubleshoot common problems.</dd>
- <dt><a href="licensingandoss.html">Open Source Licensing FAQ</a></dt>
- <dd>Common topics around licensing and Android Open Source</dd>
- <dt><a href="security.html">Android Security FAQ</a></dt>
- <dd>Answers to common questions about Android security.</dd>
-</dl>
+<script type="text/javascript">
+ document.location=toRoot+"resources/faq/index.html"
+</script>
+
+<p>You should have already been redirected by your browser. Please follow
+<a href="{@docRoot}resources/faq/index.html">this link</a>.</p>
\ No newline at end of file
diff --git a/docs/html/guide/appendix/faq/licensingandoss.jd b/docs/html/guide/appendix/faq/licensingandoss.jd
index c267fe81..0da97db 100644
--- a/docs/html/guide/appendix/faq/licensingandoss.jd
+++ b/docs/html/guide/appendix/faq/licensingandoss.jd
@@ -1,19 +1,8 @@
-page.title=Android Open Source Licensing FAQ
-parent.title=FAQs, Tips, and How-to
-parent.link=index.html
@jd:body
-<ul>
- <li><a href="#mirror">Where can I find the open source components of Android?</a></li>
- <li><a href="#timeline">When will we see more code released under open source licenses?</a></li>
- <li><a href="#apache2">Why are you releasing the code under the Apache License instead of GPLv2?</a></li>
-</ul>
+<script type="text/javascript">
+ document.location=toRoot+"resources/faq/licensingandoss.html"
+</script>
-<a name="mirror" id="mirror"></a><h2>Where can I find the open source components of Android?</h2>
-<p>The source code for the full Android stack is available from the <a href="http://source.android.com">Android Open Source Project </a> site.
-
-<p>Other mirrored GPL and LGPL'd components are available at <a href="http://code.google.com/p/android/downloads/list"><code>http://code.google.com/p/android/downloads/list</code></a>.</p>
-<p>Notices for other licenses can be found within the SDK.</p>
-
-<a name="apache2" id="apache2"></a><h2>Why are you releasing the code under the Apache License instead of GPLv2?</h2>
-<p>One of the best explanations for the reasoning behind releasing code under Apache2 can be found in a <a href="http://arstechnica.com/news.ars/post/20071106-why-google-chose-the-apache-software-license-over-gplv2.html">ArsTechnica article</a> by Ryan Paul.</p>
+<p>You should have already been redirected by your browser. Please follow
+<a href="{@docRoot}resources/faq/licensingandoss.html">this link</a>.</p>
\ No newline at end of file
diff --git a/docs/html/guide/appendix/faq/security.jd b/docs/html/guide/appendix/faq/security.jd
index b0d832b..88bcd51 100644
--- a/docs/html/guide/appendix/faq/security.jd
+++ b/docs/html/guide/appendix/faq/security.jd
@@ -1,156 +1,8 @@
-page.title=Android Security FAQ
-parent.title=FAQs, Tips, and How-to
-parent.link=index.html
@jd:body
-<ul>
- <li><a href="#secure">Is Android Secure?</a></li>
- <li><a href="#issue">I think I found a security flaw. How do I report
- it?</a></li>
- <li><a href="#informed">How can I stay informed of Android security
- announcements?</a></li>
- <li><a href="#use">How do I securely use my Android phone?</a></li>
- <li><a href="#malware">I think I found malicious software being distributed
- for Android. How can I help?</a></li>
- <li><a href="#fixes">How will Android-powered devices receive security fixes?</a>
- </li>
- <li><a href="#directfix">Can I get a fix directly from the Android Platform
- Project?</a></li>
-</ul>
+<script type="text/javascript">
+ document.location=toRoot+"resources/faq/security.html"
+</script>
-
-<a name="secure" id="secure"></a><h2>Is Android secure?</h2>
-
-<p>The security and privacy of our users' data is of primary importance to the
-Android Open Source Project. We are dedicated to building and maintaining one
-of the most secure mobile platforms available while still fulfilling our goal
-of opening the mobile device space to innovation and competition.</p>
-
-<p>The Android Platform provides a rich <a
-href="http://code.google.com/android/devel/security.html">security model</a>
-that allows developers to request the capabilities, or access, needed by their
-application and to define new capabilities that other applications can request.
-The Android user can choose to grant or deny an application's request for
-certain capabilities on the handset.</p>
-
-<p>We have made great efforts to secure the Android platform, but it is
-inevitable that security bugs will be found in any system of this complexity.
-Therefore, the Android team works hard to find new bugs internally and responds
-quickly and professionally to vulnerability reports from external researchers.
-</p>
-
-
-<a name="issue" id="issue"></a><h2>I think I found a security flaw. How do I
-report it?</h2>
-
-<p>You can reach the Android security team at <a
-href="mailto:security@android.com">security@android.com</a>. If you like, you
-can protect your message using our <a
-href="http://code.google.com/android/security_at_android_dot_com.txt">PGP
-key</a>.</p>
-
-<p>We appreciate researchers practicing responsible disclosure by emailing us
-with a detailed summary of the issue and keeping the issue confidential while
-users are at risk. In return, we will make sure to keep the researcher informed
-of our progress in issuing a fix and will properly credit the reporter(s) when
-we announce the patch. We will always move swiftly to mitigate or fix an
-externally-reported flaw and will publicly announce the fix once patches are
-available to users.</p>
-
-
-<a name="informed" id="informed"></a><h2>How can I stay informed of Android
-security announcements?</h2>
-
-<p>An important part of sustainably securing a platform, such as, Android is
-keeping the user and security community informed of bugs and fixes. We will
-publicly announce security bugs when the fixes are available via postings to
-the <a
-href="http://groups.google.com/group/android-security-announce">android-security-announce</a>
-group on Google Groups. You can subscribe to this group as you would a mailing
-list and view the archives here.</p>
-
-<p>For more general discussion of Android platform security, or how to use
-security features in your Android application, please subscribe to <a
-href="http://groups.google.com/group/android-security-discuss">android-security-discuss</a>.
-</p>
-
-
-<a name="use" id="use"></a><h2>How do I securely use my Android phone?</h2>
-
-<p>As an open platform, Android allows users to load software from any
-developer onto a device. As with a home PC, the user must be
-aware of who is providing the software they are downloading and must decide
-whether they want to grant the application the capabilities it requests.
-This decision can be informed by the user's judgment of the software
-developer's trustworthiness, and where the software came from.</p>
-
-<p>Despite the security protections in Android, it is important
-for users to only download and install software from developers they trust.
-More details on how Android users can make smart security decisions will be
-released when consumer devices become available.</p>
-
-
-<a name="malware" id="malware"></a><h2>I think I found malicious software being
-distributed for Android. How can I help?</h2>
-
-<p>Like any other open platform, it will be possible for unethical developers
-to create malicious software, known as <a
-href="http://en.wikipedia.org/wiki/Malware">malware</a>, for Android. If you
-think somebody is trying to spread malware, please let us know at <a
-href="mailto:security@android.com">security@android.com</a>. Please include as
-much detail about the application as possible, with the location it is
-being distributed from and why you suspect it of being malicious software.</p>
-
-<p>The term <i>malicious software</i> is subjective, and we cannot make an
-exhaustive definition. Some examples of what the Android Security Team believes
-to be malicious software is any application that:
-<ul>
- <li>drains the device's battery very quickly;</li>
- <li>shows the user unsolicited messages (especially messages urging the
- user to buy something);</li>
- <li>resists (or attempts to resist) the user's effort to uninstall it;</li>
- <li>attempts to automatically spread itself to other devices;</li>
- <li>hides its files and/or processes;</li>
- <li>discloses the user's private information to a third party, without the
- user's knowledge and consent;</li>
- <li>destroys the user's data (or the device itself) without the user's
- knowledge and consent;</li>
- <li>impersonates the user (such as by sending email or buying things from a
- web store) without the user's knowledge and consent; or</li>
- <li>otherwise degrades the user's experience with the device.</li>
-</ul>
-</p>
-
-
-<a name="fixes" id="fixes"></a><h2>How will Android-powered devices receive security
-fixes?</h2>
-
-<p>The manufacturer of each device is responsible for distributing software
-upgrades for it, including security fixes. Many devices will update themselves
-automatically with software downloaded "over the air", while some devices
-require the user to upgrade them manually.</p>
-
-<p>When Android-powered devices are publicly available, this FAQ will provide links how
-Open Handset Alliance members release updates.</p>
-
-<a name="directfix" id="directfix"></a><h2>Can I get a fix directly from the
-Android Platform Project?</h2>
-
-<p>Android is a mobile platform that will be released as open source and
-available for free use by anybody. This means that there will be many
-Android-based products available to consumers, and most of them will be created
-without the knowledge or participation of the Android Open Source Project. Like
-the maintainers of other open source projects, we cannot build and release
-patches for the entire ecosystem of products using Android. Instead, we will
-work diligently to find and fix flaws as quickly as possible and to distribute
-those fixes to the manufacturers of the products.</p>
-
-<p>In addition, We will add security fixes to the open source distribution of
-Android and publicly announce the changes on <a
-href="http://groups.google.com/group/android-security-announce">android-security-announce</a>.
-</p>
-
-<p>If you are making an Android-powered device and would like to know how you can
-properly support your customers by keeping abreast of software updates, please
-contact us at <a
-href="mailto:info@openhandsetalliance.com">info@openhandsetalliance.com</a>.</p>
+<p>You should have already been redirected by your browser. Please follow
+<a href="{@docRoot}resources/faq/security.html">this link</a>.</p>
\ No newline at end of file
diff --git a/docs/html/guide/appendix/faq/troubleshooting.jd b/docs/html/guide/appendix/faq/troubleshooting.jd
index 86ab187..e3a9e4182 100755
--- a/docs/html/guide/appendix/faq/troubleshooting.jd
+++ b/docs/html/guide/appendix/faq/troubleshooting.jd
@@ -1,335 +1,8 @@
-page.title=Troubleshooting
-parent.title=FAQs, Tips, and How-to
-parent.link=index.html
@jd:body
+<script type="text/javascript">
+ document.location=toRoot+"resources/faq/troubleshooting.html"
+</script>
-<p>Here are some tips and tricks for common Android errors. Don't forget to use the
- ddms logcat capability to get a deeper view when errors occur. See <a href="{@docRoot}guide/developing/debug-tasks.html">Debugging</a> for more debugging tips. </p>
-<ul>
- <li><a href="#installeclipsecomponents">ADT Installation Error: "requires plug-in org.eclipse.wst.sse.ui".</a></li>
- <li><a href="#nodevice">ADB reports "no device" when an emulator is running</a></li>
- <li><a href="#noapp">My new application/activity isn't showing up in the device application
- list </a></li>
- <li><a href="#noupdate">I updated my app, but the updates don't seem to be showing up on
- the device</a></li>
- <li><a href="#layout_wilih">I'm getting a "Binary XML file line #2: You must supply a layout_wilih
- attribute" error when I start an application</a></li>
- <li><a href="#permission">My request to (<em>make a call, catch an incoming SMS, receive
- a notification, send an intent to an Android application</em>) is being
- ignored</a></li>
- <li><a href="#build">Help! My project won't build in Eclipse</a></li>
- <li><a href="#eclipse">Eclipse isn't talking to the emulator</a></li>
- <li><a href="#majorminor">When I go to preferences in Eclipse and select "Android", I get the following error message: Unsupported major.minor version 49.0.</a></li>
- <li><a href="#apidemosreinstall">I can't install ApiDemos apps in my IDE because of a signing error</a></li>
- <li><a href="#gesturebuilderinstall">I can't install the GestureBuilder sample
-app in the emulator</a></li>
- <li><a href="#signingcalendar">I can't compile my app because the build tools generated an expired debug certificate</a></li>
- <li><a href="#manifestfiles">Unable to view manifest files from within Eclipse</a></li>
-</ul>
-
-<a name="installeclipsecomponents" id="installeclipsecomponents"></a><h2>ADT Installation Error: "requires plug-in org.eclipse.wst.sse.ui".</h2>
-<p>
-The "Android Editors" feature of the ADT Plugin requires specific Eclipse components, such as WST. If you
-encounter this error message during ADT installation, you need to install the
-required Eclipse components and then try the ADT installation again. Follow the steps below to install the required components for the
-Android Editors feature, based on the version of Eclipse that you are using.</p>
-
-<table style="font-size:100%">
-<tr><th>Eclipse 3.3 (Europa)</th><th>Eclipse 3.4 (Ganymede)</th></tr>
-<tr>
-<td width="50%">
-<ol>
-<li>From the dialog where you select the <strong>Update sites to visit</strong>, select the checkboxes for both the
-ADT site, and the Callisto/Europa/Ganymede Discovery Site (you may want to
-check <strong>Automatically select mirrors</strong> at the bottom).</li>
-<li>Click <strong>Finish</strong>.</li>
-<li>In the <strong>Next</strong> dialog, select the Android Plugins.</li>
-<li>Now, expand the tree item of the discovery site. It seems that if you
-don't do it, it doesn't load the content of the discovery site.</li>
-<li>On the right, click <strong>Select required</strong>. This will select all the components
-that are required to install the Android plugin (wst, emf, etc...).</li>
-<li>Click <strong>Next</strong>, accept the agreement, click <strong>Install All</strong>, and restart Eclipse.</li>
-</ol>
-</td>
-<td>
-<ol>
- <li>Select <strong>Help</strong> > <strong>Software Updates...</strong></li>
- <li>Select the <strong>Installed Software</strong> tab.</li>
- <li>Click <strong>Update...</strong></li>
- <li>If an update for ADT is available, select it and click <strong>Finish</strong>.</li>
-</ol>
-</td>
-</tr>
-</table>
-
-
-</p>
-<a name="nodevice"></a><h2>ADB reports "no device" when an emulator is running</h2>
- <p>Try restarting adb by stopping it (<code>adb
- kill-server</code>) then any other adb command to restart it.</p>
-
-<a name="noapp"></a><h2>My new application/activity isn't showing up in the
- applications list </h2>
-<ul>
- <li>You often must restart your device or emulator before a new activity shows
- up in the applications list. This is particularly true when it is a completely
- new application with a new AndroidManifest.xml file.</li>
- <li>If this is for a new activity in an existing AndroidManifest.xml file, did
- you include an <code><activity></code> tag for your app (or a <code><service></code> tag
- for a service, or a <code><receiver></code> tag for a receiver, etc.)? </li>
- <li>Make sure that your AndroidManifest.xml file is valid. Errors in attribute
- values, such as the <em>value </em> attribute in <code><action <em>value</em>="<em><something></em>"></code>
- will often not be caught by compilers, but will prevent your application
- from being displayed because the intent filter will not be matched. Extra
- spaces or other characters can often sneak into these strings.</li>
- <li>Did you send your .apk file to the device (<a href="{@docRoot}guide/developing/tools/adb.html#move">adb install</a>)?</li>
- <li>Run logcat on your device (<code>adb logcat</code>)
- and then install your .apk file. Check the logcat output to see whether the
- application is being installed and recognized properly. Here's sample output
- from a successful installation:
-<pre>I/FileObserver( 414): *** onEvent wfd: 3 mask: 8 path: MyRSSReader.apk
-D/PackageManager( 414): Scanning package: /data/app/MyRSSReader.apk
-D/PackageManager( 414): Adding package com.example.codelab.rssexample
-D/PackageManager( 414): Registered content provider: my_rss_item, className = com.example.codelab.rssexample.RssContentProvider, isSyncable = false
-D/PackageManager( 414): Providers: com.example.codelab.rssexample.RssContentProvider
-D/PackageManager( 414): Activities: com.example.codelab.rssexample.MyRssReader com.example.codelab.rssexample.MyRssReader2 </pre>
- </li>
- <li>If logcat shows that the package manager is having problems loading the manifest
- file, force your manifest to be recompiled by adding a space in the file and
- compiling it.</li>
-</ul>
-<a name="noupdate"></a><h2>I updated my app, but the updates don't seem to be showing up on the device</h2>
- <p>Did you remember to send your .apk file to the device (<a href="{@docRoot}guide/developing/tools/adb.html#move">adb
- install</a>)?</p>
-
-<a name="layout_wilih"></a><h2>I'm getting a "Binary XML file line #2: You must supply a layout_wilih
- attribute" error
- when I start an application (but I declare a layout_wilih attribute <em>right
- there!!!</em>)</h2>
-<ul>
- <li>Make sure that the SDK you are building with is the same version as the Android
- OS that you are running on. </li>
- <li>Make sure that you're calling setContentView() early in your onCreate() method.
- Calling other methods, such as setListAdapter() before calling setContentView()
- can sometimes create odd errors when Android tries to access screen elements
- that haven't been set before.</li>
-</ul>
-<a name="permission"></a><h2>My request to (<em>make a call, catch an incoming SMS,
-receive a notification, send an intent to an Android application</em>) is being
-ignored</h2>
- <p>You might not have permission (or might not have requested permission) to
- call this activity or receive this intent. Many standard Android activities,
- such as making a call, have a permission assigned to it to prevent arbitrary
- applications from sending or receiving requests. See <a
- href="{@docRoot}guide/topics/security/security.html">Security and
- Permissions</a> for more information on permissions, and
- {@link android.Manifest.permission Manifest.permission} for a list of
- standard permissions supported by the Android platform.
-</p>
-<a name="build"></a><h2>Help! My project won't build in Eclipse</h2>
-<p>If your project doesn't build, you may notice symptoms such as new
-resources added in the <code>res/</code> sub-folders not showing up in the R class,
-the emulator not being started, not being able to run the application, or even seeming to run an old version of the application.</p>
-<p>To troubleshoot these types of problems, first try:</p>
-<ol>
- <li>Switch to the DDMS view in Eclipse (if you don't already have it open):
- <ol type="a">
- <li>From the menu select <code>Window > Open Perspective > Other</code></li>
- <li>Select DDMS from the list and hit OK</li>
- </ol>
- </li>
- <li>In the Devices panel (top right panel by default), click on the down triangle
- to bring up the panel menu</li>
- <li>Select <code>Reset ADB</code> from the menu, and then try running the
- application again</li>
-</ol>
-<p>If the above still doesn't work, you can try these steps:</p>
-<ol>
- <li>
- Check the console and problems tabs at the bottom of the Eclipse UI
- </li>
- <li>
- If there are problems listed in either place, they should give you a clue
- what is wrong
- </li>
- <li>
- If you aren't sure if the problems are fresh or stale, clear the console
- with a right click > Clear, then clean the project
- </li>
- <li>
- To clean the project (a good idea with any kind of build error), select
- Project > Clean from the eclipse main menu, then select the project you
- are working on (or clean all)
- </li>
-</ol>
-<a name="eclipse"></a><h2>Eclipse isn't talking to the emulator</h2>
-<p>When communication doesn't seem to be happening between Eclipse and the emulator, symptoms can include: nothing happening when you press run, the emulator hanging waiting
-for a debugger to connect, or errors that Eclipse reports about not being able
-to find the emulator or shell. By far the most common symptom is that when you press run, the emulator starts (or
-is already running), but the application doesn't start.</p>
-<p>
-You may find any of these steps will fix the problem and with practice you
-probably can figure out which one you need to do for your particular issue, but
-to start with, the safest option is to run through all of them in order:</p>
-<ol>
- <li>
- Quit the emulator if it is running
- </li>
- <li>
- Check that any emulator processes are killed (sometimes they can hang, use ps on unix or mac, or task manager in the process view on
- windows).
- </li>
- <li>
- Quit Eclipse
- </li>
- <li>
- From the command line, type:
-<pre>adb kill-server </pre>
- </li>
- <li>
- Start Eclipse and try again
- </li>
-</ol>
-
-<a name="majorminor"></a><h2>When I go to preferences in Eclipse and select "Android", I get the following error message: Unsupported major.minor version 49.0.</h2>
-<p>This error is displayed if you are using an older version of the JDK. Please make sure you are using JDK version 5 or 6.</p>
-
-<h2 id="apidemosreinstall">I can't install ApiDemos apps in my IDE because of a signing error</a></h2>
-
-<p>The Android system requires that all applications be signed, as described in
- <a href="{@docRoot}guide/publishing/app-signing.html">Signing Your Applications</a>. The ApiDemos
-applications included with the SDK are preinstalled on the emulator and for that reason have been
-compiled and signed with a private key.</p>
-
-If you want to modify or run one of the ApiDemos apps from Eclipse/ADT or other IDE, you can do so
-so only after you uninstall the <em>preinstalled</em> version of the app from the emulator. If
-you try to run an ApiDemos app from your IDE without removing the preinstalled version first,
-you will get errors similar to these: </p>
-
-<pre>[2008-08-13 15:14:15 - ApiDemos] Re-installation failed due to different application signatures.
-[2008-08-13 15:14:15 - ApiDemos] You must perform a full uninstall of the application. WARNING: ...This will remove the application data!
-[2008-08-13 15:14:15 - ApiDemos] Please execute 'adb uninstall com.android.samples' in a shell.</pre>
-
-<p>The error occurs because, in this case, you are attempting to install another copy of ApiDemos
-onto the emulator, a copy that is signed with a different certificate. (The Android IDE tools will
-have signed the app with a debug certificate, where the existing version was already signed with
-a private certificate.) The system does not allow this type of reinstallation. </p>
-
-<p>To resolve the issue, you need to fully uninstall the preinstalled and then reinstall it using
-the adb tool. Here's how to do that:</p>
-
-<ol>
- <li>In a terminal, change to the tools directory of the SDK.</li>
- <li>If no emulator instance is running, start an emulator using using the command <code>emulator &</code>.</li>
- <li>Uninstall the preinstalled app using the command <code>adb uninstall com.android.samples</code>.</li>
- <li>Reinstall the app using the command <code>adb install <path to the ApiDemos.apk></code>. If you are
- working in Eclipse/ADT, you can just compile and run the app in the normal way. </li>
-</ol>
-
-<p>Note that if multiple emulator instances are running, you need to direct your uninstall/install
-commands to the emulator instance that you are targeting. To do that you can add the
-<code>-s <serialNumber></code> to the command, for example: </p>
-
-<pre>adb -s emulator-5556 install</pre>
-
-<p>For more information about adb, see the <a href="{@docRoot}guide/developing/tools/adb.html">Android Debug Bridge</a>
-documentation.</p>
-
-<h2 id="gesturebuilderinstall">I can't install the GestureBuilder sample
-app in the emulator</a></h2>
-
-<p>This is similar to the ApiDemos problem described above, except that
-you cannot fix it by uninstalling GestureBuilder from the emulator. The
-GestureBuilder app cannot be uninstalled because it is currently installed
-within the system files themselves.</p>
-
-<p><strong>Symptoms</strong></p>
-
-<ul><li><p>You cannot run GestureBuilder in the emulator:</p>
-
-<pre>[2009-12-10 14:57:19 - GestureBuilderActivity]Re-installation failed due to different application signatures.
-[2009-12-10 14:57:19 - GestureBuilderActivity]You must perform a full uninstall of the application. WARNING: This will remove the application data!
-[2009-12-10 14:57:19 - GestureBuilderActivity]Please execute 'adb uninstall com.android.gesture.builder' in a shell.</pre>
-</li>
-
-<li><p>Running <code>adb uninstall com.android.gesture.builder</code> fails:</p>
-<pre>$ adb uninstall com.android.gesture.builder
- Failure</pre>
-</li></ul>
-
-<p>For now, the work-around is to change the sample's package name
-so that the system can install it as a new app rather than as a
-replacement for the existing GestureBuilder app. To change the
-package name, open the manifest file and modify the package attribute
-of the manifest element. Next, update imports and other references to
-the package name, rebuild the app, and run it in an AVD.</p>
-
-<p>For example, here's how you could do this in Eclipse:</p>
-
-<ol>
- <li>Right-click on the package name
-(<code>src/com.android.gesture.builder</code>).</li>
- <li>Select <strong>Refactor > Rename</strong> and change the name, for example to
-<code>com.android.gestureNEW.builder</code>. </li>
- <li>Open the manifest file. Inside the <code><manifest></code>
-tag, change the package name to
-<code>com.android.gestureNEW.builder</code>.</li>
- <li>Open each of the two Activity files and do Ctrl-Shift-O to add
-missing import packages, then save each file.</li>
-<li>Run the GestureBuilder application on the emulator.</li>
-</ol>
-
-<p>If you get an error message such as "Could not load /sdcard/gestures.
-Make sure you have a mounted SD card," be sure that your target AVD has an
-SD card. To create an AVD that has an SD card, use the
-<a href="{@docRoot}guide/developing/tools/avd.html#options"><code>-c</code>
-option</a> in the <code>android create avd</code> command.</p>
-
-<h2 id="signingcalendar">I can't compile my app because the build tools generated an expired debug certificate</h2>
-
-<p>If your development machine uses a locale that has a non-Gregorian calendar, you may encounter problems when first trying to compile and run your application. Specifically, you may find that the Android build tools won't compile your application because the debug key is expired. </p>
-
-<p>The problem occurs because the Keytool utility — included in the JDK and used by the Android build tools — fails to properly handle non-Gregorian locales and may create validity dates that are in the past. That is, it may generate a debug key that is already expired, which results in the compile error.</p>
-
-<p>If you encounter this problem, follow these steps to work around it: </p>
-
-<ol>
-<li>First, delete the debug keystore/key already generated by the Android build tools. Specifically, delete the <code>debug.keystore</code> file. On Linux/Mac OSX, the file is stored in <code>~/.android</code>. On Windows XP, the file is stored in <code>
-C:\Documents and Settings\<user>\.android</code>. On Windows Vista, the file is stored in <code>
-C:\Users\<user>\.android</code></li>
-<li>Next, you can either
-<ul>
-<li>Temporarily change your development machine's locale (date and time) to one that uses a Gregorian calendar, for example, United States. Once the locale is changed, use the Android build tools to compile and install your app. The build tools will regenerate a new keystore and debug key with valid dates. Once the new debug key is generated, you can reset your development machine to the original locale. </li>
-<li>Alternatively, if you do not want to change your machine's locale settings, you can generate the keystore/key on any machine using the Gregorian calendar, then copy the <code>debug.keystore</code> file from that computer to the proper location on your development machine. </li>
-</ul>
-</li>
-</ol>
-
-<p>This problem has been verified on Windows and may apply to other platforms. </p>
-
-<p>For general information about signing Android applications, see
-<a href="{@docRoot}guide/publishing/app-signing.html">Signing Your Applications</a>. </p>
-
-<h2 id="manifestfiles">Unable to view manifest files from within
-Eclipse</a></h2>
-
-<p>When you try to open an application's manifest file from within
-Eclipse, you might get an error such as this one:</p>
-<pre>An error has occurred. See error log for more details.
-org.eclipse.wst.sse.ui.StructuredTextEditor.isBlockSelectionModeEnabled()Z</pre>
-
-<p>Try reverting to the 3.0 version of the Eclipse XML Editors and
-Tools. If this does not work, remove the 3.1 version of the tool. To do
-this in Eclipse 3.4:</p>
-
-<ol>
- <li>Select <strong>Help > Software Updates...</strong></li>
- <li>Select the <strong>Installed Software</strong> tab.</li>
- <li>Select <strong>Eclipse XML Editors and Tools</strong>.</li>
- <li>Click <strong>Uninstall</strong>.</li>
- <li>Click <strong>Finish</strong>.</li>
-</ol>
-
-<p>When you restart Eclipse, you should be able to view the manifest
-files. </p>
+<p>You should have already been redirected by your browser. Please follow
+<a href="{@docRoot}resources/faq/troubleshooting.html">this link</a>.</p>
\ No newline at end of file
diff --git a/docs/html/guide/developing/device.jd b/docs/html/guide/developing/device.jd
index abfae5d..3127e10 100644
--- a/docs/html/guide/developing/device.jd
+++ b/docs/html/guide/developing/device.jd
@@ -119,7 +119,7 @@
<table>
<tr>
- <th>Manufacturer</th><th>USB Vendor ID</th></tr>
+ <th>Company</th><th>USB Vendor ID</th></tr>
<tr>
<td>Acer</td>
<td><code>0502</code></td></tr>
@@ -133,6 +133,9 @@
<td>Garmin-Asus</td>
<td><code>091E</code></td></tr>
<tr>
+ <td>Google</td>
+ <td><code>18d1</code></td></tr>
+ <tr>
<td>HTC</td>
<td><code>0bb4</code></td></tr>
<tr>
diff --git a/docs/html/guide/developing/index.jd b/docs/html/guide/developing/index.jd
index 3a64dbc..4257bf0 100644
--- a/docs/html/guide/developing/index.jd
+++ b/docs/html/guide/developing/index.jd
@@ -23,7 +23,7 @@
before continuing.</p>
</li>
- <li>Set up Android Virtual Devices or hardware devices</a>.
+ <li>Set up Android Virtual Devices or hardware devices.
<p>You need to create Android Virtual Devices (AVD) or connect hardware devices on which
you will install your applications.</p>
@@ -66,8 +66,8 @@
run tests within an emulator or device.</p>
</li>
</ol>
-
- <h2 id="EssentialTools">Essential command line tools</h2>
+
+<h2 id="EssentialTools">Essential command line tools</h2>
<p>When developing in IDEs or editors other than Eclipse, be familiar with
all of the tools below, because you will have to run them from the command line.</p>
@@ -112,6 +112,43 @@
Eclipse, such as the <code>adb</code> shell commands. You might also need to call Keytool and Jarsigner to
sign your applications, but you can set up Eclipse to do this automatically as well.</p>
- <p>For more information on the tools provided with the Android SDK, see the
+<p>For more information on the tools provided with the Android SDK, see the
<a href="{@docRoot}guide/developing/tools/index.html">Tools</a> section of the documentation.</p>
+
+<h2 id="ThirdParty">Third-Party Development Tools</h2>
+<p>
+ The tools described in this section are not developed by the Android SDK team. The Android Dev Guide
+ does not provide documentation for these tools. Please refer to the linked documents in each
+ section for documentation.
+</p>
+<h3 id="IntelliJ">Developing in IntelliJ IDEA</h3>
+<div style="float: right">
+<img alt="The IntelliJ graphical user interface" height="500px" src="{@docRoot}images/developing/intellijidea_android_ide.png"/>
+</div>
+<p>
+ IntelliJ IDEA is a powerful Java IDE from JetBrains that provides
+ full-cycle Android development support in both the free Community
+ Edition and the Ultimate edition.
+</p>
+<p>
+ The IDE ensures compatibility with the latest Android SDK and offers a
+ smart code editor with completion, quick navigation between code and
+ resources, a graphical debugger, unit testing support using Android
+ Testing Framework, and the ability to run applications in either the
+ emulator or a USB-connected device.
+</p>
+<p>
+ <strong>Links:</strong>
+</p>
+<ul>
+ <li>
+ <a href="http://www.jetbrains.com/idea">IntelliJ IDEA official website</a>
+</li>
+ <li>
+ <a href="http://www.jetbrains.com/idea/features/google_android.html">Android support in IntelliJ IDEA</a>
+</li>
+ <li>
+ <a href="http://wiki.jetbrains.net/intellij/Android">IntelliJ IDEA Android Tutorials</a>
+ </li>
+</ul>
diff --git a/docs/html/guide/developing/tools/monkeyrunner_concepts.jd b/docs/html/guide/developing/tools/monkeyrunner_concepts.jd
index 97c7c1f..c0795d7 100644
--- a/docs/html/guide/developing/tools/monkeyrunner_concepts.jd
+++ b/docs/html/guide/developing/tools/monkeyrunner_concepts.jd
@@ -128,7 +128,7 @@
device.press('KEYCODE_MENU','DOWN_AND_UP')
# Takes a screenshot
-result = device.takeSnapShot()
+result = device.takeSnapshot()
# Writes the screenshot to a file
result.writeToFile('myproject/shot1.png','png')
diff --git a/docs/html/guide/publishing/app-signing.jd b/docs/html/guide/publishing/app-signing.jd
index 93077a0..df240e2 100644
--- a/docs/html/guide/publishing/app-signing.jd
+++ b/docs/html/guide/publishing/app-signing.jd
@@ -260,8 +260,8 @@
<p>To fix this problem, simply delete the <code>debug.keystore</code> file.
The default storage location for AVDs is in <code>~/.android/</code> on OS X and Linux,
-in <code>C:\Documents and Settings\<user>\.android\</code> on Windows XP, and in
-<code>C:\Users\<user>\.android\</code> on Windows Vista.</p>
+in <code>C:\Documents and Settings\<user>\.android\</code> on Windows XP, and in
+<code>C:\Users\<user>\.android\</code> on Windows Vista and Windows 7.</p>
<p>The next time you build, the build tools will regenerate a new keystore and debug key.</p>
diff --git a/docs/html/guide/publishing/publishing.jd b/docs/html/guide/publishing/publishing.jd
index dd1115d..0cbba53 100644
--- a/docs/html/guide/publishing/publishing.jd
+++ b/docs/html/guide/publishing/publishing.jd
@@ -259,16 +259,17 @@
</p>
<p>The <code><query></code> is a placeholder for the search query to execute in Android
-Market. The query can be a raw text string or you can include parameters that perform a search
-based on the publisher name or application package name:</p>
+Market. The query can be a raw text string or you can include a parameter that performs a search
+based on the publisher name:</p>
<ul>
- <li>To search based on the publisher name, use the {@code pub:} parameter:
+ <li>To perform a raw text search, append the query string:
+ <p><code><URI_prefix><b>search?q=</b><search_query></code></p></li>
+
+ <li>To search based on the publisher name, use the {@code pub:} parameter in the query, followed
+by the publisher name:
<p><code><URI_prefix><b>search?q=pub:</b><publisher_name></code></p>
<p>You can use this type of search to show all of your published applications.</p></li>
-
- <li>To search based on the package name, use the {@code pname:} parameter:
- <p><code><URI_prefix><b>search?q=pname:</b><package_name></code></p></li>
</ul>
@@ -279,7 +280,7 @@
<p style="margin-left:2em"><code>market://search?q=<query></code></p>
-<p>The query may include the {@code pub:} or {@code pname:} parameters described above.</p>
+<p>The query may include the {@code pub:} parameter described above.</p>
<p>For example, here's how you can initiate a search in the Android Market application, based on the
publisher name:</p>
@@ -290,6 +291,9 @@
startActivity(intent);
</pre>
+<p>The search result shows all applications published by the publisher and which are compatible with
+the current device.</p>
+
<h4>Searching the Android Market web site</h4>
@@ -300,7 +304,7 @@
<code>http://market.android.com/search?q=<query></code>
</p>
-<p>The query may include the {@code pub:} or {@code pname:} parameters described above.</p>
+<p>The query may include the {@code pub:} parameter described above.</p>
<p>For example, here's a link that initiates a search on the Android Market web site, based on the
publisher name:</p>
@@ -309,6 +313,8 @@
<a href="http://market.android.com/search?q=pub:Your Publisher Name">Search Link</a>
</pre>
+<p>The search result shows all applications published by the publisher.</p>
+
<h3 id="UriSummary">Summary of URI formats</h3>
@@ -341,11 +347,5 @@
<td><nobr><code>market://search?q=pub:<publisher_name></code></nobr></td>
</tr>
-<tr>
-<td>Search for an application by its fully qualified package name</td>
-<td><code>http://market.android.com/search?q=pname:<package_name></code></td>
-<td><code>market://search?q=pname:<package_name></code></td>
-</tr>
-
</table>
diff --git a/docs/html/guide/topics/resources/menu-resource.jd b/docs/html/guide/topics/resources/menu-resource.jd
index d09790b..5c1eed0 100644
--- a/docs/html/guide/topics/resources/menu-resource.jd
+++ b/docs/html/guide/topics/resources/menu-resource.jd
@@ -250,7 +250,7 @@
android:icon="@drawable/group_item1_icon" />
<item android:id="@+id/group_item2"
android:onClick="onGroupItemClick"
- android:title="G@string/group_item2"
+ android:title="@string/group_item2"
android:icon="@drawable/group_item2_icon" />
</group>
<item android:id="@+id/submenu"
diff --git a/docs/html/guide/topics/wireless/bluetooth.jd b/docs/html/guide/topics/wireless/bluetooth.jd
index b3c76871..ae078b9 100644
--- a/docs/html/guide/topics/wireless/bluetooth.jd
+++ b/docs/html/guide/topics/wireless/bluetooth.jd
@@ -554,7 +554,7 @@
BluetoothServerSocket tmp = null;
try {
// MY_UUID is the app's UUID string, also used by the client code
- tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
+ tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
} catch (IOException e) { }
mmServerSocket = tmp;
}
@@ -690,7 +690,7 @@
public void run() {
// Cancel discovery because it will slow down the connection
- mAdapter.cancelDiscovery();
+ mBluetoothAdapter.cancelDiscovery();
try {
// Connect the device through the socket. This will block
diff --git a/docs/html/images/avd-manager.png b/docs/html/images/avd-manager.png
index 69ce972..c33d8a8 100644
--- a/docs/html/images/avd-manager.png
+++ b/docs/html/images/avd-manager.png
Binary files differ
diff --git a/docs/html/images/billing_package.png b/docs/html/images/billing_package.png
old mode 100755
new mode 100644
index ec04c2d..951e117
--- a/docs/html/images/billing_package.png
+++ b/docs/html/images/billing_package.png
Binary files differ
diff --git a/docs/html/images/developing/adt-props-isLib.png b/docs/html/images/developing/adt-props-isLib.png
index 18bdb33..49c9111 100644
--- a/docs/html/images/developing/adt-props-isLib.png
+++ b/docs/html/images/developing/adt-props-isLib.png
Binary files differ
diff --git a/docs/html/images/developing/adt-props-libRef.png b/docs/html/images/developing/adt-props-libRef.png
index e61df51..73bccbd0 100644
--- a/docs/html/images/developing/adt-props-libRef.png
+++ b/docs/html/images/developing/adt-props-libRef.png
Binary files differ
diff --git a/docs/html/images/developing/intellijidea_android_ide.png b/docs/html/images/developing/intellijidea_android_ide.png
new file mode 100644
index 0000000..b73a4e9
--- /dev/null
+++ b/docs/html/images/developing/intellijidea_android_ide.png
Binary files differ
diff --git a/docs/html/images/licensing_add_library.png b/docs/html/images/licensing_add_library.png
index 90b4435..3bbe6d5 100644
--- a/docs/html/images/licensing_add_library.png
+++ b/docs/html/images/licensing_add_library.png
Binary files differ
diff --git a/docs/html/images/licensing_gapis_8.png b/docs/html/images/licensing_gapis_8.png
index 43ad262..480d989 100644
--- a/docs/html/images/licensing_gapis_8.png
+++ b/docs/html/images/licensing_gapis_8.png
Binary files differ
diff --git a/docs/html/images/licensing_package.png b/docs/html/images/licensing_package.png
index 5da5632..eb2c5cf 100644
--- a/docs/html/images/licensing_package.png
+++ b/docs/html/images/licensing_package.png
Binary files differ
diff --git a/docs/html/resources/faq/commontasks.jd b/docs/html/resources/faq/commontasks.jd
index a5f5177..b211db0 100644
--- a/docs/html/resources/faq/commontasks.jd
+++ b/docs/html/resources/faq/commontasks.jd
@@ -223,7 +223,7 @@
// Listen for results.
protected void onActivityResult(int requestCode, int resultCode, Intent data){
// See which child activity is calling us back.
- switch (resultCode) {
+ switch (requestCode) {
case CHOOSE_FIGHTER:
// This is the standard resultCode that is sent back if the
// activity crashed or didn't doesn't supply an explicit result.
@@ -257,7 +257,7 @@
stats.putString("height","6\'2\"");
stats.putString("weight", "190 lbs");
stats.putString("reach", "73\"");
- setResult(RESULT_OK, "Washington", Bundle);
+ setResult(RESULT_OK, "Washington", stats);
finish();
}
};
@@ -289,7 +289,12 @@
will have a title bar visible to the user until <code>onCreate</code> runs.</p>
<p>(Note that this can be applied to either the <code><application></code>
tag or to individual <code><activity></code> tags.)</p>
-<a name="localhostalias" id="localhostalias"></a><h2>Referring to localhost from the emulated environment</h2>
+<p class="caution"><strong>Caution:</strong> This theme will also hide the Action Bar on Android
+3.0 and higher. If you want to keep the Action Bar, but hide the title bar, see how you can <a
+href="{@docRoot}guide/topics/ui/themes.html#SelectATheme">select a theme based on platform
+version</a>.</p>
+<a name="localhostalias" id="localhostalias"></a><h2>Referring to localhost from the emulated
+environment</h2>
<p>
If you need to refer to your host computer's <em>localhost</em>, such as when you
want the emulator client to contact a server running on the same host, use the alias
diff --git a/docs/html/resources/tutorials/hello-world.jd b/docs/html/resources/tutorials/hello-world.jd
index 020c738..b11770f 100644
--- a/docs/html/resources/tutorials/hello-world.jd
+++ b/docs/html/resources/tutorials/hello-world.jd
@@ -433,7 +433,7 @@
</pre>
</li>
-<li>Now open and modify your <code>HelloAndroid</code> class use the
+<li>Now open and modify your <code>HelloAndroid</code> class and use the
XML layout. Edit the file to look like this:
<pre>
package com.example.helloandroid;
diff --git a/docs/html/sdk/eclipse-adt.jd b/docs/html/sdk/eclipse-adt.jd
index 3a7b39f..97717feb 100644
--- a/docs/html/sdk/eclipse-adt.jd
+++ b/docs/html/sdk/eclipse-adt.jd
@@ -594,13 +594,14 @@
<p>ADT is a plugin for the Eclipse IDE. Before you can install or use ADT,
you must have a compatible version of Eclipse installed on your development
-computer. </p>
+computer. Check the <a
+href="requirements.html">System Requirements</a> document for
+a list of Eclipse versions that are compatible with the Android SDK.</li></p>
<ul>
<li>If Eclipse is already installed on your computer, make sure that it is
-a version that is compatible with ADT and the Android SDK. Check the <a
-href="requirements.html">System Requirements</a> document for
-a list of Eclipse versions that are compatible with the Android SDK.</li>
+a version that is compatible with ADT and the Android SDK.
+
<li>If you need to install or update Eclipse, you can download it from this
location:
@@ -608,7 +609,7 @@
"http://www.eclipse.org/downloads/">http://www.eclipse.org/downloads/</a>
</p>
-<p>For Eclipse 3.5 or newer, the "Eclipse Classic" version is recommended. Otherwise, a Java or RCP
+<p>The "Eclipse Classic" version is recommended. Otherwise, a Java or RCP
version of Eclipse is recommended.</p></li>
</ul>
@@ -624,19 +625,15 @@
<h3 id="downloading">Downloading the ADT Plugin</h3>
-<p>Use Update Manager feature of your Eclipse installation to install the latest
+<p>Use the Update Manager feature of your Eclipse installation to install the latest
revision of ADT on your development computer.<p>
<p>Assuming that you have a compatible version of the Eclipse IDE installed, as
described in <a href="#preparing">Preparing for Installation</a>, above, follow
these steps to download the ADT plugin and install it in your Eclipse
-environment. </p>
+environment.</p>
-<table style="font-size:100%">
-<tr><th>Eclipse 3.5 (Galileo) and 3.6 (Helios)</th><th>Eclipse 3.4 (Ganymede)</th></tr>
-<tr>
-<td width="45%">
-<!-- 3.5+ steps -->
+
<ol>
<li>Start Eclipse, then select <strong>Help</strong> > <strong>Install New
Software...</strong>.</li>
@@ -655,35 +652,6 @@
<li>When the installation completes, restart Eclipse. </li>
</ol>
-</td>
-<td width="50%">
-
-<!-- 3.4 steps -->
-<ol>
- <li>Start Eclipse, then select <strong>Help</strong> > <strong>Software Updates...</strong>.
-In the dialog that appears, click the <strong>Available Software</strong> tab.</li>
- <li>Click <strong>Add Site</strong>.</li>
- <li>In the Add Site dialog that appears, enter this URL in the "Location" field:
- <pre>https://dl-ssl.google.com/android/eclipse/</pre>
- <p>Note: If you have trouble acquiring the plugin, you can try
- using "http" in the URL, instead of "https" (https is preferred for
- security reasons).</p>
- <p>Click <strong>OK</strong>.</p>
- </li>
- <li>Back in the Available Software view, you should see the plugin listed by the URL,
- with "Developer Tools" nested within it. Select the checkbox next to Developer Tools,
- which will automatically select the nested tools. Then click
- <strong>Install</strong></li>
- <li>On the subsequent Install window, all of the included tools
- should be checked. Click <strong>Next</strong>. </li>
- <li>Read and accept the license agreements, then click <strong>Finish</strong>.</li>
- <li>When the installation completes, restart Eclipse. </li>
-
-</ol>
-</td>
-</tr>
-</table>
-
<h3 id="configuring">Configuring the ADT Plugin</h3>
<p>Once you've successfully downloaded ADT as described above, the next step
@@ -807,11 +775,6 @@
<p>Follow the steps below to check whether an update is available and, if so,
to install it. </p>
-<table style="font-size:100%">
-<tr><th>Eclipse 3.5 (Galileo) and 3.6 (Helios)</th><th>Eclipse 3.4 (Ganymede)</th></tr>
-<tr>
-<td>
-<!-- 3.5+ steps -->
<ol>
<li>Select <strong>Help</strong> > <strong>Check for Updates</strong>.
<p>If there are no updates available, a dialog will say so and you're done.</p></li>
@@ -823,25 +786,6 @@
Android Development Tools.</li>
<li>Restart Eclipse.</li>
</ol>
-</td>
-
-<td width="50%">
-<!-- 3.4 steps -->
-<ol>
- <li>Select <strong>Help</strong> > <strong>Software Updates</strong>.</li>
- <li>Select the <strong>Available Software</strong> tab.</li>
- <li>If there are updates available, select Android DDMS, Android Development Tools,
- and Android Hierarchy Viewer, then click <strong>Update</strong>.</li>
- <li>In the resulting Available Updates dialog, ensure that each of the listed tools
- are selected, then click <strong>Next</strong>.</li>
- <li>Read and accept the license agreement and then click <strong>Finish</strong>.
- This will download and install the latest version of Android DDMS and
- Android Development Tools.</li>
- <li>Restart Eclipse.</li>
-</ol>
-</td>
-</tr>
-</table>
<p>If you encounter problems during the update, remove the existing ADT plugin from Eclipse, then
diff --git a/docs/html/sdk/installing.jd b/docs/html/sdk/installing.jd
index b0fd761..a1080c2 100644
--- a/docs/html/sdk/installing.jd
+++ b/docs/html/sdk/installing.jd
@@ -96,13 +96,14 @@
<p>If you will be developing in Eclipse with the Android Development
Tools (ADT) Plugin—the recommended path if you are new to
Android—make sure that you have a suitable version of Eclipse
-installed on your computer (3.4 or newer is recommended). If you need
-to install Eclipse, you can download it from this location: </p>
+installed on your computer as described in the
+<a href="requirements.html">System Requirements</a> document.
+If you need to install Eclipse, you can download it from this location: </p>
<p style="margin-left:2em;"><a href=
"http://www.eclipse.org/downloads/">http://www.eclipse.org/downloads/</a></p>
-<p>For Eclipse 3.5 or newer, the "Eclipse Classic" version is recommended. Otherwise, a Java or
+<p>The "Eclipse Classic" version is recommended. Otherwise, a Java or
RCP version of Eclipse is recommended.</p>
diff --git a/docs/html/sdk/requirements.jd b/docs/html/sdk/requirements.jd
index 3d62dd9..f12d0aa 100644
--- a/docs/html/sdk/requirements.jd
+++ b/docs/html/sdk/requirements.jd
@@ -24,7 +24,9 @@
<h4 style="margin-top:.25em"><em>Eclipse IDE</em></h4>
<ul>
- <li>Eclipse 3.4 (Ganymede) or greater</li>
+ <li>Eclipse 3.5 (Galileo) or greater
+<p class="note"><strong>Note:</strong> Eclipse 3.4 (Ganymede) is no longer
+supported with the latest version of ADT.</p></li>
<li>Eclipse <a href="http://www.eclipse.org/jdt">JDT</a> plugin (included
in most Eclipse IDE packages) </li>
<li>If you need to install or update Eclipse, you can download it from <a
diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp
index ddbd220..e2bfb16 100644
--- a/drm/common/IDrmManagerService.cpp
+++ b/drm/common/IDrmManagerService.cpp
@@ -596,7 +596,7 @@
handle->decryptInfo->decryptBufferLength = reply.readInt32();
}
} else {
- LOGE("no decryptHandle is generated in service side");
+ LOGV("no decryptHandle is generated in service side");
}
return handle;
}
@@ -621,11 +621,6 @@
remote()->transact(CLOSE_DECRYPT_SESSION, data, &reply);
- if (NULL != decryptHandle->decryptInfo) {
- LOGV("deleting decryptInfo");
- delete decryptHandle->decryptInfo; decryptHandle->decryptInfo = NULL;
- }
- delete decryptHandle; decryptHandle = NULL;
return reply.readInt32();
}
@@ -1308,7 +1303,7 @@
delete handle->decryptInfo; handle->decryptInfo = NULL;
}
} else {
- LOGE("NULL decryptHandle is returned");
+ LOGV("NULL decryptHandle is returned");
}
delete handle; handle = NULL;
return DRM_NO_ERROR;
diff --git a/drm/drmserver/DrmManager.cpp b/drm/drmserver/DrmManager.cpp
index ec400b7..305bafc 100644
--- a/drm/drmserver/DrmManager.cpp
+++ b/drm/drmserver/DrmManager.cpp
@@ -51,6 +51,7 @@
}
int DrmManager::addUniqueId(int uniqueId) {
+ Mutex::Autolock _l(mLock);
if (0 == uniqueId) {
int temp = 0;
bool foundUniqueId = false;
@@ -78,6 +79,7 @@
}
void DrmManager::removeUniqueId(int uniqueId) {
+ Mutex::Autolock _l(mLock);
for (unsigned int i = 0; i < mUniqueIdVector.size(); i++) {
if (uniqueId == mUniqueIdVector.itemAt(i)) {
mUniqueIdVector.removeAt(i);
@@ -107,6 +109,7 @@
}
status_t DrmManager::unloadPlugIns() {
+ Mutex::Autolock _l(mLock);
mConvertSessionMap.clear();
mDecryptSessionMap.clear();
mPlugInManager.unloadPlugIns();
@@ -126,6 +129,7 @@
}
void DrmManager::addClient(int uniqueId) {
+ Mutex::Autolock _l(mLock);
if (!mSupportInfoToPlugInIdMap.isEmpty()) {
Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
for (unsigned int index = 0; index < plugInIdList.size(); index++) {
@@ -137,6 +141,7 @@
}
void DrmManager::removeClient(int uniqueId) {
+ Mutex::Autolock _l(mLock);
Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
for (unsigned int index = 0; index < plugInIdList.size(); index++) {
IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
@@ -145,6 +150,7 @@
}
DrmConstraints* DrmManager::getConstraints(int uniqueId, const String8* path, const int action) {
+ Mutex::Autolock _l(mLock);
const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path);
if (EMPTY_STRING != plugInId) {
IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
@@ -154,6 +160,7 @@
}
DrmMetadata* DrmManager::getMetadata(int uniqueId, const String8* path) {
+ Mutex::Autolock _l(mLock);
const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path);
if (EMPTY_STRING != plugInId) {
IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
@@ -163,6 +170,7 @@
}
status_t DrmManager::installDrmEngine(int uniqueId, const String8& absolutePath) {
+ Mutex::Autolock _l(mLock);
mPlugInManager.loadPlugIn(absolutePath);
IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(absolutePath);
@@ -176,6 +184,7 @@
}
bool DrmManager::canHandle(int uniqueId, const String8& path, const String8& mimeType) {
+ Mutex::Autolock _l(mLock);
const String8 plugInId = getSupportedPlugInId(mimeType);
bool result = (EMPTY_STRING != plugInId) ? true : false;
@@ -194,6 +203,7 @@
}
DrmInfoStatus* DrmManager::processDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
+ Mutex::Autolock _l(mLock);
const String8 plugInId = getSupportedPlugInId(drmInfo->getMimeType());
if (EMPTY_STRING != plugInId) {
IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
@@ -218,6 +228,7 @@
}
DrmInfo* DrmManager::acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
+ Mutex::Autolock _l(mLock);
const String8 plugInId = getSupportedPlugInId(drmInfoRequest->getMimeType());
if (EMPTY_STRING != plugInId) {
IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
@@ -228,6 +239,7 @@
status_t DrmManager::saveRights(int uniqueId, const DrmRights& drmRights,
const String8& rightsPath, const String8& contentPath) {
+ Mutex::Autolock _l(mLock);
const String8 plugInId = getSupportedPlugInId(drmRights.getMimeType());
status_t result = DRM_ERROR_UNKNOWN;
if (EMPTY_STRING != plugInId) {
@@ -238,6 +250,7 @@
}
String8 DrmManager::getOriginalMimeType(int uniqueId, const String8& path) {
+ Mutex::Autolock _l(mLock);
const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
if (EMPTY_STRING != plugInId) {
IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
@@ -247,6 +260,7 @@
}
int DrmManager::getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType) {
+ Mutex::Autolock _l(mLock);
const String8 plugInId = getSupportedPlugInId(uniqueId, path, mimeType);
if (EMPTY_STRING != plugInId) {
IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
@@ -256,6 +270,7 @@
}
int DrmManager::checkRightsStatus(int uniqueId, const String8& path, int action) {
+ Mutex::Autolock _l(mLock);
const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
if (EMPTY_STRING != plugInId) {
IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
@@ -267,6 +282,7 @@
status_t DrmManager::consumeRights(
int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
status_t result = DRM_ERROR_UNKNOWN;
+ Mutex::Autolock _l(mDecryptLock);
if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
result = drmEngine->consumeRights(uniqueId, decryptHandle, action, reserve);
@@ -277,6 +293,7 @@
status_t DrmManager::setPlaybackStatus(
int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) {
status_t result = DRM_ERROR_UNKNOWN;
+ Mutex::Autolock _l(mDecryptLock);
if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
result = drmEngine->setPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position);
@@ -286,6 +303,7 @@
bool DrmManager::validateAction(
int uniqueId, const String8& path, int action, const ActionDescription& description) {
+ Mutex::Autolock _l(mLock);
const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
if (EMPTY_STRING != plugInId) {
IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
@@ -295,6 +313,7 @@
}
status_t DrmManager::removeRights(int uniqueId, const String8& path) {
+ Mutex::Autolock _l(mLock);
const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
status_t result = DRM_ERROR_UNKNOWN;
if (EMPTY_STRING != plugInId) {
@@ -318,6 +337,7 @@
}
int DrmManager::openConvertSession(int uniqueId, const String8& mimeType) {
+ Mutex::Autolock _l(mConvertLock);
int convertId = -1;
const String8 plugInId = getSupportedPlugInId(mimeType);
@@ -325,7 +345,6 @@
IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
if (DRM_NO_ERROR == rDrmEngine.openConvertSession(uniqueId, mConvertId + 1)) {
- Mutex::Autolock _l(mConvertLock);
++mConvertId;
convertId = mConvertId;
mConvertSessionMap.add(convertId, &rDrmEngine);
@@ -338,6 +357,7 @@
int uniqueId, int convertId, const DrmBuffer* inputData) {
DrmConvertedStatus *drmConvertedStatus = NULL;
+ Mutex::Autolock _l(mConvertLock);
if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) {
IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId);
drmConvertedStatus = drmEngine->convertData(uniqueId, convertId, inputData);
@@ -346,6 +366,7 @@
}
DrmConvertedStatus* DrmManager::closeConvertSession(int uniqueId, int convertId) {
+ Mutex::Autolock _l(mConvertLock);
DrmConvertedStatus *drmConvertedStatus = NULL;
if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) {
@@ -358,6 +379,7 @@
status_t DrmManager::getAllSupportInfo(
int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray) {
+ Mutex::Autolock _l(mLock);
Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
int size = plugInPathList.size();
int validPlugins = 0;
@@ -437,7 +459,7 @@
}
if (DRM_NO_ERROR != result) {
delete handle; handle = NULL;
- LOGE("DrmManager::openDecryptSession: no capable plug-in found");
+ LOGV("DrmManager::openDecryptSession: no capable plug-in found");
}
return handle;
}
@@ -458,6 +480,7 @@
status_t DrmManager::initializeDecryptUnit(
int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
status_t result = DRM_ERROR_UNKNOWN;
+ Mutex::Autolock _l(mDecryptLock);
if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
result = drmEngine->initializeDecryptUnit(uniqueId, decryptHandle, decryptUnitId, headerInfo);
@@ -468,6 +491,8 @@
status_t DrmManager::decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
status_t result = DRM_ERROR_UNKNOWN;
+
+ Mutex::Autolock _l(mDecryptLock);
if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
result = drmEngine->decrypt(
@@ -479,6 +504,7 @@
status_t DrmManager::finalizeDecryptUnit(
int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
status_t result = DRM_ERROR_UNKNOWN;
+ Mutex::Autolock _l(mDecryptLock);
if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
result = drmEngine->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
@@ -490,6 +516,7 @@
void* buffer, ssize_t numBytes, off64_t offset) {
ssize_t result = DECRYPT_FILE_ERROR;
+ Mutex::Autolock _l(mDecryptLock);
if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
result = drmEngine->pread(uniqueId, decryptHandle, buffer, numBytes, offset);
diff --git a/drm/java/android/drm/DrmManagerClient.java b/drm/java/android/drm/DrmManagerClient.java
index c541456..782ffdb 100644
--- a/drm/java/android/drm/DrmManagerClient.java
+++ b/drm/java/android/drm/DrmManagerClient.java
@@ -735,6 +735,7 @@
* This method expects uri in the following format
* content://media/<table_name>/<row_index> (or)
* file://sdcard/test.mp4
+ * http://test.com/test.mp4
*
* Here <table_name> shall be "video" or "audio" or "images"
* <row_index> the index of the content in given table
@@ -746,6 +747,10 @@
if (null == scheme || scheme.equals("") ||
scheme.equals(ContentResolver.SCHEME_FILE)) {
path = uri.getPath();
+
+ } else if (scheme.equals("http")) {
+ path = uri.toString();
+
} else if (scheme.equals(ContentResolver.SCHEME_CONTENT)) {
String[] projection = new String[] {MediaStore.MediaColumns.DATA};
Cursor cursor = null;
diff --git a/drm/libdrmframework/DrmManagerClient.cpp b/drm/libdrmframework/DrmManagerClient.cpp
index 7b51822..3143d45 100644
--- a/drm/libdrmframework/DrmManagerClient.cpp
+++ b/drm/libdrmframework/DrmManagerClient.cpp
@@ -77,13 +77,14 @@
return mDrmManagerClientImpl->checkRightsStatus(mUniqueId, path, action);
}
-status_t DrmManagerClient::consumeRights(DecryptHandle* decryptHandle, int action, bool reserve) {
+status_t DrmManagerClient::consumeRights(
+ sp<DecryptHandle> &decryptHandle, int action, bool reserve) {
Mutex::Autolock _l(mDecryptLock);
return mDrmManagerClientImpl->consumeRights(mUniqueId, decryptHandle, action, reserve);
}
status_t DrmManagerClient::setPlaybackStatus(
- DecryptHandle* decryptHandle, int playbackStatus, int64_t position) {
+ sp<DecryptHandle> &decryptHandle, int playbackStatus, int64_t position) {
return mDrmManagerClientImpl
->setPlaybackStatus(mUniqueId, decryptHandle, playbackStatus, position);
}
@@ -117,40 +118,42 @@
return mDrmManagerClientImpl->getAllSupportInfo(mUniqueId, length, drmSupportInfoArray);
}
-DecryptHandle* DrmManagerClient::openDecryptSession(int fd, off64_t offset, off64_t length) {
+sp<DecryptHandle> DrmManagerClient::openDecryptSession(int fd, off64_t offset, off64_t length) {
return mDrmManagerClientImpl->openDecryptSession(mUniqueId, fd, offset, length);
}
-DecryptHandle* DrmManagerClient::openDecryptSession(const char* uri) {
+sp<DecryptHandle> DrmManagerClient::openDecryptSession(const char* uri) {
return mDrmManagerClientImpl->openDecryptSession(mUniqueId, uri);
}
-status_t DrmManagerClient::closeDecryptSession(DecryptHandle* decryptHandle) {
+status_t DrmManagerClient::closeDecryptSession(sp<DecryptHandle> &decryptHandle) {
return mDrmManagerClientImpl->closeDecryptSession(mUniqueId, decryptHandle);
}
status_t DrmManagerClient::initializeDecryptUnit(
- DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
+ sp<DecryptHandle> &decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
Mutex::Autolock _l(mDecryptLock);
return mDrmManagerClientImpl->initializeDecryptUnit(
mUniqueId, decryptHandle, decryptUnitId, headerInfo);
}
status_t DrmManagerClient::decrypt(
- DecryptHandle* decryptHandle, int decryptUnitId,
- const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
+ sp<DecryptHandle> &decryptHandle, int decryptUnitId,
+ const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
Mutex::Autolock _l(mDecryptLock);
return mDrmManagerClientImpl->decrypt(
mUniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
}
-status_t DrmManagerClient::finalizeDecryptUnit(DecryptHandle* decryptHandle, int decryptUnitId) {
+status_t DrmManagerClient::finalizeDecryptUnit(
+ sp<DecryptHandle> &decryptHandle, int decryptUnitId) {
Mutex::Autolock _l(mDecryptLock);
- return mDrmManagerClientImpl->finalizeDecryptUnit(mUniqueId, decryptHandle, decryptUnitId);
+ return mDrmManagerClientImpl->finalizeDecryptUnit(mUniqueId,
+ decryptHandle, decryptUnitId);
}
ssize_t DrmManagerClient::pread(
- DecryptHandle* decryptHandle, void* buffer, ssize_t numBytes, off64_t offset) {
+ sp<DecryptHandle> &decryptHandle, void* buffer, ssize_t numBytes, off64_t offset) {
Mutex::Autolock _l(mDecryptLock);
return mDrmManagerClientImpl->pread(mUniqueId, decryptHandle, buffer, numBytes, offset);
}
diff --git a/drm/libdrmframework/DrmManagerClientImpl.cpp b/drm/libdrmframework/DrmManagerClientImpl.cpp
index d20de92..e6ae220 100644
--- a/drm/libdrmframework/DrmManagerClientImpl.cpp
+++ b/drm/libdrmframework/DrmManagerClientImpl.cpp
@@ -78,14 +78,16 @@
}
status_t DrmManagerClientImpl::setOnInfoListener(
- int uniqueId, const sp<DrmManagerClient::OnInfoListener>& infoListener) {
+ int uniqueId,
+ const sp<DrmManagerClient::OnInfoListener>& infoListener) {
Mutex::Autolock _l(mLock);
mOnInfoListener = infoListener;
return getDrmManagerService()->setDrmServiceListener(uniqueId,
(NULL != infoListener.get()) ? this : NULL);
}
-status_t DrmManagerClientImpl::installDrmEngine(int uniqueId, const String8& drmEngineFile) {
+status_t DrmManagerClientImpl::installDrmEngine(
+ int uniqueId, const String8& drmEngineFile) {
status_t status = DRM_ERROR_UNKNOWN;
if (EMPTY_STRING != drmEngineFile) {
status = getDrmManagerService()->installDrmEngine(uniqueId, drmEngineFile);
@@ -97,7 +99,8 @@
int uniqueId, const String8* path, const int action) {
DrmConstraints *drmConstraints = NULL;
if ((NULL != path) && (EMPTY_STRING != *path)) {
- drmConstraints = getDrmManagerService()->getConstraints(uniqueId, path, action);
+ drmConstraints =
+ getDrmManagerService()->getConstraints(uniqueId, path, action);
}
return drmConstraints;
}
@@ -110,7 +113,8 @@
return drmMetadata;
}
-bool DrmManagerClientImpl::canHandle(int uniqueId, const String8& path, const String8& mimeType) {
+bool DrmManagerClientImpl::canHandle(
+ int uniqueId, const String8& path, const String8& mimeType) {
bool retCode = false;
if ((EMPTY_STRING != path) || (EMPTY_STRING != mimeType)) {
retCode = getDrmManagerService()->canHandle(uniqueId, path, mimeType);
@@ -118,7 +122,8 @@
return retCode;
}
-DrmInfoStatus* DrmManagerClientImpl::processDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
+DrmInfoStatus* DrmManagerClientImpl::processDrmInfo(
+ int uniqueId, const DrmInfo* drmInfo) {
DrmInfoStatus *drmInfoStatus = NULL;
if (NULL != drmInfo) {
drmInfoStatus = getDrmManagerService()->processDrmInfo(uniqueId, drmInfo);
@@ -126,7 +131,8 @@
return drmInfoStatus;
}
-DrmInfo* DrmManagerClientImpl::acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
+DrmInfo* DrmManagerClientImpl::acquireDrmInfo(
+ int uniqueId, const DrmInfoRequest* drmInfoRequest) {
DrmInfo* drmInfo = NULL;
if (NULL != drmInfoRequest) {
drmInfo = getDrmManagerService()->acquireDrmInfo(uniqueId, drmInfoRequest);
@@ -138,12 +144,14 @@
const String8& rightsPath, const String8& contentPath) {
status_t status = DRM_ERROR_UNKNOWN;
if (EMPTY_STRING != contentPath) {
- status = getDrmManagerService()->saveRights(uniqueId, drmRights, rightsPath, contentPath);
+ status = getDrmManagerService()->saveRights(
+ uniqueId, drmRights, rightsPath, contentPath);
}
return status;
}
-String8 DrmManagerClientImpl::getOriginalMimeType(int uniqueId, const String8& path) {
+String8 DrmManagerClientImpl::getOriginalMimeType(
+ int uniqueId, const String8& path) {
String8 mimeType = EMPTY_STRING;
if (EMPTY_STRING != path) {
mimeType = getDrmManagerService()->getOriginalMimeType(uniqueId, path);
@@ -155,7 +163,8 @@
int uniqueId, const String8& path, const String8& mimeType) {
int drmOjectType = DrmObjectType::UNKNOWN;
if ((EMPTY_STRING != path) || (EMPTY_STRING != mimeType)) {
- drmOjectType = getDrmManagerService()->getDrmObjectType(uniqueId, path, mimeType);
+ drmOjectType =
+ getDrmManagerService()->getDrmObjectType(uniqueId, path, mimeType);
}
return drmOjectType;
}
@@ -164,35 +173,41 @@
int uniqueId, const String8& path, int action) {
int rightsStatus = RightsStatus::RIGHTS_INVALID;
if (EMPTY_STRING != path) {
- rightsStatus = getDrmManagerService()->checkRightsStatus(uniqueId, path, action);
+ rightsStatus =
+ getDrmManagerService()->checkRightsStatus(uniqueId, path, action);
}
return rightsStatus;
}
status_t DrmManagerClientImpl::consumeRights(
- int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
+ int uniqueId, sp<DecryptHandle> &decryptHandle,
+ int action, bool reserve) {
status_t status = DRM_ERROR_UNKNOWN;
- if (NULL != decryptHandle) {
- status = getDrmManagerService()->consumeRights(uniqueId, decryptHandle, action, reserve);
+ if (NULL != decryptHandle.get()) {
+ status = getDrmManagerService()->consumeRights(
+ uniqueId, decryptHandle.get(), action, reserve);
}
return status;
}
status_t DrmManagerClientImpl::setPlaybackStatus(
- int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) {
+ int uniqueId, sp<DecryptHandle> &decryptHandle,
+ int playbackStatus, int64_t position) {
status_t status = DRM_ERROR_UNKNOWN;
- if (NULL != decryptHandle) {
+ if (NULL != decryptHandle.get()) {
status = getDrmManagerService()->setPlaybackStatus(
- uniqueId, decryptHandle, playbackStatus, position);
+ uniqueId, decryptHandle.get(), playbackStatus, position);
}
return status;
}
bool DrmManagerClientImpl::validateAction(
- int uniqueId, const String8& path, int action, const ActionDescription& description) {
+ int uniqueId, const String8& path,
+ int action, const ActionDescription& description) {
bool retCode = false;
if (EMPTY_STRING != path) {
- retCode = getDrmManagerService()->validateAction(uniqueId, path, action, description);
+ retCode = getDrmManagerService()->validateAction(
+ uniqueId, path, action, description);
}
return retCode;
}
@@ -209,7 +224,8 @@
return getDrmManagerService()->removeAllRights(uniqueId);
}
-int DrmManagerClientImpl::openConvertSession(int uniqueId, const String8& mimeType) {
+int DrmManagerClientImpl::openConvertSession(
+ int uniqueId, const String8& mimeType) {
int retCode = INVALID_VALUE;
if (EMPTY_STRING != mimeType) {
retCode = getDrmManagerService()->openConvertSession(uniqueId, mimeType);
@@ -221,12 +237,14 @@
int uniqueId, int convertId, const DrmBuffer* inputData) {
DrmConvertedStatus* drmConvertedStatus = NULL;
if (NULL != inputData) {
- drmConvertedStatus = getDrmManagerService()->convertData(uniqueId, convertId, inputData);
+ drmConvertedStatus =
+ getDrmManagerService()->convertData(uniqueId, convertId, inputData);
}
return drmConvertedStatus;
}
-DrmConvertedStatus* DrmManagerClientImpl::closeConvertSession(int uniqueId, int convertId) {
+DrmConvertedStatus* DrmManagerClientImpl::closeConvertSession(
+ int uniqueId, int convertId) {
return getDrmManagerService()->closeConvertSession(uniqueId, convertId);
}
@@ -234,17 +252,19 @@
int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray) {
status_t status = DRM_ERROR_UNKNOWN;
if ((NULL != drmSupportInfoArray) && (NULL != length)) {
- status = getDrmManagerService()->getAllSupportInfo(uniqueId, length, drmSupportInfoArray);
+ status = getDrmManagerService()->getAllSupportInfo(
+ uniqueId, length, drmSupportInfoArray);
}
return status;
}
-DecryptHandle* DrmManagerClientImpl::openDecryptSession(
+sp<DecryptHandle> DrmManagerClientImpl::openDecryptSession(
int uniqueId, int fd, off64_t offset, off64_t length) {
return getDrmManagerService()->openDecryptSession(uniqueId, fd, offset, length);
}
-DecryptHandle* DrmManagerClientImpl::openDecryptSession(int uniqueId, const char* uri) {
+sp<DecryptHandle> DrmManagerClientImpl::openDecryptSession(
+ int uniqueId, const char* uri) {
DecryptHandle* handle = NULL;
if (NULL != uri) {
handle = getDrmManagerService()->openDecryptSession(uniqueId, uri);
@@ -252,50 +272,57 @@
return handle;
}
-status_t DrmManagerClientImpl::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
+status_t DrmManagerClientImpl::closeDecryptSession(
+ int uniqueId, sp<DecryptHandle> &decryptHandle) {
status_t status = DRM_ERROR_UNKNOWN;
- if (NULL != decryptHandle) {
- status = getDrmManagerService()->closeDecryptSession( uniqueId, decryptHandle);
+ if (NULL != decryptHandle.get()) {
+ status = getDrmManagerService()->closeDecryptSession(
+ uniqueId, decryptHandle.get());
}
return status;
}
-status_t DrmManagerClientImpl::initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
- int decryptUnitId, const DrmBuffer* headerInfo) {
+status_t DrmManagerClientImpl::initializeDecryptUnit(
+ int uniqueId, sp<DecryptHandle> &decryptHandle,
+ int decryptUnitId, const DrmBuffer* headerInfo) {
status_t status = DRM_ERROR_UNKNOWN;
- if ((NULL != decryptHandle) && (NULL != headerInfo)) {
+ if ((NULL != decryptHandle.get()) && (NULL != headerInfo)) {
status = getDrmManagerService()->initializeDecryptUnit(
- uniqueId, decryptHandle, decryptUnitId, headerInfo);
+ uniqueId, decryptHandle.get(), decryptUnitId, headerInfo);
}
return status;
}
-status_t DrmManagerClientImpl::decrypt(int uniqueId, DecryptHandle* decryptHandle,
- int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
+status_t DrmManagerClientImpl::decrypt(
+ int uniqueId, sp<DecryptHandle> &decryptHandle,
+ int decryptUnitId, const DrmBuffer* encBuffer,
+ DrmBuffer** decBuffer, DrmBuffer* IV) {
status_t status = DRM_ERROR_UNKNOWN;
- if ((NULL != decryptHandle) && (NULL != encBuffer)
+ if ((NULL != decryptHandle.get()) && (NULL != encBuffer)
&& (NULL != decBuffer) && (NULL != *decBuffer)) {
status = getDrmManagerService()->decrypt(
- uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
+ uniqueId, decryptHandle.get(), decryptUnitId,
+ encBuffer, decBuffer, IV);
}
return status;
}
status_t DrmManagerClientImpl::finalizeDecryptUnit(
- int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
+ int uniqueId, sp<DecryptHandle> &decryptHandle, int decryptUnitId) {
status_t status = DRM_ERROR_UNKNOWN;
- if (NULL != decryptHandle) {
- status
- = getDrmManagerService()->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
+ if (NULL != decryptHandle.get()) {
+ status = getDrmManagerService()->finalizeDecryptUnit(
+ uniqueId, decryptHandle.get(), decryptUnitId);
}
return status;
}
-ssize_t DrmManagerClientImpl::pread(int uniqueId, DecryptHandle* decryptHandle,
+ssize_t DrmManagerClientImpl::pread(int uniqueId, sp<DecryptHandle> &decryptHandle,
void* buffer, ssize_t numBytes, off64_t offset) {
ssize_t retCode = INVALID_VALUE;
- if ((NULL != decryptHandle) && (NULL != buffer) && (0 < numBytes)) {
- retCode = getDrmManagerService()->pread(uniqueId, decryptHandle, buffer, numBytes, offset);
+ if ((NULL != decryptHandle.get()) && (NULL != buffer) && (0 < numBytes)) {
+ retCode = getDrmManagerService()->pread(
+ uniqueId, decryptHandle.get(), buffer, numBytes, offset);
}
return retCode;
}
diff --git a/drm/libdrmframework/include/DrmManagerClientImpl.h b/drm/libdrmframework/include/DrmManagerClientImpl.h
index 0a7fcd1..0cba8d4 100644
--- a/drm/libdrmframework/include/DrmManagerClientImpl.h
+++ b/drm/libdrmframework/include/DrmManagerClientImpl.h
@@ -189,7 +189,7 @@
* @return status_t
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
- status_t consumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
+ status_t consumeRights(int uniqueId, sp<DecryptHandle> &decryptHandle, int action, bool reserve);
/**
* Informs the DRM engine about the playback actions performed on the DRM files.
@@ -203,7 +203,7 @@
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
status_t setPlaybackStatus(
- int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position);
+ int uniqueId, sp<DecryptHandle> &decryptHandle, int playbackStatus, int64_t position);
/**
* Validates whether an action on the DRM content is allowed or not.
@@ -303,7 +303,7 @@
* @return
* Handle for the decryption session
*/
- DecryptHandle* openDecryptSession(int uniqueId, int fd, off64_t offset, off64_t length);
+ sp<DecryptHandle> openDecryptSession(int uniqueId, int fd, off64_t offset, off64_t length);
/**
* Open the decrypt session to decrypt the given protected content
@@ -313,7 +313,7 @@
* @return
* Handle for the decryption session
*/
- DecryptHandle* openDecryptSession(int uniqueId, const char* uri);
+ sp<DecryptHandle> openDecryptSession(int uniqueId, const char* uri);
/**
* Close the decrypt session for the given handle
@@ -323,7 +323,7 @@
* @return status_t
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
- status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
+ status_t closeDecryptSession(int uniqueId, sp<DecryptHandle> &decryptHandle);
/**
* Initialize decryption for the given unit of the protected content
@@ -335,7 +335,7 @@
* @return status_t
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
- status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+ status_t initializeDecryptUnit(int uniqueId, sp<DecryptHandle> &decryptHandle,
int decryptUnitId, const DrmBuffer* headerInfo);
/**
@@ -355,7 +355,7 @@
* DRM_ERROR_SESSION_NOT_OPENED, DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED,
* DRM_ERROR_DECRYPT for failure.
*/
- status_t decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+ status_t decrypt(int uniqueId, sp<DecryptHandle> &decryptHandle, int decryptUnitId,
const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV);
/**
@@ -367,7 +367,7 @@
* @return status_t
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
- status_t finalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
+ status_t finalizeDecryptUnit(int uniqueId, sp<DecryptHandle> &decryptHandle, int decryptUnitId);
/**
* Reads the specified number of bytes from an open DRM file.
@@ -380,7 +380,7 @@
*
* @return Number of bytes read. Returns -1 for Failure.
*/
- ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
+ ssize_t pread(int uniqueId, sp<DecryptHandle> &decryptHandle,
void* buffer, ssize_t numBytes, off64_t offset);
/**
diff --git a/include/android_runtime/android_graphics_SurfaceTexture.h b/include/android_runtime/android_graphics_SurfaceTexture.h
new file mode 100644
index 0000000..8e6fc6ee
--- /dev/null
+++ b/include/android_runtime/android_graphics_SurfaceTexture.h
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+#ifndef _ANDROID_GRAPHICS_SURFACETEXTURE_H
+#define _ANDROID_GRAPHICS_SURFACETEXTURE_H
+
+#include <android/native_window.h>
+
+#include "jni.h"
+
+namespace android {
+
+extern sp<ANativeWindow> android_SurfaceTexture_getNativeWindow(
+ JNIEnv* env, jobject thiz);
+
+} // namespace android
+
+#endif // _ANDROID_GRAPHICS_SURFACETEXTURE_H
diff --git a/include/drm/DrmManagerClient.h b/include/drm/DrmManagerClient.h
index 085ebf1..044ff0e 100644
--- a/include/drm/DrmManagerClient.h
+++ b/include/drm/DrmManagerClient.h
@@ -69,7 +69,7 @@
* @return
* Handle for the decryption session
*/
- DecryptHandle* openDecryptSession(int fd, off64_t offset, off64_t length);
+ sp<DecryptHandle> openDecryptSession(int fd, off64_t offset, off64_t length);
/**
* Open the decrypt session to decrypt the given protected content
@@ -78,7 +78,7 @@
* @return
* Handle for the decryption session
*/
- DecryptHandle* openDecryptSession(const char* uri);
+ sp<DecryptHandle> openDecryptSession(const char* uri);
/**
* Close the decrypt session for the given handle
@@ -87,7 +87,7 @@
* @return status_t
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
- status_t closeDecryptSession(DecryptHandle* decryptHandle);
+ status_t closeDecryptSession(sp<DecryptHandle> &decryptHandle);
/**
* Consumes the rights for a content.
@@ -101,7 +101,7 @@
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure.
* In case license has been expired, DRM_ERROR_LICENSE_EXPIRED will be returned.
*/
- status_t consumeRights(DecryptHandle* decryptHandle, int action, bool reserve);
+ status_t consumeRights(sp<DecryptHandle> &decryptHandle, int action, bool reserve);
/**
* Informs the DRM engine about the playback actions performed on the DRM files.
@@ -113,7 +113,8 @@
* @return status_t
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
- status_t setPlaybackStatus(DecryptHandle* decryptHandle, int playbackStatus, int64_t position);
+ status_t setPlaybackStatus(
+ sp<DecryptHandle> &decryptHandle, int playbackStatus, int64_t position);
/**
* Initialize decryption for the given unit of the protected content
@@ -125,7 +126,7 @@
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
status_t initializeDecryptUnit(
- DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo);
+ sp<DecryptHandle> &decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo);
/**
* Decrypt the protected content buffers for the given unit
@@ -144,7 +145,7 @@
* DRM_ERROR_DECRYPT for failure.
*/
status_t decrypt(
- DecryptHandle* decryptHandle, int decryptUnitId,
+ sp<DecryptHandle> &decryptHandle, int decryptUnitId,
const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV = NULL);
/**
@@ -155,7 +156,8 @@
* @return status_t
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
- status_t finalizeDecryptUnit(DecryptHandle* decryptHandle, int decryptUnitId);
+ status_t finalizeDecryptUnit(
+ sp<DecryptHandle> &decryptHandle, int decryptUnitId);
/**
* Reads the specified number of bytes from an open DRM file.
@@ -167,7 +169,8 @@
*
* @return Number of bytes read. Returns -1 for Failure.
*/
- ssize_t pread(DecryptHandle* decryptHandle, void* buffer, ssize_t numBytes, off64_t offset);
+ ssize_t pread(sp<DecryptHandle> &decryptHandle,
+ void* buffer, ssize_t numBytes, off64_t offset);
/**
* Validates whether an action on the DRM content is allowed or not.
diff --git a/include/drm/drm_framework_common.h b/include/drm/drm_framework_common.h
index 1758cdd..3ad0330 100644
--- a/include/drm/drm_framework_common.h
+++ b/include/drm/drm_framework_common.h
@@ -19,6 +19,7 @@
#include <utils/Vector.h>
#include <utils/KeyedVector.h>
+#include <utils/RefBase.h>
#include <utils/String8.h>
#include <utils/Errors.h>
@@ -240,7 +241,7 @@
/**
* Defines decryption handle
*/
-class DecryptHandle {
+class DecryptHandle : public RefBase {
public:
/**
* Decryption session Handle
@@ -285,10 +286,15 @@
decryptId(INVALID_VALUE),
mimeType(""),
decryptApiType(INVALID_VALUE),
- status(INVALID_VALUE) {
+ status(INVALID_VALUE),
+ decryptInfo(NULL) {
}
+ ~DecryptHandle() {
+ delete decryptInfo; decryptInfo = NULL;
+ }
+
bool operator<(const DecryptHandle& handle) const {
return (decryptId < handle.decryptId);
}
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index 5f7cd90..293764d 100644
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -346,12 +346,14 @@
};
bool processAudioBuffer(const sp<ClientRecordThread>& thread);
- status_t openRecord(uint32_t sampleRate,
+ status_t openRecord_l(uint32_t sampleRate,
int format,
int channelCount,
int frameCount,
uint32_t flags,
audio_io_handle_t input);
+ audio_io_handle_t getInput_l();
+ status_t restoreRecord_l(audio_track_cblk_t*& cblk);
sp<IAudioRecord> mAudioRecord;
sp<IMemory> mCblkMemory;
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index 813a905..3e346db 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -437,7 +437,7 @@
};
bool processAudioBuffer(const sp<AudioTrackThread>& thread);
- status_t createTrack(int streamType,
+ status_t createTrack_l(int streamType,
uint32_t sampleRate,
int format,
int channelCount,
@@ -446,6 +446,10 @@
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output,
bool enforceFrameCount);
+ void flush_l();
+ status_t setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCount);
+ audio_io_handle_t getOutput_l();
+ status_t restoreTrack_l(audio_track_cblk_t*& cblk, bool fromStart);
sp<IAudioTrack> mAudioTrack;
sp<IMemory> mCblkMemory;
diff --git a/include/media/mediametadataretriever.h b/include/media/mediametadataretriever.h
index e905006..a5cb949 100644
--- a/include/media/mediametadataretriever.h
+++ b/include/media/mediametadataretriever.h
@@ -47,6 +47,12 @@
METADATA_KEY_ALBUMARTIST = 13,
METADATA_KEY_DISC_NUMBER = 14,
METADATA_KEY_COMPILATION = 15,
+ METADATA_KEY_HAS_AUDIO = 16,
+ METADATA_KEY_HAS_VIDEO = 17,
+ METADATA_KEY_VIDEO_WIDTH = 18,
+ METADATA_KEY_VIDEO_HEIGHT = 19,
+ METADATA_KEY_BITRATE = 20,
+
// Add more here...
};
diff --git a/include/media/stagefright/DataSource.h b/include/media/stagefright/DataSource.h
index f95e56a..d30e908 100644
--- a/include/media/stagefright/DataSource.h
+++ b/include/media/stagefright/DataSource.h
@@ -75,10 +75,10 @@
static void RegisterDefaultSniffers();
// for DRM
- virtual DecryptHandle* DrmInitialization() {
+ virtual sp<DecryptHandle> DrmInitialization() {
return NULL;
}
- virtual void getDrmInfo(DecryptHandle **handle, DrmManagerClient **client) {};
+ virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client) {};
virtual String8 getUri() {
return String8();
diff --git a/include/media/stagefright/FileSource.h b/include/media/stagefright/FileSource.h
index 51a4343..6cf86dc 100644
--- a/include/media/stagefright/FileSource.h
+++ b/include/media/stagefright/FileSource.h
@@ -38,9 +38,9 @@
virtual status_t getSize(off64_t *size);
- virtual DecryptHandle* DrmInitialization();
+ virtual sp<DecryptHandle> DrmInitialization();
- virtual void getDrmInfo(DecryptHandle **handle, DrmManagerClient **client);
+ virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client);
protected:
virtual ~FileSource();
@@ -52,7 +52,7 @@
Mutex mLock;
/*for DRM*/
- DecryptHandle *mDecryptHandle;
+ sp<DecryptHandle> mDecryptHandle;
DrmManagerClient *mDrmManagerClient;
int64_t mDrmBufOffset;
int64_t mDrmBufSize;
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index f7d837a..93b5d24 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -50,6 +50,9 @@
// Only submit one input buffer at one time.
kOnlySubmitOneInputBufferAtOneTime = 64,
+
+ // Enable GRALLOC_USAGE_PROTECTED for output buffers from native window
+ kEnableGrallocUsageProtected = 128,
};
static sp<MediaSource> Create(
const sp<IOMX> &omx,
@@ -197,6 +200,7 @@
bool mIsMetaDataStoredInVideoBuffers;
bool mOnlySubmitOneBufferAtOneTime;
+ bool mEnableGrallocUsageProtected;
OMXCodec(const sp<IOMX> &omx, IOMX::node_id node, uint32_t quirks,
bool isEncoder, const char *mime, const char *componentName,
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index c6990bf..4610135 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -31,6 +31,7 @@
#define MAX_STARTUP_TIMEOUT_MS 3000 // Longer timeout period at startup to cope with A2DP init time
#define MAX_RUN_TIMEOUT_MS 1000
#define WAIT_PERIOD_MS 10
+#define RESTORE_TIMEOUT_MS 5000 // Maximum waiting time for a track to be restored
#define CBLK_UNDERRUN_MSK 0x0001
#define CBLK_UNDERRUN_ON 0x0001 // underrun (out) or overrrun (in) indication
@@ -47,6 +48,12 @@
#define CBLK_DISABLED_MSK 0x0010
#define CBLK_DISABLED_ON 0x0010 // track disabled by AudioFlinger due to underrun:
#define CBLK_DISABLED_OFF 0x0000 // must be re-started
+#define CBLK_RESTORING_MSK 0x0020
+#define CBLK_RESTORING_ON 0x0020 // track is being restored after invalidation
+#define CBLK_RESTORING_OFF 0x0000 // by AudioFlinger
+#define CBLK_RESTORED_MSK 0x0040
+#define CBLK_RESTORED_ON 0x0040 // track has been restored after invalidation
+#define CBLK_RESTORED_OFF 0x0040 // by AudioFlinger
struct audio_track_cblk_t
{
diff --git a/include/surfaceflinger/ISurfaceComposer.h b/include/surfaceflinger/ISurfaceComposer.h
index 361e7dc..dea1b10 100644
--- a/include/surfaceflinger/ISurfaceComposer.h
+++ b/include/surfaceflinger/ISurfaceComposer.h
@@ -138,6 +138,10 @@
* This is an ASYNCHRONOUS call.
*/
virtual void signal() const = 0;
+
+ /* verify that an ISurface was created by SurfaceFlinger.
+ */
+ virtual bool authenticateSurface(const sp<ISurface>& surface) const = 0;
};
// ----------------------------------------------------------------------------
@@ -161,7 +165,8 @@
SIGNAL,
CAPTURE_SCREEN,
TURN_ELECTRON_BEAM_OFF,
- TURN_ELECTRON_BEAM_ON
+ TURN_ELECTRON_BEAM_ON,
+ AUTHENTICATE_SURFACE,
};
virtual status_t onTransact( uint32_t code,
diff --git a/include/ui/Input.h b/include/ui/Input.h
index e92d7f5..d9d77c4 100644
--- a/include/ui/Input.h
+++ b/include/ui/Input.h
@@ -144,6 +144,14 @@
};
/*
+ * Button state.
+ */
+enum {
+ // Primary button pressed (left mouse button).
+ BUTTON_STATE_PRIMARY = 1 << 0,
+};
+
+/*
* Describes the basic configuration of input devices that are present.
*/
struct InputConfiguration {
@@ -544,6 +552,8 @@
~InputDeviceInfo();
struct MotionRange {
+ int32_t axis;
+ uint32_t source;
float min;
float max;
float flat;
@@ -556,16 +566,17 @@
inline const String8 getName() const { return mName; }
inline uint32_t getSources() const { return mSources; }
- const MotionRange* getMotionRange(int32_t axis) const;
+ const MotionRange* getMotionRange(int32_t axis, uint32_t source) const;
void addSource(uint32_t source);
- void addMotionRange(int32_t axis, float min, float max, float flat, float fuzz);
- void addMotionRange(int32_t axis, const MotionRange& range);
+ void addMotionRange(int32_t axis, uint32_t source,
+ float min, float max, float flat, float fuzz);
+ void addMotionRange(const MotionRange& range);
inline void setKeyboardType(int32_t keyboardType) { mKeyboardType = keyboardType; }
inline int32_t getKeyboardType() const { return mKeyboardType; }
- inline const KeyedVector<int32_t, MotionRange> getMotionRanges() const {
+ inline const Vector<MotionRange>& getMotionRanges() const {
return mMotionRanges;
}
@@ -575,7 +586,7 @@
uint32_t mSources;
int32_t mKeyboardType;
- KeyedVector<int32_t, MotionRange> mMotionRanges;
+ Vector<MotionRange> mMotionRanges;
};
/*
diff --git a/include/ui/KeyLayoutMap.h b/include/ui/KeyLayoutMap.h
index 904c8f3..d82d0c8 100644
--- a/include/ui/KeyLayoutMap.h
+++ b/include/ui/KeyLayoutMap.h
@@ -24,6 +24,36 @@
namespace android {
+struct AxisInfo {
+ enum Mode {
+ // Axis value is reported directly.
+ MODE_NORMAL = 0,
+ // Axis value should be inverted before reporting.
+ MODE_INVERT = 1,
+ // Axis value should be split into two axes
+ MODE_SPLIT = 2,
+ };
+
+ // Axis mode.
+ Mode mode;
+
+ // Axis id.
+ // When split, this is the axis used for values smaller than the split position.
+ int32_t axis;
+
+ // When split, this is the axis used for values after higher than the split position.
+ int32_t highAxis;
+
+ // The split value, or 0 if not split.
+ int32_t splitValue;
+
+ // The flat value, or -1 if none.
+ int32_t flatOverride;
+
+ AxisInfo() : mode(MODE_NORMAL), axis(-1), highAxis(-1), splitValue(0), flatOverride(-1) {
+ }
+};
+
/**
* Describes a mapping from keyboard scan codes and joystick axes to Android key codes and axes.
*/
@@ -36,7 +66,7 @@
status_t mapKey(int32_t scanCode, int32_t* keyCode, uint32_t* flags) const;
status_t findScanCodesForKey(int32_t keyCode, Vector<int32_t>* outScanCodes) const;
- status_t mapAxis(int32_t scanCode, int32_t* axis) const;
+ status_t mapAxis(int32_t scanCode, AxisInfo* outAxisInfo) const;
private:
struct Key {
@@ -45,7 +75,7 @@
};
KeyedVector<int32_t, Key> mKeys;
- KeyedVector<int32_t, int32_t> mAxes;
+ KeyedVector<int32_t, AxisInfo> mAxes;
KeyLayoutMap();
diff --git a/include/ui/KeycodeLabels.h b/include/ui/KeycodeLabels.h
index bdfbf7c..b912e9b 100755
--- a/include/ui/KeycodeLabels.h
+++ b/include/ui/KeycodeLabels.h
@@ -270,6 +270,11 @@
{ "HAT_Y", 16 },
{ "LTRIGGER", 17 },
{ "RTRIGGER", 18 },
+ { "THROTTLE", 19 },
+ { "RUDDER", 20 },
+ { "WHEEL", 21 },
+ { "GAS", 22 },
+ { "BRAKE", 23 },
{ "GENERIC_1", 32 },
{ "GENERIC_2", 33 },
{ "GENERIC_3", 34 },
diff --git a/include/ui/egl/android_natives.h b/include/ui/egl/android_natives.h
index fd83f46..0ac34d0 100644
--- a/include/ui/egl/android_natives.h
+++ b/include/ui/egl/android_natives.h
@@ -95,6 +95,21 @@
* 5. Queue, dequeue, queue, dequeue, ad infinitum
*/
NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
+
+ /* Check whether queueBuffer operations on the ANativeWindow send the buffer
+ * to the window compositor. The query sets the returned 'value' argument
+ * to 1 if the ANativeWindow DOES send queued buffers directly to the window
+ * compositor and 0 if the buffers do not go directly to the window
+ * compositor.
+ *
+ * This can be used to determine whether protected buffer content should be
+ * sent to the ANativeWindow. Note, however, that a result of 1 does NOT
+ * indicate that queued buffers will be protected from applications or users
+ * capturing their contents. If that behavior is desired then some other
+ * mechanism (e.g. the GRALLOC_USAGE_PROTECTED flag) should be used in
+ * conjunction with this query.
+ */
+ NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
};
/* valid operations for the (*perform)() hook */
diff --git a/include/utils/Functor.h b/include/utils/Functor.h
index 3955bc3..565f4a3 100644
--- a/include/utils/Functor.h
+++ b/include/utils/Functor.h
@@ -26,6 +26,7 @@
Functor() {}
virtual ~Functor() {}
virtual status_t operator ()() { return true; }
+ virtual status_t operator ()(float* data, uint32_t len) { return true; }
};
}; // namespace android
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index 43b330c..a40fac9 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -156,6 +156,10 @@
case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
*value = MIN_UNDEQUEUED_BUFFERS;
return NO_ERROR;
+ case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
+ // SurfaceTextureClient currently never queues frames to SurfaceFlinger.
+ *value = 0;
+ return NO_ERROR;
}
return BAD_VALUE;
}
diff --git a/libs/gui/tests/Android.mk b/libs/gui/tests/Android.mk
new file mode 100644
index 0000000..1dd8885
--- /dev/null
+++ b/libs/gui/tests/Android.mk
@@ -0,0 +1,53 @@
+# Build the unit tests.
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+ifneq ($(TARGET_SIMULATOR),true)
+
+# Build the unit tests.
+test_src_files := \
+ SurfaceTextureClient_test.cpp \
+
+shared_libraries := \
+ libcutils \
+ libutils \
+ libbinder \
+ libgui \
+ libstlport \
+
+static_libraries := \
+ libgtest \
+ libgtest_main \
+
+c_includes := \
+ bionic \
+ bionic/libstdc++/include \
+ external/gtest/include \
+ external/stlport/stlport \
+
+module_tags := tests
+
+$(foreach file,$(test_src_files), \
+ $(eval include $(CLEAR_VARS)) \
+ $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
+ $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \
+ $(eval LOCAL_C_INCLUDES := $(c_includes)) \
+ $(eval LOCAL_SRC_FILES := $(file)) \
+ $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
+ $(eval LOCAL_MODULE_TAGS := $(module_tags)) \
+ $(eval include $(BUILD_EXECUTABLE)) \
+)
+
+# Build the manual test programs.
+include $(call all-subdir-makefiles)
+
+endif
+
+# Include subdirectory makefiles
+# ============================================================
+
+# If we're building with ONE_SHOT_MAKEFILE (mm, mmm), then what the framework
+# team really wants is to build the stuff defined by this makefile.
+ifeq (,$(ONE_SHOT_MAKEFILE))
+include $(call first-makefiles-under,$(LOCAL_PATH))
+endif
diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp
new file mode 100644
index 0000000..0f140ff
--- /dev/null
+++ b/libs/gui/tests/SurfaceTextureClient_test.cpp
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+#include <gui/SurfaceTextureClient.h>
+#include <gtest/gtest.h>
+
+namespace android {
+
+class SurfaceTextureClientTest : public ::testing::Test {
+protected:
+ virtual void SetUp() {
+ mST = new SurfaceTexture(123);
+ mSTC = new SurfaceTextureClient(mST);
+ }
+
+ virtual void TearDown() {
+ mST.clear();
+ mSTC.clear();
+ }
+
+ sp<SurfaceTexture> mST;
+ sp<SurfaceTextureClient> mSTC;
+};
+
+TEST_F(SurfaceTextureClientTest, QueuesToWindowCompositorIsFalse) {
+ sp<ANativeWindow> anw(mSTC);
+ int result = -123;
+ int err = anw->query(anw.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
+ &result);
+ EXPECT_EQ(NO_ERROR, err);
+ EXPECT_EQ(0, result);
+}
+
+}
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 38e0848..f4a0161 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -15,7 +15,6 @@
LayerCache.cpp \
LayerRenderer.cpp \
Matrix.cpp \
- OpenGLDebugRenderer.cpp \
OpenGLRenderer.cpp \
Patch.cpp \
PatchCache.cpp \
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index d5d2ba0..737fa02 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -166,7 +166,7 @@
void DisplayList::init() {
}
-bool DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) {
+bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level) {
bool needsInvalidate = false;
TextContainer text;
mReader.rewind();
@@ -189,7 +189,7 @@
case DrawGLFunction: {
Functor *functor = (Functor *) getInt();
DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor);
- needsInvalidate |= renderer.callDrawGLFunction(functor);
+ needsInvalidate |= renderer.callDrawGLFunction(functor, dirty);
}
break;
case Save: {
@@ -287,7 +287,7 @@
DisplayList* displayList = getDisplayList();
DISPLAY_LIST_LOGD("%s%s %p, %d", (char*) indent, OP_NAMES[op],
displayList, level + 1);
- needsInvalidate |= renderer.drawDisplayList(displayList, level + 1);
+ needsInvalidate |= renderer.drawDisplayList(displayList, dirty, level + 1);
}
break;
case DrawLayer: {
@@ -589,7 +589,8 @@
void DisplayListRenderer::resume() {
}
-bool DisplayListRenderer::callDrawGLFunction(Functor *functor) {
+bool DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) {
+ // Ignore dirty during recording, it matters only when we replay
addOp(DisplayList::DrawGLFunction);
addInt((int) functor);
return false; // No invalidate needed at record-time
@@ -673,7 +674,9 @@
return OpenGLRenderer::clipRect(left, top, right, bottom, op);
}
-bool DisplayListRenderer::drawDisplayList(DisplayList* displayList, uint32_t level) {
+bool DisplayListRenderer::drawDisplayList(DisplayList* displayList, Rect& dirty, uint32_t level) {
+ // dirty is an out parameter and should not be recorded,
+ // it matters only when replaying the display list
addOp(DisplayList::DrawDisplayList);
addDisplayList(displayList);
return false;
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index e8f189d..f24545d 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -103,7 +103,7 @@
void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false);
- bool replay(OpenGLRenderer& renderer, uint32_t level = 0);
+ bool replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level = 0);
private:
void init();
@@ -214,7 +214,7 @@
void prepareDirty(float left, float top, float right, float bottom, bool opaque);
void finish();
- bool callDrawGLFunction(Functor *functor);
+ bool callDrawGLFunction(Functor *functor, Rect& dirty);
void interrupt();
void resume();
@@ -238,7 +238,7 @@
bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
- bool drawDisplayList(DisplayList* displayList, uint32_t level = 0);
+ bool drawDisplayList(DisplayList* displayList, Rect& dirty, uint32_t level = 0);
void drawLayer(Layer* layer, float x, float y, SkPaint* paint);
void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
diff --git a/libs/hwui/OpenGLDebugRenderer.cpp b/libs/hwui/OpenGLDebugRenderer.cpp
deleted file mode 100644
index 05870bb..0000000
--- a/libs/hwui/OpenGLDebugRenderer.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * 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.
- * 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.
- */
-
-#define LOG_TAG "OpenGLRenderer"
-
-#include <utils/StopWatch.h>
-
-#include "OpenGLDebugRenderer.h"
-
-namespace android {
-namespace uirenderer {
-
-void OpenGLDebugRenderer::prepareDirty(float left, float top,
- float right, float bottom, bool opaque) {
- mPrimitivesCount = 0;
- LOGD("========= Frame start =========");
- OpenGLRenderer::prepareDirty(left, top, right, bottom, opaque);
-}
-
-void OpenGLDebugRenderer::finish() {
- LOGD("========= Frame end =========");
- LOGD("Primitives draw count = %d", mPrimitivesCount);
- OpenGLRenderer::finish();
-}
-
-void OpenGLDebugRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) {
- mPrimitivesCount++;
- StopWatch w("composeLayer");
- return OpenGLRenderer::composeLayer(current, previous);
-}
-
-int OpenGLDebugRenderer::saveLayer(float left, float top, float right, float bottom,
- SkPaint* p, int flags) {
- mPrimitivesCount++;
- StopWatch w("saveLayer");
- return OpenGLRenderer::saveLayer(left, top, right, bottom, p, flags);
-}
-
-bool OpenGLDebugRenderer::drawDisplayList(DisplayList* displayList, uint32_t level) {
- mPrimitivesCount++;
- StopWatch w("drawDisplayList");
- return OpenGLRenderer::drawDisplayList(displayList);
-}
-
-void OpenGLDebugRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
- mPrimitivesCount++;
- StopWatch w("drawLayer");
- OpenGLRenderer::drawLayer(layer, x, y, paint);
-}
-
-void OpenGLDebugRenderer::drawBitmap(SkBitmap* bitmap, float left, float top,
- SkPaint* paint) {
- mPrimitivesCount++;
- StopWatch w("drawBitmap");
- OpenGLRenderer::drawBitmap(bitmap, left, top, paint);
-}
-
-void OpenGLDebugRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix,
- SkPaint* paint) {
- mPrimitivesCount++;
- StopWatch w("drawBitmapMatrix");
- OpenGLRenderer::drawBitmap(bitmap, matrix, paint);
-}
-
-void OpenGLDebugRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
- float srcRight, float srcBottom, float dstLeft, float dstTop,
- float dstRight, float dstBottom, SkPaint* paint) {
- mPrimitivesCount++;
- StopWatch w("drawBitmapRect");
- OpenGLRenderer::drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom,
- dstLeft, dstTop, dstRight, dstBottom, paint);
-}
-
-void OpenGLDebugRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
- const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
- float left, float top, float right, float bottom, SkPaint* paint) {
- mPrimitivesCount++;
- StopWatch w("drawPatch");
- OpenGLRenderer::drawPatch(bitmap, xDivs, yDivs, colors, width, height, numColors,
- left, top, right, bottom, paint);
-}
-
-void OpenGLDebugRenderer::drawColor(int color, SkXfermode::Mode mode) {
- mPrimitivesCount++;
- StopWatch w("drawColor");
- OpenGLRenderer::drawColor(color, mode);
-}
-
-void OpenGLDebugRenderer::drawRect(float left, float top, float right, float bottom,
- SkPaint* paint) {
- mPrimitivesCount++;
- StopWatch w("drawRect");
- OpenGLRenderer::drawRect(left, top, right, bottom, paint);
-}
-
-void OpenGLDebugRenderer::drawRoundRect(float left, float top, float right, float bottom,
- float rx, float ry, SkPaint* paint) {
- mPrimitivesCount++;
- StopWatch w("drawRoundRect");
- OpenGLRenderer::drawRoundRect(left, top, right, bottom, rx, ry, paint);
-}
-
-void OpenGLDebugRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
- mPrimitivesCount++;
- StopWatch w("drawCircle");
- OpenGLRenderer::drawCircle(x, y, radius, paint);
-}
-
-void OpenGLDebugRenderer::drawOval(float left, float top, float right, float bottom,
- SkPaint* paint) {
- mPrimitivesCount++;
- StopWatch w("drawOval");
- OpenGLRenderer::drawOval(left, top, right, bottom, paint);
-}
-
-void OpenGLDebugRenderer::drawArc(float left, float top, float right, float bottom,
- float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
- mPrimitivesCount++;
- StopWatch w("drawArc");
- OpenGLRenderer::drawArc(left, top, right, bottom, startAngle, sweepAngle, useCenter, paint);
-}
-
-void OpenGLDebugRenderer::drawPath(SkPath* path, SkPaint* paint) {
- mPrimitivesCount++;
- StopWatch w("drawPath");
- OpenGLRenderer::drawPath(path, paint);
-}
-
-void OpenGLDebugRenderer::drawLines(float* points, int count, SkPaint* paint) {
- mPrimitivesCount++;
- StopWatch w("drawLines");
- OpenGLRenderer::drawLines(points, count, paint);
-}
-
-void OpenGLDebugRenderer::drawText(const char* text, int bytesCount, int count, float x, float y,
- SkPaint* paint) {
- mPrimitivesCount++;
- StopWatch w("drawText");
- OpenGLRenderer::drawText(text, bytesCount, count, x, y, paint);
-}
-
-}; // namespace uirenderer
-}; // namespace android
diff --git a/libs/hwui/OpenGLDebugRenderer.h b/libs/hwui/OpenGLDebugRenderer.h
deleted file mode 100644
index 1a18a67..0000000
--- a/libs/hwui/OpenGLDebugRenderer.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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.
- * 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.
- */
-
-#ifndef ANDROID_HWUI_OPENGL_DEBUG_RENDERER_H
-#define ANDROID_HWUI_OPENGL_DEBUG_RENDERER_H
-
-#include "OpenGLRenderer.h"
-
-namespace android {
-namespace uirenderer {
-
-///////////////////////////////////////////////////////////////////////////////
-// Renderer
-///////////////////////////////////////////////////////////////////////////////
-
-class OpenGLDebugRenderer: public OpenGLRenderer {
-public:
- OpenGLDebugRenderer(): mPrimitivesCount(0) {
- }
-
- ~OpenGLDebugRenderer() {
- }
-
- void prepareDirty(float left, float top, float right, float bottom, bool opaque);
- void finish();
-
- int saveLayer(float left, float top, float right, float bottom,
- SkPaint* p, int flags);
-
- bool drawDisplayList(DisplayList* displayList, uint32_t level = 0);
- void drawLayer(Layer* layer, float x, float y, SkPaint* paint);
- void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
- void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
- void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
- float srcRight, float srcBottom, float dstLeft, float dstTop,
- float dstRight, float dstBottom, SkPaint* paint);
- void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
- const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
- float left, float top, float right, float bottom, SkPaint* paint);
- void drawColor(int color, SkXfermode::Mode mode);
- void drawRect(float left, float top, float right, float bottom, SkPaint* paint);
- void drawRoundRect(float left, float top, float right, float bottom,
- float rx, float ry, SkPaint* paint);
- void drawCircle(float x, float y, float radius, SkPaint* paint);
- void drawOval(float left, float top, float right, float bottom, SkPaint* paint);
- void drawArc(float left, float top, float right, float bottom,
- float startAngle, float sweepAngle, bool useCenter, SkPaint* paint);
- void drawPath(SkPath* path, SkPaint* paint);
- void drawLines(float* points, int count, SkPaint* paint);
- void drawText(const char* text, int bytesCount, int count, float x, float y,
- SkPaint* paint);
-
-protected:
- void composeLayer(sp<Snapshot> current, sp<Snapshot> previous);
-
-private:
- uint32_t mPrimitivesCount;
-
-}; // class OpenGLDebugRenderer
-
-}; // namespace uirenderer
-}; // namespace android
-
-#endif // ANDROID_HWUI_OPENGL_DEBUG_RENDERER_H
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index dfca7eb..1f65201 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -210,7 +210,7 @@
glBlendEquation(GL_FUNC_ADD);
}
-bool OpenGLRenderer::callDrawGLFunction(Functor *functor) {
+bool OpenGLRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) {
interrupt();
if (mDirtyClip) {
setScissorFromClip();
@@ -226,9 +226,16 @@
}
#endif
- status_t result = (*functor)();
+ float bounds[4];
+ status_t result = (*functor)(&bounds[0], 4);
+
+ if (result != 0) {
+ Rect localDirty(bounds[0], bounds[1], bounds[2], bounds[3]);
+ dirty.unionWith(localDirty);
+ }
+
resume();
- return (result == 0) ? false : true;
+ return result != 0;
}
///////////////////////////////////////////////////////////////////////////////
@@ -1057,11 +1064,11 @@
// Drawing
///////////////////////////////////////////////////////////////////////////////
-bool OpenGLRenderer::drawDisplayList(DisplayList* displayList, uint32_t level) {
+bool OpenGLRenderer::drawDisplayList(DisplayList* displayList, Rect& dirty, uint32_t level) {
// All the usual checks and setup operations (quickReject, setupDraw, etc.)
// will be performed by the display list itself
if (displayList) {
- return displayList->replay(*this, level);
+ return displayList->replay(*this, dirty, level);
}
return false;
}
@@ -1522,7 +1529,6 @@
break;
}
- // TODO: Handle paint->getTextScaleX()
const float oldX = x;
const float oldY = y;
const bool pureTranslate = mSnapshot->transform->isPureTranslate();
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 7bbf034..9d86388 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -70,7 +70,7 @@
virtual void interrupt();
virtual void resume();
- virtual bool callDrawGLFunction(Functor *functor);
+ virtual bool callDrawGLFunction(Functor *functor, Rect& dirty);
int getSaveCount() const;
virtual int save(int flags);
@@ -96,7 +96,7 @@
bool quickReject(float left, float top, float right, float bottom);
virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
- virtual bool drawDisplayList(DisplayList* displayList, uint32_t level = 0);
+ virtual bool drawDisplayList(DisplayList* displayList, Rect& dirty, uint32_t level = 0);
virtual void drawLayer(Layer* layer, float x, float y, SkPaint* paint);
virtual void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
virtual void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
diff --git a/libs/hwui/TextDropShadowCache.h b/libs/hwui/TextDropShadowCache.h
index 62c4250..d46686d 100644
--- a/libs/hwui/TextDropShadowCache.h
+++ b/libs/hwui/TextDropShadowCache.h
@@ -42,6 +42,17 @@
textSize = paint->getTextSize();
typeface = paint->getTypeface();
+
+ flags = 0;
+ if (paint->isFakeBoldText()) {
+ flags |= Font::kFakeBold;
+ }
+
+ const float skewX = paint->getTextSkewX();
+ italicStyle = *(uint32_t*) &skewX;
+
+ const float scaleXFloat = paint->getTextScaleX();
+ scaleX = *(uint32_t*) &scaleXFloat;
}
~ShadowText() {
@@ -51,6 +62,9 @@
uint32_t len;
float textSize;
SkTypeface* typeface;
+ uint32_t flags;
+ uint32_t italicStyle;
+ uint32_t scaleX;
const char16_t* text;
String16 str;
@@ -65,7 +79,13 @@
LTE_INT(radius) {
LTE_FLOAT(textSize) {
LTE_INT(typeface) {
- return strncmp16(text, rhs.text, len >> 1) < 0;
+ LTE_INT(flags) {
+ LTE_INT(italicStyle) {
+ LTE_INT(scaleX) {
+ return strncmp16(text, rhs.text, len >> 1) < 0;
+ }
+ }
+ }
}
}
}
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 4a5620d..f9e29f1 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -592,11 +592,11 @@
void Context::launchThreads(WorkerCallback_t cbk, void *data) {
mWorkers.mLaunchData = data;
mWorkers.mLaunchCallback = cbk;
- mWorkers.mRunningCount = (int)mWorkers.mCount;
+ android_atomic_release_store(mWorkers.mCount, &mWorkers.mRunningCount);
for (uint32_t ct = 0; ct < mWorkers.mCount; ct++) {
mWorkers.mLaunchSignals[ct].set();
}
- while (mWorkers.mRunningCount) {
+ while (android_atomic_acquire_load(&mWorkers.mRunningCount) != 0) {
mWorkers.mCompleteSignal.wait();
}
}
@@ -707,8 +707,8 @@
}
mWorkers.mCompleteSignal.init();
- mWorkers.mRunningCount = 0;
- mWorkers.mLaunchCount = 0;
+ android_atomic_release_store(mWorkers.mCount, &mWorkers.mRunningCount);
+ android_atomic_release_store(0, &mWorkers.mLaunchCount);
for (uint32_t ct=0; ct < mWorkers.mCount; ct++) {
status = pthread_create(&mWorkers.mThreadId[ct], &threadAttr, helperThreadProc, this);
if (status) {
@@ -717,6 +717,9 @@
break;
}
}
+ while (android_atomic_acquire_load(&mWorkers.mRunningCount) != 0) {
+ usleep(100);
+ }
pthread_attr_destroy(&threadAttr);
return true;
}
@@ -736,14 +739,14 @@
// Cleanup compute threads.
mWorkers.mLaunchData = NULL;
mWorkers.mLaunchCallback = NULL;
- mWorkers.mRunningCount = (int)mWorkers.mCount;
+ android_atomic_release_store(mWorkers.mCount, &mWorkers.mRunningCount);
for (uint32_t ct = 0; ct < mWorkers.mCount; ct++) {
mWorkers.mLaunchSignals[ct].set();
}
for (uint32_t ct = 0; ct < mWorkers.mCount; ct++) {
status = pthread_join(mWorkers.mThreadId[ct], &res);
}
- rsAssert(!mWorkers.mRunningCount);
+ rsAssert(android_atomic_acquire_load(&mWorkers.mRunningCount) == 0);
// Global structure cleanup.
pthread_mutex_lock(&gInitMutex);
diff --git a/libs/surfaceflinger_client/ISurfaceComposer.cpp b/libs/surfaceflinger_client/ISurfaceComposer.cpp
index 01ae23f..8951c3f 100644
--- a/libs/surfaceflinger_client/ISurfaceComposer.cpp
+++ b/libs/surfaceflinger_client/ISurfaceComposer.cpp
@@ -25,9 +25,11 @@
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
+#include <surfaceflinger/ISurfaceComposer.h>
+
#include <ui/DisplayInfo.h>
-#include <surfaceflinger/ISurfaceComposer.h>
+#include <utils/Log.h>
// ---------------------------------------------------------------------------
@@ -178,6 +180,40 @@
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
remote()->transact(BnSurfaceComposer::SIGNAL, data, &reply, IBinder::FLAG_ONEWAY);
}
+
+ virtual bool authenticateSurface(const sp<ISurface>& surface) const
+ {
+ Parcel data, reply;
+ int err = NO_ERROR;
+ err = data.writeInterfaceToken(
+ ISurfaceComposer::getInterfaceDescriptor());
+ if (err != NO_ERROR) {
+ LOGE("ISurfaceComposer::authenticateSurface: error writing "
+ "interface descriptor: %s (%d)", strerror(-err), -err);
+ return false;
+ }
+ err = data.writeStrongBinder(surface->asBinder());
+ if (err != NO_ERROR) {
+ LOGE("ISurfaceComposer::authenticateSurface: error writing strong "
+ "binder to parcel: %s (%d)", strerror(-err), -err);
+ return false;
+ }
+ err = remote()->transact(BnSurfaceComposer::AUTHENTICATE_SURFACE, data,
+ &reply);
+ if (err != NO_ERROR) {
+ LOGE("ISurfaceComposer::authenticateSurface: error performing "
+ "transaction: %s (%d)", strerror(-err), -err);
+ return false;
+ }
+ int32_t result = 0;
+ err = reply.readInt32(&result);
+ if (err != NO_ERROR) {
+ LOGE("ISurfaceComposer::authenticateSurface: error retrieving "
+ "result: %s (%d)", strerror(-err), -err);
+ return false;
+ }
+ return result != 0;
+ }
};
IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer");
@@ -273,6 +309,12 @@
status_t res = turnElectronBeamOn(mode);
reply->writeInt32(res);
} break;
+ case AUTHENTICATE_SURFACE: {
+ CHECK_INTERFACE(ISurfaceComposer, data, reply);
+ sp<ISurface> surface = interface_cast<ISurface>(data.readStrongBinder());
+ int32_t result = authenticateSurface(surface) ? 1 : 0;
+ reply->writeInt32(result);
+ } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp
index 818114a..afabbf4 100644
--- a/libs/surfaceflinger_client/Surface.cpp
+++ b/libs/surfaceflinger_client/Surface.cpp
@@ -712,6 +712,10 @@
case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
*value = MIN_UNDEQUEUED_BUFFERS;
return NO_ERROR;
+ case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
+ sp<ISurfaceComposer> sf(ComposerService::getComposerService());
+ *value = sf->authenticateSurface(mSurface) ? 1 : 0;
+ return NO_ERROR;
}
return BAD_VALUE;
}
diff --git a/libs/surfaceflinger_client/tests/Android.mk b/libs/surfaceflinger_client/tests/Android.mk
index 5053e7d..212b8e7 100644
--- a/libs/surfaceflinger_client/tests/Android.mk
+++ b/libs/surfaceflinger_client/tests/Android.mk
@@ -1 +1,53 @@
+# Build the unit tests.
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+ifneq ($(TARGET_SIMULATOR),true)
+
+# Build the unit tests.
+test_src_files := \
+ Surface_test.cpp \
+
+shared_libraries := \
+ libcutils \
+ libutils \
+ libbinder \
+ libsurfaceflinger_client \
+ libstlport \
+
+static_libraries := \
+ libgtest \
+ libgtest_main \
+
+c_includes := \
+ bionic \
+ bionic/libstdc++/include \
+ external/gtest/include \
+ external/stlport/stlport \
+
+module_tags := tests
+
+$(foreach file,$(test_src_files), \
+ $(eval include $(CLEAR_VARS)) \
+ $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
+ $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \
+ $(eval LOCAL_C_INCLUDES := $(c_includes)) \
+ $(eval LOCAL_SRC_FILES := $(file)) \
+ $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
+ $(eval LOCAL_MODULE_TAGS := $(module_tags)) \
+ $(eval include $(BUILD_EXECUTABLE)) \
+)
+
+# Build the manual test programs.
include $(call all-subdir-makefiles)
+
+endif
+
+# Include subdirectory makefiles
+# ============================================================
+
+# If we're building with ONE_SHOT_MAKEFILE (mm, mmm), then what the framework
+# team really wants is to build the stuff defined by this makefile.
+ifeq (,$(ONE_SHOT_MAKEFILE))
+include $(call first-makefiles-under,$(LOCAL_PATH))
+endif
diff --git a/libs/surfaceflinger_client/tests/Surface_test.cpp b/libs/surfaceflinger_client/tests/Surface_test.cpp
new file mode 100644
index 0000000..74ebf4e
--- /dev/null
+++ b/libs/surfaceflinger_client/tests/Surface_test.cpp
@@ -0,0 +1,133 @@
+/*
+ * 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.
+ */
+
+#include <gtest/gtest.h>
+
+#include <binder/IMemory.h>
+#include <surfaceflinger/ISurfaceComposer.h>
+#include <surfaceflinger/Surface.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
+#include <utils/String8.h>
+
+namespace android {
+
+class SurfaceTest : public ::testing::Test {
+protected:
+ virtual void SetUp() {
+ mComposerClient = new SurfaceComposerClient;
+ ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
+
+ mSurfaceControl = mComposerClient->createSurface(getpid(),
+ String8("Test Surface"), 0, 32, 32, PIXEL_FORMAT_RGB_888, 0);
+
+ ASSERT_TRUE(mSurfaceControl != NULL);
+ ASSERT_TRUE(mSurfaceControl->isValid());
+
+ ASSERT_EQ(NO_ERROR, mComposerClient->openTransaction());
+ ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(30000));
+ ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
+ ASSERT_EQ(NO_ERROR, mComposerClient->closeTransaction());
+
+ mSurface = mSurfaceControl->getSurface();
+ ASSERT_TRUE(mSurface != NULL);
+ }
+
+ virtual void TearDown() {
+ mComposerClient->dispose();
+ }
+
+ sp<Surface> mSurface;
+ sp<SurfaceComposerClient> mComposerClient;
+ sp<SurfaceControl> mSurfaceControl;
+};
+
+TEST_F(SurfaceTest, QueuesToWindowComposerIsTrueWhenVisible) {
+ sp<ANativeWindow> anw(mSurface);
+ int result = -123;
+ int err = anw->query(anw.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
+ &result);
+ EXPECT_EQ(NO_ERROR, err);
+ EXPECT_EQ(1, result);
+}
+
+TEST_F(SurfaceTest, QueuesToWindowComposerIsTrueWhenPurgatorized) {
+ mSurfaceControl.clear();
+
+ sp<ANativeWindow> anw(mSurface);
+ int result = -123;
+ int err = anw->query(anw.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
+ &result);
+ EXPECT_EQ(NO_ERROR, err);
+ EXPECT_EQ(1, result);
+}
+
+// This test probably doesn't belong here.
+TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersFail) {
+ sp<ANativeWindow> anw(mSurface);
+
+ // Verify the screenshot works with no protected buffers.
+ sp<IMemoryHeap> heap;
+ uint32_t w=0, h=0;
+ PixelFormat fmt=0;
+ sp<ISurfaceComposer> sf(ComposerService::getComposerService());
+ ASSERT_EQ(NO_ERROR, sf->captureScreen(0, &heap, &w, &h, &fmt, 64, 64, 0,
+ 40000));
+ ASSERT_TRUE(heap != NULL);
+
+ // Set the PROTECTED usage bit and verify that the screenshot fails. Note
+ // that we need to dequeue a buffer in order for it to actually get
+ // allocated in SurfaceFlinger.
+ ASSERT_EQ(NO_ERROR, native_window_set_usage(anw.get(),
+ GRALLOC_USAGE_PROTECTED));
+ ASSERT_EQ(NO_ERROR, native_window_set_buffer_count(anw.get(), 3));
+ android_native_buffer_t* buf = 0;
+ for (int i = 0; i < 4; i++) {
+ // Loop to make sure SurfaceFlinger has retired a protected buffer.
+ ASSERT_EQ(NO_ERROR, anw->dequeueBuffer(anw.get(), &buf));
+ ASSERT_EQ(NO_ERROR, anw->lockBuffer(anw.get(), buf));
+ ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf));
+ }
+ heap = 0;
+ w = h = fmt = 0;
+ ASSERT_EQ(INVALID_OPERATION, sf->captureScreen(0, &heap, &w, &h, &fmt,
+ 64, 64, 0, 40000));
+ ASSERT_TRUE(heap == NULL);
+
+ // XXX: This should not be needed, but it seems that the new buffers don't
+ // correctly show up after the upcoming dequeue/lock/queue loop without it.
+ // We should look into this at some point.
+ ASSERT_EQ(NO_ERROR, native_window_set_buffer_count(anw.get(), 3));
+
+ // Un-set the PROTECTED usage bit and verify that the screenshot works
+ // again. Note that we have to change the buffers geometry to ensure that
+ // the buffers get reallocated, as the new usage bits are a subset of the
+ // old.
+ ASSERT_EQ(NO_ERROR, native_window_set_usage(anw.get(), 0));
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(anw.get(), 32, 32, 0));
+ for (int i = 0; i < 4; i++) {
+ // Loop to make sure SurfaceFlinger has retired a protected buffer.
+ ASSERT_EQ(NO_ERROR, anw->dequeueBuffer(anw.get(), &buf));
+ ASSERT_EQ(NO_ERROR, anw->lockBuffer(anw.get(), buf));
+ ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf));
+ }
+ heap = 0;
+ w = h = fmt = 0;
+ ASSERT_EQ(NO_ERROR, sf->captureScreen(0, &heap, &w, &h, &fmt, 64, 64, 0,
+ 40000));
+ ASSERT_TRUE(heap != NULL);
+}
+
+}
diff --git a/libs/ui/Input.cpp b/libs/ui/Input.cpp
index 0ed0866..e2e698e 100644
--- a/libs/ui/Input.cpp
+++ b/libs/ui/Input.cpp
@@ -657,23 +657,30 @@
mMotionRanges.clear();
}
-const InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange(int32_t axis) const {
- ssize_t index = mMotionRanges.indexOfKey(axis);
- return index >= 0 ? & mMotionRanges.valueAt(index) : NULL;
+const InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange(
+ int32_t axis, uint32_t source) const {
+ size_t numRanges = mMotionRanges.size();
+ for (size_t i = 0; i < numRanges; i++) {
+ const MotionRange& range = mMotionRanges.itemAt(i);
+ if (range.axis == axis && range.source == source) {
+ return ⦥
+ }
+ }
+ return NULL;
}
void InputDeviceInfo::addSource(uint32_t source) {
mSources |= source;
}
-void InputDeviceInfo::addMotionRange(int32_t axis, float min, float max,
+void InputDeviceInfo::addMotionRange(int32_t axis, uint32_t source, float min, float max,
float flat, float fuzz) {
- MotionRange range = { min, max, flat, fuzz };
- addMotionRange(axis, range);
+ MotionRange range = { axis, source, min, max, flat, fuzz };
+ mMotionRanges.add(range);
}
-void InputDeviceInfo::addMotionRange(int32_t axis, const MotionRange& range) {
- mMotionRanges.add(axis, range);
+void InputDeviceInfo::addMotionRange(const MotionRange& range) {
+ mMotionRanges.add(range);
}
} // namespace android
diff --git a/libs/ui/KeyLayoutMap.cpp b/libs/ui/KeyLayoutMap.cpp
index 2ed0e66..8626a03 100644
--- a/libs/ui/KeyLayoutMap.cpp
+++ b/libs/ui/KeyLayoutMap.cpp
@@ -113,20 +113,23 @@
return NO_ERROR;
}
-status_t KeyLayoutMap::mapAxis(int32_t scanCode, int32_t* axis) const {
+status_t KeyLayoutMap::mapAxis(int32_t scanCode, AxisInfo* outAxisInfo) const {
ssize_t index = mAxes.indexOfKey(scanCode);
if (index < 0) {
#if DEBUG_MAPPING
LOGD("mapAxis: scanCode=%d ~ Failed.", scanCode);
#endif
- *axis = -1;
return NAME_NOT_FOUND;
}
- *axis = mAxes.valueAt(index);
+ *outAxisInfo = mAxes.valueAt(index);
#if DEBUG_MAPPING
- LOGD("mapAxis: scanCode=%d ~ Result axis=%d.", scanCode, *axis);
+ LOGD("mapAxis: scanCode=%d ~ Result mode=%d, axis=%d, highAxis=%d, "
+ "splitValue=%d, flatOverride=%d.",
+ scanCode,
+ outAxisInfo->mode, outAxisInfo->axis, outAxisInfo->highAxis,
+ outAxisInfo->splitValue, outAxisInfo->flatOverride);
#endif
return NO_ERROR;
}
@@ -249,19 +252,89 @@
return BAD_VALUE;
}
+ AxisInfo axisInfo;
+
mTokenizer->skipDelimiters(WHITESPACE);
- String8 axisToken = mTokenizer->nextToken(WHITESPACE);
- int32_t axis = getAxisByLabel(axisToken.string());
- if (axis < 0) {
- LOGE("%s: Expected axis label, got '%s'.", mTokenizer->getLocation().string(),
- axisToken.string());
- return BAD_VALUE;
+ String8 token = mTokenizer->nextToken(WHITESPACE);
+ if (token == "invert") {
+ axisInfo.mode = AxisInfo::MODE_INVERT;
+
+ mTokenizer->skipDelimiters(WHITESPACE);
+ String8 axisToken = mTokenizer->nextToken(WHITESPACE);
+ axisInfo.axis = getAxisByLabel(axisToken.string());
+ if (axisInfo.axis < 0) {
+ LOGE("%s: Expected inverted axis label, got '%s'.",
+ mTokenizer->getLocation().string(), axisToken.string());
+ return BAD_VALUE;
+ }
+ } else if (token == "split") {
+ axisInfo.mode = AxisInfo::MODE_SPLIT;
+
+ mTokenizer->skipDelimiters(WHITESPACE);
+ String8 splitToken = mTokenizer->nextToken(WHITESPACE);
+ axisInfo.splitValue = int32_t(strtol(splitToken.string(), &end, 0));
+ if (*end) {
+ LOGE("%s: Expected split value, got '%s'.",
+ mTokenizer->getLocation().string(), splitToken.string());
+ return BAD_VALUE;
+ }
+
+ mTokenizer->skipDelimiters(WHITESPACE);
+ String8 lowAxisToken = mTokenizer->nextToken(WHITESPACE);
+ axisInfo.axis = getAxisByLabel(lowAxisToken.string());
+ if (axisInfo.axis < 0) {
+ LOGE("%s: Expected low axis label, got '%s'.",
+ mTokenizer->getLocation().string(), lowAxisToken.string());
+ return BAD_VALUE;
+ }
+
+ mTokenizer->skipDelimiters(WHITESPACE);
+ String8 highAxisToken = mTokenizer->nextToken(WHITESPACE);
+ axisInfo.highAxis = getAxisByLabel(highAxisToken.string());
+ if (axisInfo.highAxis < 0) {
+ LOGE("%s: Expected high axis label, got '%s'.",
+ mTokenizer->getLocation().string(), highAxisToken.string());
+ return BAD_VALUE;
+ }
+ } else {
+ axisInfo.axis = getAxisByLabel(token.string());
+ if (axisInfo.axis < 0) {
+ LOGE("%s: Expected axis label, 'split' or 'invert', got '%s'.",
+ mTokenizer->getLocation().string(), token.string());
+ return BAD_VALUE;
+ }
+ }
+
+ for (;;) {
+ mTokenizer->skipDelimiters(WHITESPACE);
+ if (mTokenizer->isEol()) {
+ break;
+ }
+ String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
+ if (keywordToken == "flat") {
+ mTokenizer->skipDelimiters(WHITESPACE);
+ String8 flatToken = mTokenizer->nextToken(WHITESPACE);
+ axisInfo.flatOverride = int32_t(strtol(flatToken.string(), &end, 0));
+ if (*end) {
+ LOGE("%s: Expected flat value, got '%s'.",
+ mTokenizer->getLocation().string(), flatToken.string());
+ return BAD_VALUE;
+ }
+ } else {
+ LOGE("%s: Expected keyword 'flat', got '%s'.",
+ mTokenizer->getLocation().string(), keywordToken.string());
+ return BAD_VALUE;
+ }
}
#if DEBUG_PARSER
- LOGD("Parsed axis: scanCode=%d, axis=%d.", scanCode, axis);
+ LOGD("Parsed axis: scanCode=%d, mode=%d, axis=%d, highAxis=%d, "
+ "splitValue=%d, flatOverride=%d.",
+ scanCode,
+ axisInfo.mode, axisInfo.axis, axisInfo.highAxis,
+ axisInfo.splitValue, axisInfo.flatOverride);
#endif
- mMap->mAxes.add(scanCode, axis);
+ mMap->mAxes.add(scanCode, axisInfo);
return NO_ERROR;
}
diff --git a/libs/usb/Android.mk b/libs/usb/Android.mk
index b4e1fbf..129828f 100644
--- a/libs/usb/Android.mk
+++ b/libs/usb/Android.mk
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2008 The Android Open Source Project
+# 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.
diff --git a/libs/usb/src/com/android/future/usb/UsbAccessory.java b/libs/usb/src/com/android/future/usb/UsbAccessory.java
index cdd2b73..3d0707f 100644
--- a/libs/usb/src/com/android/future/usb/UsbAccessory.java
+++ b/libs/usb/src/com/android/future/usb/UsbAccessory.java
@@ -23,14 +23,16 @@
private final String mManufacturer;
private final String mModel;
- private final String mType;
+ private final String mDescription;
private final String mVersion;
+ private final String mUri;
/* package */ UsbAccessory(android.hardware.usb.UsbAccessory accessory) {
mManufacturer = accessory.getManufacturer();
mModel = accessory.getModel();
- mType = accessory.getType();
+ mDescription = accessory.getDescription();
mVersion = accessory.getVersion();
+ mUri = accessory.getUri();
}
/**
@@ -52,12 +54,12 @@
}
/**
- * Returns the type of the accessory.
+ * Returns a user visible description of the accessory.
*
- * @return the accessory type
+ * @return the accessory description
*/
- public String getType() {
- return mType;
+ public String getDescription() {
+ return mDescription;
}
/**
@@ -69,6 +71,17 @@
return mVersion;
}
+ /**
+ * Returns the URI for the accessory.
+ * This is an optional URI that might show information about the accessory
+ * or provide the option to download an application for the accessory
+ *
+ * @return the accessory URI
+ */
+ public String getUri() {
+ return mUri;
+ }
+
private static boolean compare(String s1, String s2) {
if (s1 == null) return (s2 == null);
return s1.equals(s2);
@@ -80,17 +93,28 @@
UsbAccessory accessory = (UsbAccessory)obj;
return (compare(mManufacturer, accessory.getManufacturer()) &&
compare(mModel, accessory.getModel()) &&
- compare(mType, accessory.getType()) &&
- compare(mVersion, accessory.getVersion()));
+ compare(mDescription, accessory.getDescription()) &&
+ compare(mVersion, accessory.getVersion()) &&
+ compare(mUri, accessory.getUri()));
}
return false;
}
@Override
+ public int hashCode() {
+ return ((mManufacturer == null ? 0 : mManufacturer.hashCode()) ^
+ (mModel == null ? 0 : mModel.hashCode()) ^
+ (mDescription == null ? 0 : mDescription.hashCode()) ^
+ (mVersion == null ? 0 : mVersion.hashCode()) ^
+ (mUri == null ? 0 : mUri.hashCode()));
+ }
+
+ @Override
public String toString() {
return "UsbAccessory[mManufacturer=" + mManufacturer +
", mModel=" + mModel +
- ", mType=" + mType +
- ", mVersion=" + mVersion + "]";
+ ", mDescription=" + mDescription +
+ ", mVersion=" + mVersion +
+ ", mUri=" + mUri + "]";
}
}
diff --git a/libs/usb/src/com/android/future/usb/UsbManager.java b/libs/usb/src/com/android/future/usb/UsbManager.java
index f74b291..840e1e3 100644
--- a/libs/usb/src/com/android/future/usb/UsbManager.java
+++ b/libs/usb/src/com/android/future/usb/UsbManager.java
@@ -17,6 +17,7 @@
package com.android.future.usb;
+import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.hardware.usb.IUsbManager;
@@ -55,28 +56,39 @@
public static final String ACTION_USB_ACCESSORY_DETACHED =
"android.hardware.usb.action.USB_ACCESSORY_DETACHED";
+ /**
+ * Name of extra added to the {@link android.app.PendingIntent}
+ * passed into {#requestPermission} or {#requestPermission}
+ * containing a boolean value indicating whether the user granted permission or not.
+ */
+ public static final String EXTRA_PERMISSION_GRANTED = "permission";
+
+ private final Context mContext;
private final IUsbManager mService;
- private UsbManager(IUsbManager service) {
+ private UsbManager(Context context, IUsbManager service) {
+ mContext = context;
mService = service;
}
/**
* Returns a new instance of this class.
*
+ * @param context the caller's {@link android.content.Context}
* @return UsbManager instance.
*/
- public static UsbManager getInstance() {
+ public static UsbManager getInstance(Context context) {
IBinder b = ServiceManager.getService(Context.USB_SERVICE);
- return new UsbManager(IUsbManager.Stub.asInterface(b));
+ return new UsbManager(context, IUsbManager.Stub.asInterface(b));
}
/**
* Returns the {@link com.google.android.usb.UsbAccessory} for
* a {@link #ACTION_USB_ACCESSORY_ATTACHED} or {@link #ACTION_USB_ACCESSORY_ATTACHED}
- * broadcast Intent
+ * broadcast Intent. This can also be used to retrieve the accessory from the result
+ * of a call to {#requestPermission}.
*
- * @return UsbAccessory for the broadcast.
+ * @return UsbAccessory for the intent.
*/
public static UsbAccessory getAccessory(Intent intent) {
android.hardware.usb.UsbAccessory accessory =
@@ -118,10 +130,54 @@
try {
return mService.openAccessory(new android.hardware.usb.UsbAccessory(
accessory.getManufacturer(),accessory.getModel(),
- accessory.getType(), accessory.getVersion()));
+ accessory.getDescription(), accessory.getVersion(), accessory.getUri()));
} catch (RemoteException e) {
Log.e(TAG, "RemoteException in openAccessory" , e);
return null;
}
}
+
+ /**
+ * Returns true if the caller has permission to access the accessory.
+ * Permission might have been granted temporarily via
+ * {@link #requestPermission(android.hardware.usb.UsbAccessory} or
+ * by the user choosing the caller as the default application for the accessory.
+ *
+ * @param accessory to check permissions for
+ * @return true if caller has permission
+ */
+ public boolean hasPermission(UsbAccessory accessory) {
+ try {
+ return mService.hasAccessoryPermission(new android.hardware.usb.UsbAccessory(
+ accessory.getManufacturer(),accessory.getModel(),
+ accessory.getDescription(), accessory.getVersion(), accessory.getUri()));
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in hasPermission", e);
+ return false;
+ }
+ }
+
+ /**
+ * Requests temporary permission for the given package to access the accessory.
+ * This may result in a system dialog being displayed to the user
+ * if permission had not already been granted.
+ * Success or failure is returned via the {@link android.app.PendingIntent} pi.
+ * The boolean extra {@link #EXTRA_PERMISSION_GRANTED} will be attached to the
+ * PendingIntent to indicate success or failure.
+ * If successful, this grants the caller permission to access the device only
+ * until the device is disconnected.
+ *
+ * @param accessory to request permissions for
+ * @param pi PendingIntent for returning result
+ */
+ public void requestPermission(UsbAccessory accessory, PendingIntent pi) {
+ try {
+ mService.requestAccessoryPermission(new android.hardware.usb.UsbAccessory(
+ accessory.getManufacturer(),accessory.getModel(),
+ accessory.getDescription(), accessory.getVersion(), accessory.getUri()),
+ mContext.getPackageName(), pi);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in requestPermission", e);
+ }
+ }
}
diff --git a/libs/usb/tests/AccessoryChat/Android.mk b/libs/usb/tests/AccessoryChat/Android.mk
index 98b6090..d555961 100644
--- a/libs/usb/tests/AccessoryChat/Android.mk
+++ b/libs/usb/tests/AccessoryChat/Android.mk
@@ -1,3 +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.
+#
+
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
diff --git a/libs/usb/tests/AccessoryChat/AndroidManifest.xml b/libs/usb/tests/AccessoryChat/AndroidManifest.xml
index 97e2ade..d6093ae 100644
--- a/libs/usb/tests/AccessoryChat/AndroidManifest.xml
+++ b/libs/usb/tests/AccessoryChat/AndroidManifest.xml
@@ -1,3 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.accessorychat">
diff --git a/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c b/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c
index 94cc0ce..3c0de69 100644
--- a/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c
+++ b/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c
@@ -133,10 +133,19 @@
} else {
printf("Found possible android device - attempting to switch to accessory mode\n");
+ uint16_t protocol;
+ ret = usb_device_control_transfer(device, USB_DIR_IN | USB_TYPE_VENDOR,
+ ACCESSORY_GET_PROTOCOL, 0, 0, &protocol, sizeof(protocol), 0);
+ if (ret == 2)
+ printf("device supports protocol version %d\n", protocol);
+ else
+ fprintf(stderr, "failed to read protocol version\n");
+
send_string(device, ACCESSORY_STRING_MANUFACTURER, "Google, Inc.");
send_string(device, ACCESSORY_STRING_MODEL, "AccessoryChat");
- send_string(device, ACCESSORY_STRING_TYPE, "Sample Program");
+ send_string(device, ACCESSORY_STRING_DESCRIPTION, "Sample Program");
send_string(device, ACCESSORY_STRING_VERSION, "1.0");
+ send_string(device, ACCESSORY_STRING_URI, "http://www.android.com");
ret = usb_device_control_transfer(device, USB_DIR_OUT | USB_TYPE_VENDOR,
ACCESSORY_START, 0, 0, 0, 0, 0);
diff --git a/libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java b/libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java
index 5cf02c7..f9a5bf4 100644
--- a/libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java
+++ b/libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java
@@ -17,9 +17,11 @@
package com.android.accessorychat;
import android.app.Activity;
+import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
@@ -42,18 +44,47 @@
public class AccessoryChat extends Activity implements Runnable, TextView.OnEditorActionListener {
private static final String TAG = "AccessoryChat";
- TextView mLog;
- EditText mEditText;
- ParcelFileDescriptor mFileDescriptor;
- FileInputStream mInputStream;
- FileOutputStream mOutputStream;
+
+ private static final String ACTION_USB_PERMISSION =
+ "com.android.accessorychat.action.USB_PERMISSION";
+
+ private TextView mLog;
+ private EditText mEditText;
+ private ParcelFileDescriptor mFileDescriptor;
+ private FileInputStream mInputStream;
+ private FileOutputStream mOutputStream;
+ private UsbManager mUsbManager;
+ private PendingIntent mPermissionIntent;
+ private boolean mPermissionRequestPending;
private static final int MESSAGE_LOG = 1;
+ private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (ACTION_USB_PERMISSION.equals(intent.getAction())) {
+ synchronized (this) {
+ UsbAccessory accessory = UsbManager.getAccessory(intent);
+ if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
+ openAccessory(accessory);
+ } else {
+ Log.d(TAG, "permission denied for accessory " + accessory);
+ }
+ mPermissionRequestPending = false;
+ }
+ }
+ }
+ };
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ mUsbManager = UsbManager.getInstance(this);
+ mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
+ IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
+ registerReceiver(mUsbReceiver, filter);
+
setContentView(R.layout.accessory_chat);
mLog = (TextView)findViewById(R.id.log);
mEditText = (EditText)findViewById(R.id.message);
@@ -66,21 +97,20 @@
Intent intent = getIntent();
Log.d(TAG, "intent: " + intent);
- UsbManager manager = UsbManager.getInstance();
- UsbAccessory[] accessories = manager.getAccessoryList();
+ UsbAccessory[] accessories = mUsbManager.getAccessoryList();
UsbAccessory accessory = (accessories == null ? null : accessories[0]);
if (accessory != null) {
- mFileDescriptor = manager.openAccessory(accessory);
- if (mFileDescriptor != null) {
- FileDescriptor fd = mFileDescriptor.getFileDescriptor();
- mInputStream = new FileInputStream(fd);
- mOutputStream = new FileOutputStream(fd);
- Thread thread = new Thread(null, this, "AccessoryChat");
- thread.start();
+ if (mUsbManager.hasPermission(accessory)) {
+ openAccessory(accessory);
} else {
- Log.d(TAG, "openAccessory fail");
+ synchronized (mUsbReceiver) {
+ if (!mPermissionRequestPending) {
+ mUsbManager.requestPermission(accessory, mPermissionIntent);
+ mPermissionRequestPending = true;
+ }
+ }
}
- } else {
+ } else {
Log.d(TAG, "mAccessory is null");
}
}
@@ -100,9 +130,24 @@
@Override
public void onDestroy() {
+ unregisterReceiver(mUsbReceiver);
super.onDestroy();
}
+ private void openAccessory(UsbAccessory accessory) {
+ mFileDescriptor = mUsbManager.openAccessory(accessory);
+ if (mFileDescriptor != null) {
+ FileDescriptor fd = mFileDescriptor.getFileDescriptor();
+ mInputStream = new FileInputStream(fd);
+ mOutputStream = new FileOutputStream(fd);
+ Thread thread = new Thread(null, this, "AccessoryChat");
+ thread.start();
+ Log.d(TAG, "openAccessory succeeded");
+ } else {
+ Log.d(TAG, "openAccessory fail");
+ }
+ }
+
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE && mOutputStream != null) {
try {
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 5a73d2d..fd12e19 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -805,7 +805,7 @@
if (mode != mMode) {
// automatically handle audio focus for mode changes
- handleFocusForCalls(mMode, mode);
+ handleFocusForCalls(mMode, mode, cb);
if (AudioSystem.setPhoneState(mode) == AudioSystem.AUDIO_STATUS_OK) {
mMode = mode;
@@ -864,7 +864,7 @@
}
/** pre-condition: oldMode != newMode */
- private void handleFocusForCalls(int oldMode, int newMode) {
+ private void handleFocusForCalls(int oldMode, int newMode, IBinder cb) {
// if ringing
if (newMode == AudioSystem.MODE_RINGTONE) {
// if not ringing silently
@@ -872,8 +872,8 @@
if (ringVolume > 0) {
// request audio focus for the communication focus entry
requestAudioFocus(AudioManager.STREAM_RING,
- AudioManager.AUDIOFOCUS_GAIN_TRANSIENT,
- null, null /* both allowed to be null only for this clientId */,
+ AudioManager.AUDIOFOCUS_GAIN_TRANSIENT, cb,
+ null /* IAudioFocusDispatcher allowed to be null only for this clientId */,
IN_VOICE_COMM_FOCUS_ID /*clientId*/);
}
@@ -884,8 +884,8 @@
// request audio focus for the communication focus entry
// (it's ok if focus was already requested during ringing)
requestAudioFocus(AudioManager.STREAM_RING,
- AudioManager.AUDIOFOCUS_GAIN_TRANSIENT,
- null, null /* both allowed to be null only for this clientId */,
+ AudioManager.AUDIOFOCUS_GAIN_TRANSIENT, cb,
+ null /* IAudioFocusDispatcher allowed to be null only for this clientId */,
IN_VOICE_COMM_FOCUS_ID /*clientId*/);
}
// if exiting call
@@ -2547,10 +2547,9 @@
// the main stream type for the audio focus request is currently not used. It may
// potentially be used to handle multiple stream type-dependent audio focuses.
- // we need a valid binder callback for clients other than the AudioService's phone
- // state listener
- if (!IN_VOICE_COMM_FOCUS_ID.equals(clientId) && ((cb == null) || !cb.pingBinder())) {
- Log.i(TAG, " AudioFocus DOA client for requestAudioFocus(), exiting");
+ // we need a valid binder callback for clients
+ if (!cb.pingBinder()) {
+ Log.e(TAG, " AudioFocus DOA client for requestAudioFocus(), aborting.");
return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
}
@@ -2591,17 +2590,14 @@
}//synchronized(mAudioFocusLock)
// handle the potential premature death of the new holder of the focus
- // (premature death == death before abandoning focus) for a client which is not the
- // AudioService's phone state listener
- if (!IN_VOICE_COMM_FOCUS_ID.equals(clientId)) {
- // Register for client death notification
- AudioFocusDeathHandler afdh = new AudioFocusDeathHandler(cb);
- try {
- cb.linkToDeath(afdh, 0);
- } catch (RemoteException e) {
- // client has already died!
- Log.w(TAG, "AudioFocus requestAudioFocus() could not link to "+cb+" binder death");
- }
+ // (premature death == death before abandoning focus)
+ // Register for client death notification
+ AudioFocusDeathHandler afdh = new AudioFocusDeathHandler(cb);
+ try {
+ cb.linkToDeath(afdh, 0);
+ } catch (RemoteException e) {
+ // client has already died!
+ Log.w(TAG, "AudioFocus requestAudioFocus() could not link to "+cb+" binder death");
}
return AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java
index 77e939e..13e1732 100644
--- a/media/java/android/media/MediaMetadataRetriever.java
+++ b/media/java/android/media/MediaMetadataRetriever.java
@@ -398,5 +398,25 @@
* The metadata key to retrieve the music album compilation status.
*/
public static final int METADATA_KEY_COMPILATION = 15;
+ /**
+ * If this key exists the media contains audio content.
+ */
+ public static final int METADATA_KEY_HAS_AUDIO = 16;
+ /**
+ * If this key exists the media contains video content.
+ */
+ public static final int METADATA_KEY_HAS_VIDEO = 17;
+ /**
+ * If the media contains video, this key retrieves its width.
+ */
+ public static final int METADATA_KEY_VIDEO_WIDTH = 18;
+ /**
+ * If the media contains video, this key retrieves its height.
+ */
+ public static final int METADATA_KEY_VIDEO_HEIGHT = 19;
+ /**
+ * This key retrieves the average bitrate (in bits/sec), if available.
+ */
+ public static final int METADATA_KEY_BITRATE = 20;
// Add more here...
}
diff --git a/media/java/android/media/videoeditor/AudioTrack.java b/media/java/android/media/videoeditor/AudioTrack.java
index b2f547b..7069b23 100755
--- a/media/java/android/media/videoeditor/AudioTrack.java
+++ b/media/java/android/media/videoeditor/AudioTrack.java
@@ -140,7 +140,7 @@
try {
properties = mMANativeHelper.getMediaProperties(filename);
} catch (Exception e) {
- throw new IllegalArgumentException("Unsupported file or file not found");
+ throw new IllegalArgumentException(e.getMessage() + " : " + filename);
}
switch (mMANativeHelper.getFileType(properties.fileType)) {
case MediaProperties.FILE_3GP:
diff --git a/media/java/android/media/videoeditor/MediaVideoItem.java b/media/java/android/media/videoeditor/MediaVideoItem.java
index c91d796..4758de6 100755
--- a/media/java/android/media/videoeditor/MediaVideoItem.java
+++ b/media/java/android/media/videoeditor/MediaVideoItem.java
@@ -115,7 +115,7 @@
try {
properties = mMANativeHelper.getMediaProperties(filename);
} catch ( Exception e) {
- throw new IllegalArgumentException("Unsupported file or file not found: " + filename);
+ throw new IllegalArgumentException(e.getMessage() + " : " + filename);
}
switch (mMANativeHelper.getFileType(properties.fileType)) {
diff --git a/media/java/android/media/videoeditor/Transition.java b/media/java/android/media/videoeditor/Transition.java
index 3e8fe94..fa9d26d 100755
--- a/media/java/android/media/videoeditor/Transition.java
+++ b/media/java/android/media/videoeditor/Transition.java
@@ -131,6 +131,11 @@
if (durationMs > getMaximumDuration()) {
throw new IllegalArgumentException("The duration is too large");
}
+ if (afterMediaItem != null) {
+ mNativeHelper = afterMediaItem.getNativeContext();
+ }else {
+ mNativeHelper = beforeMediaItem.getNativeContext();
+ }
}
/**
diff --git a/media/java/android/media/videoeditor/TransitionAlpha.java b/media/java/android/media/videoeditor/TransitionAlpha.java
index f7d17cb..22788d4 100755
--- a/media/java/android/media/videoeditor/TransitionAlpha.java
+++ b/media/java/android/media/videoeditor/TransitionAlpha.java
@@ -104,13 +104,6 @@
mWidth = dbo.outWidth;
mHeight = dbo.outHeight;
- if (afterMediaItem != null) {
- mNativeHelper = afterMediaItem.getNativeContext();
- }else {
- mNativeHelper = beforeMediaItem.getNativeContext();
- }
-
-
mRGBMaskFile = String.format(mNativeHelper.getProjectPath() +
"/" + "mask" + transitionId+ ".rgb");
diff --git a/media/java/android/mtp/MtpConstants.java b/media/java/android/mtp/MtpConstants.java
index ad67bb9..d245f588 100644
--- a/media/java/android/mtp/MtpConstants.java
+++ b/media/java/android/mtp/MtpConstants.java
@@ -271,7 +271,7 @@
/**
* Returns true if the object is abstract (that is, it has no representation
- * in the underlying file system.
+ * in the underlying file system).
*
* @param format the format of the object
* @return true if the object is abstract
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index 98de2f7..b4a4689 100644
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -20,6 +20,7 @@
import android.content.ContentValues;
import android.content.IContentProvider;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.media.MediaScanner;
@@ -62,8 +63,8 @@
// true if the database has been modified in the current MTP session
private boolean mDatabaseModified;
- // database for writable MTP device properties
- private SQLiteDatabase mDevicePropDb;
+ // SharedPreferences for writable MTP device properties
+ private SharedPreferences mDeviceProperties;
private static final int DEVICE_PROPERTIES_DATABASE_VERSION = 1;
// FIXME - this should be passed in via the constructor
@@ -96,9 +97,6 @@
private static final String PARENT_FORMAT_WHERE = PARENT_WHERE + " AND "
+ Files.FileColumns.FORMAT + "=?";
- private static final String[] DEVICE_PROPERTY_PROJECTION = new String[] { "_id", "value" };
- private static final String DEVICE_PROPERTY_WHERE = "code=?";
-
private final MediaScanner mMediaScanner;
static {
@@ -114,7 +112,7 @@
mMediaStoragePath = storagePath;
mObjectsUri = Files.getMtpObjectsUri(volumeName);
mMediaScanner = new MediaScanner(context);
- openDevicePropertiesDatabase(context);
+ initDeviceProperties(context);
}
@Override
@@ -126,19 +124,38 @@
}
}
- private void openDevicePropertiesDatabase(Context context) {
- mDevicePropDb = context.openOrCreateDatabase("device-properties", Context.MODE_PRIVATE, null);
- int version = mDevicePropDb.getVersion();
+ private void initDeviceProperties(Context context) {
+ final String devicePropertiesName = "device-properties";
+ mDeviceProperties = context.getSharedPreferences(devicePropertiesName, Context.MODE_PRIVATE);
+ File databaseFile = context.getDatabasePath(devicePropertiesName);
- // initialize if necessary
- if (version != DEVICE_PROPERTIES_DATABASE_VERSION) {
- mDevicePropDb.execSQL("CREATE TABLE properties (" +
- "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
- "code INTEGER UNIQUE ON CONFLICT REPLACE," +
- "value TEXT" +
- ");");
- mDevicePropDb.execSQL("CREATE INDEX property_index ON properties (code);");
- mDevicePropDb.setVersion(DEVICE_PROPERTIES_DATABASE_VERSION);
+ if (databaseFile.exists()) {
+ // for backward compatibility - read device properties from sqlite database
+ // and migrate them to shared prefs
+ SQLiteDatabase db = null;
+ Cursor c = null;
+ try {
+ db = context.openOrCreateDatabase("device-properties", Context.MODE_PRIVATE, null);
+ if (db != null) {
+ c = db.query("properties", new String[] { "_id", "code", "value" },
+ null, null, null, null, null);
+ if (c != null) {
+ SharedPreferences.Editor e = mDeviceProperties.edit();
+ while (c.moveToNext()) {
+ String name = c.getString(1);
+ String value = c.getString(2);
+ e.putString(name, value);
+ }
+ e.commit();
+ }
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "failed to migrate device properties", e);
+ } finally {
+ if (c != null) c.close();
+ if (db != null) db.close();
+ }
+ databaseFile.delete();
}
}
@@ -567,30 +584,15 @@
switch (property) {
case MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER:
case MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME:
- // writable string properties kept in our device property database
- Cursor c = null;
- try {
- c = mDevicePropDb.query("properties", DEVICE_PROPERTY_PROJECTION,
- DEVICE_PROPERTY_WHERE, new String[] { Integer.toString(property) },
- null, null, null);
-
- if (c != null && c.moveToNext()) {
- String value = c.getString(1);
- int length = value.length();
- if (length > 255) {
- length = 255;
- }
- value.getChars(0, length, outStringValue, 0);
- outStringValue[length] = 0;
- } else {
- outStringValue[0] = 0;
- }
- return MtpConstants.RESPONSE_OK;
- } finally {
- if (c != null) {
- c.close();
- }
+ // writable string properties kept in shared preferences
+ String value = mDeviceProperties.getString(Integer.toString(property), "");
+ int length = value.length();
+ if (length > 255) {
+ length = 255;
}
+ value.getChars(0, length, outStringValue, 0);
+ outStringValue[length] = 0;
+ return MtpConstants.RESPONSE_OK;
case MtpConstants.DEVICE_PROPERTY_IMAGE_SIZE:
// use screen size as max image size
@@ -612,16 +614,11 @@
switch (property) {
case MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER:
case MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME:
- // writable string properties kept in our device property database
- try {
- ContentValues values = new ContentValues();
- values.put("code", property);
- values.put("value", stringValue);
- mDevicePropDb.insert("properties", "code", values);
- return MtpConstants.RESPONSE_OK;
- } catch (Exception e) {
- return MtpConstants.RESPONSE_GENERAL_ERROR;
- }
+ // writable string properties kept in shared prefs
+ SharedPreferences.Editor e = mDeviceProperties.edit();
+ e.putString(Integer.toString(property), stringValue);
+ return (e.commit() ? MtpConstants.RESPONSE_OK
+ : MtpConstants.RESPONSE_GENERAL_ERROR);
}
return MtpConstants.RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
diff --git a/media/java/android/mtp/MtpDevice.java b/media/java/android/mtp/MtpDevice.java
index 22961d7f..af37c9e 100644
--- a/media/java/android/mtp/MtpDevice.java
+++ b/media/java/android/mtp/MtpDevice.java
@@ -17,7 +17,7 @@
package android.mtp;
import android.hardware.usb.UsbDevice;
-import android.hardware.usb.UsbManager;
+import android.hardware.usb.UsbDeviceConnection;
import android.os.ParcelFileDescriptor;
import android.util.Log;
@@ -44,17 +44,20 @@
}
/**
- * Opens the MTP or PTP device and return an {@link android.mtp.MtpDevice} for it.
+ * Opens the MTP device. Once the device is open it takes ownership of the
+ * {@link android.hardware.usb.UsbDeviceConnection}.
+ * The connection will be closed when you call {@link #close()}
+ * The connection will also be closed if this method fails.
*
- * @param manager reference to {@link android.hardware.usb.UsbManager}
+ * @param connection an open {@link android.hardware.usb.UsbDeviceConnection} for the device
* @return true if the device was successfully opened.
*/
- public boolean open(UsbManager manager) {
- if (manager.openDevice(mDevice)) {
- return native_open(mDevice.getDeviceName(), mDevice.getFileDescriptor());
- } else {
- return false;
+ public boolean open(UsbDeviceConnection connection) {
+ boolean result = native_open(mDevice.getDeviceName(), connection.getFileDescriptor());
+ if (!result) {
+ connection.close();
}
+ return result;
}
/**
@@ -195,7 +198,7 @@
* @param objectHandle handle of the object to query
* @return the object's storage unit ID
*/
- public long getStorageID(int objectHandle) {
+ public long getStorageId(int objectHandle) {
return native_get_storage_id(objectHandle);
}
diff --git a/media/jni/android_media_MediaScanner.cpp b/media/jni/android_media_MediaScanner.cpp
index a5176fa..8bbb997 100644
--- a/media/jni/android_media_MediaScanner.cpp
+++ b/media/jni/android_media_MediaScanner.cpp
@@ -1,4 +1,4 @@
-/* //device/libs/media_jni/MediaScanner.cpp
+/*
**
** Copyright 2007, The Android Open Source Project
**
@@ -15,36 +15,36 @@
** limitations under the License.
*/
-#define LOG_TAG "MediaScanner"
-#include "utils/Log.h"
-
-#include <media/mediascanner.h>
-#include <stdio.h>
-#include <assert.h>
-#include <limits.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <cutils/properties.h>
+//#define LOG_NDEBUG 0
+#define LOG_TAG "MediaScannerJNI"
+#include <utils/Log.h>
#include <utils/threads.h>
+#include <media/mediascanner.h>
+#include <media/stagefright/StagefrightMediaScanner.h>
#include "jni.h"
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
-#include <media/stagefright/StagefrightMediaScanner.h>
-
-// ----------------------------------------------------------------------------
-
using namespace android;
-// ----------------------------------------------------------------------------
struct fields_t {
jfieldID context;
};
static fields_t fields;
-// ----------------------------------------------------------------------------
+static const char* const kClassMediaScannerClient =
+ "android/media/MediaScannerClient";
+
+static const char* const kClassMediaScanner =
+ "android/media/MediaScanner";
+
+static const char* const kRunTimeException =
+ "java/lang/RuntimeException";
+
+static const char* const kIllegalArgumentException =
+ "java/lang/IllegalArgumentException";
class MyMediaScannerClient : public MediaScannerClient
{
@@ -56,33 +56,53 @@
mHandleStringTagMethodID(0),
mSetMimeTypeMethodID(0)
{
- jclass mediaScannerClientInterface = env->FindClass("android/media/MediaScannerClient");
+ LOGV("MyMediaScannerClient constructor");
+ jclass mediaScannerClientInterface =
+ env->FindClass(kClassMediaScannerClient);
+
if (mediaScannerClientInterface == NULL) {
- fprintf(stderr, "android/media/MediaScannerClient not found\n");
- }
- else {
- mScanFileMethodID = env->GetMethodID(mediaScannerClientInterface, "scanFile",
- "(Ljava/lang/String;JJZ)V");
- mHandleStringTagMethodID = env->GetMethodID(mediaScannerClientInterface, "handleStringTag",
- "(Ljava/lang/String;Ljava/lang/String;)V");
- mSetMimeTypeMethodID = env->GetMethodID(mediaScannerClientInterface, "setMimeType",
- "(Ljava/lang/String;)V");
- mAddNoMediaFolderMethodID = env->GetMethodID(mediaScannerClientInterface, "addNoMediaFolder",
- "(Ljava/lang/String;)V");
+ LOGE("Class %s not found", kClassMediaScannerClient);
+ } else {
+ mScanFileMethodID = env->GetMethodID(
+ mediaScannerClientInterface,
+ "scanFile",
+ "(Ljava/lang/String;JJZ)V");
+
+ mHandleStringTagMethodID = env->GetMethodID(
+ mediaScannerClientInterface,
+ "handleStringTag",
+ "(Ljava/lang/String;Ljava/lang/String;)V");
+
+ mSetMimeTypeMethodID = env->GetMethodID(
+ mediaScannerClientInterface,
+ "setMimeType",
+ "(Ljava/lang/String;)V");
+
+ mAddNoMediaFolderMethodID = env->GetMethodID(
+ mediaScannerClientInterface,
+ "addNoMediaFolder",
+ "(Ljava/lang/String;)V");
}
}
-
+
virtual ~MyMediaScannerClient()
{
+ LOGV("MyMediaScannerClient destructor");
mEnv->DeleteGlobalRef(mClient);
}
-
- // returns true if it succeeded, false if an exception occured in the Java code
+
+ // Returns true if it succeeded, false if an exception occured
+ // in the Java code
virtual bool scanFile(const char* path, long long lastModified,
long long fileSize, bool isDirectory)
{
+ LOGV("scanFile: path(%s), time(%lld), size(%lld) and isDir(%d)",
+ path, lastModified, fileSize, isDirectory);
+
jstring pathStr;
- if ((pathStr = mEnv->NewStringUTF(path)) == NULL) return false;
+ if ((pathStr = mEnv->NewStringUTF(path)) == NULL) {
+ return false;
+ }
mEnv->CallVoidMethod(mClient, mScanFileMethodID, pathStr, lastModified,
fileSize, isDirectory);
@@ -91,25 +111,36 @@
return (!mEnv->ExceptionCheck());
}
- // returns true if it succeeded, false if an exception occured in the Java code
+ // Returns true if it succeeded, false if an exception occured
+ // in the Java code
virtual bool handleStringTag(const char* name, const char* value)
{
+ LOGV("handleStringTag: name(%s) and value(%s)", name, value);
jstring nameStr, valueStr;
- if ((nameStr = mEnv->NewStringUTF(name)) == NULL) return false;
- if ((valueStr = mEnv->NewStringUTF(value)) == NULL) return false;
+ if ((nameStr = mEnv->NewStringUTF(name)) == NULL) {
+ return false;
+ }
+ if ((valueStr = mEnv->NewStringUTF(value)) == NULL) {
+ return false;
+ }
- mEnv->CallVoidMethod(mClient, mHandleStringTagMethodID, nameStr, valueStr);
+ mEnv->CallVoidMethod(
+ mClient, mHandleStringTagMethodID, nameStr, valueStr);
mEnv->DeleteLocalRef(nameStr);
mEnv->DeleteLocalRef(valueStr);
return (!mEnv->ExceptionCheck());
}
- // returns true if it succeeded, false if an exception occured in the Java code
+ // Returns true if it succeeded, false if an exception occured
+ // in the Java code
virtual bool setMimeType(const char* mimeType)
{
+ LOGV("setMimeType: %s", mimeType);
jstring mimeTypeStr;
- if ((mimeTypeStr = mEnv->NewStringUTF(mimeType)) == NULL) return false;
+ if ((mimeTypeStr = mEnv->NewStringUTF(mimeType)) == NULL) {
+ return false;
+ }
mEnv->CallVoidMethod(mClient, mSetMimeTypeMethodID, mimeTypeStr);
@@ -117,11 +148,15 @@
return (!mEnv->ExceptionCheck());
}
- // returns true if it succeeded, false if an exception occured in the Java code
+ // Returns true if it succeeded, false if an exception occured
+ // in the Java code
virtual bool addNoMediaFolder(const char* path)
{
+ LOGV("addNoMediaFolder: path(%s)", path);
jstring pathStr;
- if ((pathStr = mEnv->NewStringUTF(path)) == NULL) return false;
+ if ((pathStr = mEnv->NewStringUTF(path)) == NULL) {
+ return false;
+ }
mEnv->CallVoidMethod(mClient, mAddNoMediaFolderMethodID, pathStr);
@@ -133,33 +168,35 @@
private:
JNIEnv *mEnv;
jobject mClient;
- jmethodID mScanFileMethodID;
- jmethodID mHandleStringTagMethodID;
+ jmethodID mScanFileMethodID;
+ jmethodID mHandleStringTagMethodID;
jmethodID mSetMimeTypeMethodID;
jmethodID mAddNoMediaFolderMethodID;
};
-// ----------------------------------------------------------------------------
-
static bool ExceptionCheck(void* env)
{
+ LOGV("ExceptionCheck");
return ((JNIEnv *)env)->ExceptionCheck();
}
static void
-android_media_MediaScanner_processDirectory(JNIEnv *env, jobject thiz, jstring path, jobject client)
+android_media_MediaScanner_processDirectory(
+ JNIEnv *env, jobject thiz, jstring path, jobject client)
{
- MediaScanner *mp = (MediaScanner *)env->GetIntField(thiz, fields.context);
+ LOGV("processDirectory");
+ MediaScanner *mp =
+ (MediaScanner *)env->GetIntField(thiz, fields.context);
if (path == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ jniThrowException(env, kIllegalArgumentException, NULL);
return;
}
const char *pathStr = env->GetStringUTFChars(path, NULL);
if (pathStr == NULL) { // Out of memory
- jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
+ jniThrowException(env, kRunTimeException, "Out of memory");
return;
}
@@ -169,24 +206,30 @@
}
static void
-android_media_MediaScanner_processFile(JNIEnv *env, jobject thiz, jstring path, jstring mimeType, jobject client)
+android_media_MediaScanner_processFile(
+ JNIEnv *env, jobject thiz, jstring path,
+ jstring mimeType, jobject client)
{
- MediaScanner *mp = (MediaScanner *)env->GetIntField(thiz, fields.context);
+ LOGV("processFile");
+ MediaScanner *mp =
+ (MediaScanner *)env->GetIntField(thiz, fields.context);
if (path == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ jniThrowException(env, kIllegalArgumentException, NULL);
return;
}
-
+
const char *pathStr = env->GetStringUTFChars(path, NULL);
if (pathStr == NULL) { // Out of memory
- jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
+ jniThrowException(env, kRunTimeException, "Out of memory");
return;
}
- const char *mimeTypeStr = (mimeType ? env->GetStringUTFChars(mimeType, NULL) : NULL);
+
+ const char *mimeTypeStr =
+ (mimeType ? env->GetStringUTFChars(mimeType, NULL) : NULL);
if (mimeType && mimeTypeStr == NULL) { // Out of memory
env->ReleaseStringUTFChars(path, pathStr);
- jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
+ jniThrowException(env, kRunTimeException, "Out of memory");
return;
}
@@ -199,17 +242,20 @@
}
static void
-android_media_MediaScanner_setLocale(JNIEnv *env, jobject thiz, jstring locale)
+android_media_MediaScanner_setLocale(
+ JNIEnv *env, jobject thiz, jstring locale)
{
- MediaScanner *mp = (MediaScanner *)env->GetIntField(thiz, fields.context);
+ LOGV("setLocale");
+ MediaScanner *mp =
+ (MediaScanner *)env->GetIntField(thiz, fields.context);
if (locale == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ jniThrowException(env, kIllegalArgumentException, NULL);
return;
}
const char *localeStr = env->GetStringUTFChars(locale, NULL);
if (localeStr == NULL) { // Out of memory
- jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
+ jniThrowException(env, kRunTimeException, "Out of memory");
return;
}
mp->setLocale(localeStr);
@@ -218,12 +264,15 @@
}
static jbyteArray
-android_media_MediaScanner_extractAlbumArt(JNIEnv *env, jobject thiz, jobject fileDescriptor)
+android_media_MediaScanner_extractAlbumArt(
+ JNIEnv *env, jobject thiz, jobject fileDescriptor)
{
- MediaScanner *mp = (MediaScanner *)env->GetIntField(thiz, fields.context);
+ LOGV("extractAlbumArt");
+ MediaScanner *mp =
+ (MediaScanner *)env->GetIntField(thiz, fields.context);
if (fileDescriptor == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ jniThrowException(env, kIllegalArgumentException, NULL);
return NULL;
}
@@ -233,14 +282,14 @@
return NULL;
}
long len = *((long*)data);
-
+
jbyteArray array = env->NewByteArray(len);
if (array != NULL) {
jbyte* bytes = env->GetByteArrayElements(array, NULL);
memcpy(bytes, data + 4, len);
env->ReleaseByteArrayElements(array, bytes, 0);
}
-
+
done:
free(data);
// if NewByteArray() returned NULL, an out-of-memory
@@ -256,17 +305,18 @@
static void
android_media_MediaScanner_native_init(JNIEnv *env)
{
- jclass clazz;
-
- clazz = env->FindClass("android/media/MediaScanner");
+ LOGV("native_init");
+ jclass clazz = env->FindClass(kClassMediaScanner);
if (clazz == NULL) {
- jniThrowException(env, "java/lang/RuntimeException", "Can't find android/media/MediaScanner");
+ const char* err = "Can't find android/media/MediaScanner";
+ jniThrowException(env, kRunTimeException, err);
return;
}
fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
if (fields.context == NULL) {
- jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaScanner.mNativeContext");
+ const char* err = "Can't find MediaScanner.mNativeContext";
+ jniThrowException(env, kRunTimeException, err);
return;
}
}
@@ -274,10 +324,11 @@
static void
android_media_MediaScanner_native_setup(JNIEnv *env, jobject thiz)
{
+ LOGV("native_setup");
MediaScanner *mp = new StagefrightMediaScanner;
if (mp == NULL) {
- jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
+ jniThrowException(env, kRunTimeException, "Out of memory");
return;
}
@@ -287,38 +338,67 @@
static void
android_media_MediaScanner_native_finalize(JNIEnv *env, jobject thiz)
{
- MediaScanner *mp = (MediaScanner *)env->GetIntField(thiz, fields.context);
+ LOGV("native_finalize");
+ MediaScanner *mp =
+ (MediaScanner *)env->GetIntField(thiz, fields.context);
- //printf("##### android_media_MediaScanner_native_finalize: ctx=0x%p\n", ctx);
-
- if (mp == 0)
+ if (mp == 0) {
return;
+ }
delete mp;
}
-// ----------------------------------------------------------------------------
-
static JNINativeMethod gMethods[] = {
- {"processDirectory", "(Ljava/lang/String;Landroid/media/MediaScannerClient;)V",
- (void *)android_media_MediaScanner_processDirectory},
- {"processFile", "(Ljava/lang/String;Ljava/lang/String;Landroid/media/MediaScannerClient;)V",
- (void *)android_media_MediaScanner_processFile},
- {"setLocale", "(Ljava/lang/String;)V", (void *)android_media_MediaScanner_setLocale},
- {"extractAlbumArt", "(Ljava/io/FileDescriptor;)[B", (void *)android_media_MediaScanner_extractAlbumArt},
- {"native_init", "()V", (void *)android_media_MediaScanner_native_init},
- {"native_setup", "()V", (void *)android_media_MediaScanner_native_setup},
- {"native_finalize", "()V", (void *)android_media_MediaScanner_native_finalize},
-};
+ {
+ "processDirectory",
+ "(Ljava/lang/String;Landroid/media/MediaScannerClient;)V",
+ (void *)android_media_MediaScanner_processDirectory
+ },
-static const char* const kClassPathName = "android/media/MediaScanner";
+ {
+ "processFile",
+ "(Ljava/lang/String;Ljava/lang/String;Landroid/media/MediaScannerClient;)V",
+ (void *)android_media_MediaScanner_processFile
+ },
+
+ {
+ "setLocale",
+ "(Ljava/lang/String;)V",
+ (void *)android_media_MediaScanner_setLocale
+ },
+
+ {
+ "extractAlbumArt",
+ "(Ljava/io/FileDescriptor;)[B",
+ (void *)android_media_MediaScanner_extractAlbumArt
+ },
+
+ {
+ "native_init",
+ "()V",
+ (void *)android_media_MediaScanner_native_init
+ },
+
+ {
+ "native_setup",
+ "()V",
+ (void *)android_media_MediaScanner_native_setup
+ },
+
+ {
+ "native_finalize",
+ "()V",
+ (void *)android_media_MediaScanner_native_finalize
+ },
+};
// This function only registers the native methods, and is called from
// JNI_OnLoad in android_media_MediaPlayer.cpp
int register_android_media_MediaScanner(JNIEnv *env)
{
return AndroidRuntime::registerNativeMethods(env,
- "android/media/MediaScanner", gMethods, NELEM(gMethods));
+ kClassMediaScanner, gMethods, NELEM(gMethods));
}
diff --git a/media/jni/android_mtp_MtpDevice.cpp b/media/jni/android_mtp_MtpDevice.cpp
index fd32665..f5fcb4e 100644
--- a/media/jni/android_mtp_MtpDevice.cpp
+++ b/media/jni/android_mtp_MtpDevice.cpp
@@ -311,9 +311,9 @@
if (objectInfo->mName)
env->SetObjectField(info, field_objectInfo_name, env->NewStringUTF(objectInfo->mName));
if (objectInfo->mDateCreated)
- env->SetLongField(info, field_objectInfo_dateCreated, objectInfo->mDateCreated);
+ env->SetLongField(info, field_objectInfo_dateCreated, objectInfo->mDateCreated * 1000LL);
if (objectInfo->mDateModified)
- env->SetLongField(info, field_objectInfo_dateModified, objectInfo->mDateModified);
+ env->SetLongField(info, field_objectInfo_dateModified, objectInfo->mDateModified * 1000LL);
if (objectInfo->mKeywords)
env->SetObjectField(info, field_objectInfo_keywords,
env->NewStringUTF(objectInfo->mKeywords));
diff --git a/media/jni/mediaeditor/Android.mk b/media/jni/mediaeditor/Android.mk
index 6a7116c..f054deb 100755
--- a/media/jni/mediaeditor/Android.mk
+++ b/media/jni/mediaeditor/Android.mk
@@ -68,9 +68,6 @@
-DUSE_STAGEFRIGHT_READERS \
-DUSE_STAGEFRIGHT_3GPP_READER
-
-LOCAL_LDFLAGS += -fuse-ld=bfd
-
LOCAL_STATIC_LIBRARIES := \
libvideoeditor_core \
libstagefright_color_conversion \
diff --git a/media/jni/mediaeditor/VideoEditorOsal.cpp b/media/jni/mediaeditor/VideoEditorOsal.cpp
index 423e93f..035f59a 100755
--- a/media/jni/mediaeditor/VideoEditorOsal.cpp
+++ b/media/jni/mediaeditor/VideoEditorOsal.cpp
@@ -207,6 +207,7 @@
VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_AUDIOBITRATE_TOO_HIGH ),
VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_OUTPUT_FILE_SIZE_TOO_SMALL ),
VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_NOMORE_SPACE ),
+ VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_FILE_DRM_PROTECTED ),
// M4READER_Common.h
VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_READER_UNKNOWN_STREAM_TYPE ),
diff --git a/media/jni/mediaeditor/VideoEditorPropertiesMain.cpp b/media/jni/mediaeditor/VideoEditorPropertiesMain.cpp
index 73a7c9c..3b795ce 100755
--- a/media/jni/mediaeditor/VideoEditorPropertiesMain.cpp
+++ b/media/jni/mediaeditor/VideoEditorPropertiesMain.cpp
@@ -204,10 +204,17 @@
result = getClipProperties(
pEnv, thiz, pFile, clipType, pClipProperties);
- // Check if the creation succeeded.
- videoEditJava_checkAndThrowIllegalArgumentException(
- &gotten, pEnv,(M4NO_ERROR != result),
- "Invalid File or File not found");
+ if (M4MCS_ERR_FILE_DRM_PROTECTED == result) {
+ // Check if the creation succeeded.
+ videoEditJava_checkAndThrowIllegalArgumentException(
+ &gotten, pEnv,(M4NO_ERROR != result),
+ "Invalid File - DRM Protected ");
+ } else {
+ // Check if the creation succeeded.
+ videoEditJava_checkAndThrowIllegalArgumentException(
+ &gotten, pEnv,(M4NO_ERROR != result),
+ "Invalid File or File not found ");
+ }
/**
* Max resolution supported is 1280 x 720.
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 1d6ffa0..a18bedb2 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -128,6 +128,9 @@
{
LOGV("set(): sampleRate %d, channels %d, frameCount %d",sampleRate, channels, frameCount);
+
+ AutoMutex lock(mLock);
+
if (mAudioRecord != 0) {
return INVALID_OPERATION;
}
@@ -183,7 +186,7 @@
mSessionId = sessionId;
// create the IAudioRecord
- status = openRecord(sampleRate, format, channelCount,
+ status = openRecord_l(sampleRate, format, channelCount,
frameCount, flags, input);
if (status != NO_ERROR) {
return status;
@@ -282,21 +285,31 @@
}
AutoMutex lock(mLock);
+ // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed
+ // while we are accessing the cblk
+ sp <IAudioRecord> audioRecord = mAudioRecord;
+ sp <IMemory> iMem = mCblkMemory;
+ audio_track_cblk_t* cblk = mCblk;
if (mActive == 0) {
mActive = 1;
- ret = mAudioRecord->start();
- if (ret == DEAD_OBJECT) {
- LOGV("start() dead IAudioRecord: creating a new one");
- ret = openRecord(mCblk->sampleRate, mFormat, mChannelCount,
- mFrameCount, mFlags, getInput());
- if (ret == NO_ERROR) {
- ret = mAudioRecord->start();
+
+ cblk->lock.lock();
+ if (!(cblk->flags & CBLK_INVALID_MSK)) {
+ cblk->lock.unlock();
+ ret = mAudioRecord->start();
+ cblk->lock.lock();
+ if (ret == DEAD_OBJECT) {
+ cblk->flags |= CBLK_INVALID_MSK;
}
}
+ if (cblk->flags & CBLK_INVALID_MSK) {
+ ret = restoreRecord_l(cblk);
+ }
+ cblk->lock.unlock();
if (ret == NO_ERROR) {
- mNewPosition = mCblk->user + mUpdatePeriod;
- mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
- mCblk->waitTimeMs = 0;
+ mNewPosition = cblk->user + mUpdatePeriod;
+ cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
+ cblk->waitTimeMs = 0;
if (t != 0) {
t->run("ClientRecordThread", THREAD_PRIORITY_AUDIO_CLIENT);
} else {
@@ -353,6 +366,7 @@
uint32_t AudioRecord::getSampleRate()
{
+ AutoMutex lock(mLock);
return mCblk->sampleRate;
}
@@ -400,6 +414,7 @@
{
if (position == 0) return BAD_VALUE;
+ AutoMutex lock(mLock);
*position = mCblk->user;
return NO_ERROR;
@@ -415,7 +430,8 @@
// -------------------------------------------------------------------------
-status_t AudioRecord::openRecord(
+// must be called with mLock held
+status_t AudioRecord::openRecord_l(
uint32_t sampleRate,
int format,
int channelCount,
@@ -459,6 +475,7 @@
status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
{
+ AutoMutex lock(mLock);
int active;
status_t result;
audio_track_cblk_t* cblk = mCblk;
@@ -483,7 +500,19 @@
cblk->lock.unlock();
return WOULD_BLOCK;
}
- result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs));
+ if (!(cblk->flags & CBLK_INVALID_MSK)) {
+ mLock.unlock();
+ result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs));
+ cblk->lock.unlock();
+ mLock.lock();
+ if (mActive == 0) {
+ return status_t(STOPPED);
+ }
+ cblk->lock.lock();
+ }
+ if (cblk->flags & CBLK_INVALID_MSK) {
+ goto create_new_record;
+ }
if (__builtin_expect(result!=NO_ERROR, false)) {
cblk->waitTimeMs += waitTimeMs;
if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) {
@@ -491,16 +520,17 @@
"user=%08x, server=%08x", cblk->user, cblk->server);
cblk->lock.unlock();
result = mAudioRecord->start();
- if (result == DEAD_OBJECT) {
- LOGW("obtainBuffer() dead IAudioRecord: creating a new one");
- result = openRecord(cblk->sampleRate, mFormat, mChannelCount,
- mFrameCount, mFlags, getInput());
- if (result == NO_ERROR) {
- cblk = mCblk;
- mAudioRecord->start();
- }
- }
cblk->lock.lock();
+ if (result == DEAD_OBJECT) {
+ cblk->flags |= CBLK_INVALID_MSK;
+create_new_record:
+ result = AudioRecord::restoreRecord_l(cblk);
+ }
+ if (result != NO_ERROR) {
+ LOGW("obtainBuffer create Track error %d", result);
+ cblk->lock.unlock();
+ return result;
+ }
cblk->waitTimeMs = 0;
}
if (--waitCount == 0) {
@@ -540,12 +570,19 @@
void AudioRecord::releaseBuffer(Buffer* audioBuffer)
{
- audio_track_cblk_t* cblk = mCblk;
- cblk->stepUser(audioBuffer->frameCount);
+ AutoMutex lock(mLock);
+ mCblk->stepUser(audioBuffer->frameCount);
}
audio_io_handle_t AudioRecord::getInput()
{
+ AutoMutex lock(mLock);
+ return getInput_l();
+}
+
+// must be called with mLock held
+audio_io_handle_t AudioRecord::getInput_l()
+{
mInput = AudioSystem::getInput(mInputSource,
mCblk->sampleRate,
mFormat, mChannels,
@@ -573,6 +610,12 @@
return BAD_VALUE;
}
+ mLock.lock();
+ // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed
+ // while we are accessing the cblk
+ sp <IAudioRecord> audioRecord = mAudioRecord;
+ sp <IMemory> iMem = mCblkMemory;
+ mLock.unlock();
do {
@@ -613,9 +656,17 @@
uint32_t frames = mRemainingFrames;
size_t readSize;
+ mLock.lock();
+ // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed
+ // while we are accessing the cblk
+ sp <IAudioRecord> audioRecord = mAudioRecord;
+ sp <IMemory> iMem = mCblkMemory;
+ audio_track_cblk_t* cblk = mCblk;
+ mLock.unlock();
+
// Manage marker callback
if (!mMarkerReached && (mMarkerPosition > 0)) {
- if (mCblk->user >= mMarkerPosition) {
+ if (cblk->user >= mMarkerPosition) {
mCbf(EVENT_MARKER, mUserData, (void *)&mMarkerPosition);
mMarkerReached = true;
}
@@ -623,7 +674,7 @@
// Manage new position callback
if (mUpdatePeriod > 0) {
- while (mCblk->user >= mNewPosition) {
+ while (cblk->user >= mNewPosition) {
mCbf(EVENT_NEW_POS, mUserData, (void *)&mNewPosition);
mNewPosition += mUpdatePeriod;
}
@@ -669,11 +720,11 @@
// Manage overrun callback
- if (mActive && (mCblk->framesAvailable_l() == 0)) {
- LOGV("Overrun user: %x, server: %x, flags %04x", mCblk->user, mCblk->server, mCblk->flags);
- if ((mCblk->flags & CBLK_UNDERRUN_MSK) == CBLK_UNDERRUN_OFF) {
+ if (mActive && (cblk->framesAvailable() == 0)) {
+ LOGV("Overrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags);
+ if ((cblk->flags & CBLK_UNDERRUN_MSK) == CBLK_UNDERRUN_OFF) {
mCbf(EVENT_OVERRUN, mUserData, 0);
- mCblk->flags |= CBLK_UNDERRUN_ON;
+ cblk->flags |= CBLK_UNDERRUN_ON;
}
}
@@ -685,6 +736,69 @@
return true;
}
+// must be called with mLock and cblk.lock held. Callers must also hold strong references on
+// the IAudioRecord and IMemory in case they are recreated here.
+// If the IAudioRecord is successfully restored, the cblk pointer is updated
+status_t AudioRecord::restoreRecord_l(audio_track_cblk_t*& cblk)
+{
+ status_t result;
+
+ if (!(cblk->flags & CBLK_RESTORING_MSK)) {
+ LOGW("dead IAudioRecord, creating a new one");
+
+ cblk->flags |= CBLK_RESTORING_ON;
+ // signal old cblk condition so that other threads waiting for available buffers stop
+ // waiting now
+ cblk->cv.broadcast();
+ cblk->lock.unlock();
+
+ // if the new IAudioRecord is created, openRecord_l() will modify the
+ // following member variables: mAudioRecord, mCblkMemory and mCblk.
+ // It will also delete the strong references on previous IAudioRecord and IMemory
+ result = openRecord_l(cblk->sampleRate, mFormat, mChannelCount,
+ mFrameCount, mFlags, getInput_l());
+ if (result == NO_ERROR) {
+ result = mAudioRecord->start();
+ }
+ if (result != NO_ERROR) {
+ mActive = false;
+ }
+
+ // signal old cblk condition for other threads waiting for restore completion
+ cblk->lock.lock();
+ cblk->flags |= CBLK_RESTORED_MSK;
+ cblk->cv.broadcast();
+ cblk->lock.unlock();
+ } else {
+ if (!(cblk->flags & CBLK_RESTORED_MSK)) {
+ LOGW("dead IAudioRecord, waiting for a new one to be created");
+ mLock.unlock();
+ result = cblk->cv.waitRelative(cblk->lock, milliseconds(RESTORE_TIMEOUT_MS));
+ cblk->lock.unlock();
+ mLock.lock();
+ } else {
+ LOGW("dead IAudioRecord, already restored");
+ result = NO_ERROR;
+ cblk->lock.unlock();
+ }
+ if (result != NO_ERROR || mActive == 0) {
+ result = status_t(STOPPED);
+ }
+ }
+ LOGV("restoreRecord_l() status %d mActive %d cblk %p, old cblk %p flags %08x old flags %08x",
+ result, mActive, mCblk, cblk, mCblk->flags, cblk->flags);
+
+ if (result == NO_ERROR) {
+ // from now on we switch to the newly created cblk
+ cblk = mCblk;
+ }
+ cblk->lock.lock();
+
+ LOGW_IF(result != NO_ERROR, "restoreRecord_l() error %d", result);
+
+ return result;
+}
+
// =========================================================================
AudioRecord::ClientRecordThread::ClientRecordThread(AudioRecord& receiver, bool bCanCallJava)
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index c1bed59..8d8f67b 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -148,6 +148,7 @@
LOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size());
+ AutoMutex lock(mLock);
if (mAudioTrack != 0) {
LOGE("Track already in use");
return INVALID_OPERATION;
@@ -211,8 +212,15 @@
mAuxEffectId = 0;
// create the IAudioTrack
- status_t status = createTrack(streamType, sampleRate, format, channelCount,
- frameCount, flags, sharedBuffer, output, true);
+ status_t status = createTrack_l(streamType,
+ sampleRate,
+ format,
+ channelCount,
+ frameCount,
+ flags,
+ sharedBuffer,
+ output,
+ true);
if (status != NO_ERROR) {
return status;
@@ -312,37 +320,38 @@
}
AutoMutex lock(mLock);
+ // acquire a strong reference on the IMemory and IAudioTrack so that they cannot be destroyed
+ // while we are accessing the cblk
+ sp <IAudioTrack> audioTrack = mAudioTrack;
+ sp <IMemory> iMem = mCblkMemory;
+ audio_track_cblk_t* cblk = mCblk;
+
if (mActive == 0) {
mActive = 1;
- mNewPosition = mCblk->server + mUpdatePeriod;
- mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
- mCblk->waitTimeMs = 0;
- mCblk->flags &= ~CBLK_DISABLED_ON;
+ mNewPosition = cblk->server + mUpdatePeriod;
+ cblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
+ cblk->waitTimeMs = 0;
+ cblk->flags &= ~CBLK_DISABLED_ON;
if (t != 0) {
t->run("AudioTrackThread", THREAD_PRIORITY_AUDIO_CLIENT);
} else {
setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT);
}
- if (mCblk->flags & CBLK_INVALID_MSK) {
- LOGW("start() track %p invalidated, creating a new one", this);
- // no need to clear the invalid flag as this cblk will not be used anymore
- // force new track creation
- status = DEAD_OBJECT;
- } else {
+ LOGV("start %p before lock cblk %p", this, mCblk);
+ cblk->lock.lock();
+ if (!(cblk->flags & CBLK_INVALID_MSK)) {
+ cblk->lock.unlock();
status = mAudioTrack->start();
- }
- if (status == DEAD_OBJECT) {
- LOGV("start() dead IAudioTrack: creating a new one");
- status = createTrack(mStreamType, mCblk->sampleRate, mFormat, mChannelCount,
- mFrameCount, mFlags, mSharedBuffer, getOutput(), false);
- if (status == NO_ERROR) {
- status = mAudioTrack->start();
- if (status == NO_ERROR) {
- mNewPosition = mCblk->server + mUpdatePeriod;
- }
+ cblk->lock.lock();
+ if (status == DEAD_OBJECT) {
+ cblk->flags |= CBLK_INVALID_MSK;
}
}
+ if (cblk->flags & CBLK_INVALID_MSK) {
+ status = restoreTrack_l(cblk, true);
+ }
+ cblk->lock.unlock();
if (status != NO_ERROR) {
LOGV("start() failed");
mActive = 0;
@@ -375,14 +384,14 @@
mAudioTrack->stop();
// Cancel loops (If we are in the middle of a loop, playback
// would not stop until loopCount reaches 0).
- setLoop(0, 0, 0);
+ setLoop_l(0, 0, 0);
// the playback head position will reset to 0, so if a marker is set, we need
// to activate it again
mMarkerReached = false;
// Force flush if a shared buffer is used otherwise audioflinger
// will not stop before end of buffer is reached.
if (mSharedBuffer != 0) {
- flush();
+ flush_l();
}
if (t != 0) {
t->requestExit();
@@ -403,6 +412,13 @@
void AudioTrack::flush()
{
+ AutoMutex lock(mLock);
+ flush_l();
+}
+
+// must be called with mLock held
+void AudioTrack::flush_l()
+{
LOGV("flush");
// clear playback marker and periodic update counter
@@ -445,6 +461,7 @@
return BAD_VALUE;
}
+ AutoMutex lock(mLock);
mVolume[LEFT] = left;
mVolume[RIGHT] = right;
@@ -470,6 +487,7 @@
if (level > 1.0f) {
return BAD_VALUE;
}
+ AutoMutex lock(mLock);
mSendLevel = level;
@@ -495,17 +513,26 @@
// Resampler implementation limits input sampling rate to 2 x output sampling rate.
if (rate <= 0 || rate > afSamplingRate*2 ) return BAD_VALUE;
+ AutoMutex lock(mLock);
mCblk->sampleRate = rate;
return NO_ERROR;
}
uint32_t AudioTrack::getSampleRate()
{
+ AutoMutex lock(mLock);
return mCblk->sampleRate;
}
status_t AudioTrack::setLoop(uint32_t loopStart, uint32_t loopEnd, int loopCount)
{
+ AutoMutex lock(mLock);
+ return setLoop_l(loopStart, loopEnd, loopCount);
+}
+
+// must be called with mLock held
+status_t AudioTrack::setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCount)
+{
audio_track_cblk_t* cblk = mCblk;
Mutex::Autolock _l(cblk->lock);
@@ -540,6 +567,7 @@
status_t AudioTrack::getLoop(uint32_t *loopStart, uint32_t *loopEnd, int *loopCount)
{
+ AutoMutex lock(mLock);
if (loopStart != 0) {
*loopStart = mCblk->loopStart;
}
@@ -599,6 +627,7 @@
status_t AudioTrack::setPosition(uint32_t position)
{
+ AutoMutex lock(mLock);
Mutex::Autolock _l(mCblk->lock);
if (!stopped()) return INVALID_OPERATION;
@@ -614,7 +643,7 @@
status_t AudioTrack::getPosition(uint32_t *position)
{
if (position == 0) return BAD_VALUE;
-
+ AutoMutex lock(mLock);
*position = mCblk->server;
return NO_ERROR;
@@ -622,9 +651,11 @@
status_t AudioTrack::reload()
{
+ AutoMutex lock(mLock);
+
if (!stopped()) return INVALID_OPERATION;
- flush();
+ flush_l();
mCblk->stepUser(mCblk->frameCount);
@@ -633,6 +664,13 @@
audio_io_handle_t AudioTrack::getOutput()
{
+ AutoMutex lock(mLock);
+ return getOutput_l();
+}
+
+// must be called with mLock held
+audio_io_handle_t AudioTrack::getOutput_l()
+{
return AudioSystem::getOutput((AudioSystem::stream_type)mStreamType,
mCblk->sampleRate, mFormat, mChannels, (AudioSystem::output_flags)mFlags);
}
@@ -654,7 +692,8 @@
// -------------------------------------------------------------------------
-status_t AudioTrack::createTrack(
+// must be called with mLock held
+status_t AudioTrack::createTrack_l(
int streamType,
uint32_t sampleRate,
int format,
@@ -774,6 +813,7 @@
status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
{
+ AutoMutex lock(mLock);
int active;
status_t result;
audio_track_cblk_t* cblk = mCblk;
@@ -800,12 +840,17 @@
return WOULD_BLOCK;
}
if (!(cblk->flags & CBLK_INVALID_MSK)) {
+ mLock.unlock();
result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs));
- }
- if (cblk->flags & CBLK_INVALID_MSK) {
- LOGW("obtainBuffer() track %p invalidated, creating a new one", this);
- // no need to clear the invalid flag as this cblk will not be used anymore
cblk->lock.unlock();
+ mLock.lock();
+ if (mActive == 0) {
+ return status_t(STOPPED);
+ }
+ cblk->lock.lock();
+ }
+
+ if (cblk->flags & CBLK_INVALID_MSK) {
goto create_new_track;
}
if (__builtin_expect(result!=NO_ERROR, false)) {
@@ -819,18 +864,17 @@
//unlock cblk mutex before calling mAudioTrack->start() (see issue #1617140)
cblk->lock.unlock();
result = mAudioTrack->start();
- if (result == DEAD_OBJECT) {
- LOGW("obtainBuffer() dead IAudioTrack: creating a new one");
-create_new_track:
- result = createTrack(mStreamType, cblk->sampleRate, mFormat, mChannelCount,
- mFrameCount, mFlags, mSharedBuffer, getOutput(), false);
- if (result == NO_ERROR) {
- cblk = mCblk;
- cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
- mAudioTrack->start();
- }
- }
cblk->lock.lock();
+ if (result == DEAD_OBJECT) {
+ cblk->flags |= CBLK_INVALID_MSK;
+create_new_track:
+ result = restoreTrack_l(cblk, false);
+ }
+ if (result != NO_ERROR) {
+ LOGW("obtainBuffer create Track error %d", result);
+ cblk->lock.unlock();
+ return result;
+ }
}
cblk->waitTimeMs = 0;
}
@@ -848,7 +892,7 @@
}
// restart track if it was disabled by audioflinger due to previous underrun
- if (cblk->flags & CBLK_DISABLED_MSK) {
+ if (mActive && (cblk->flags & CBLK_DISABLED_MSK)) {
cblk->flags &= ~CBLK_DISABLED_ON;
LOGW("obtainBuffer() track %p disabled, restarting", this);
mAudioTrack->start();
@@ -883,8 +927,8 @@
void AudioTrack::releaseBuffer(Buffer* audioBuffer)
{
- audio_track_cblk_t* cblk = mCblk;
- cblk->stepUser(audioBuffer->frameCount);
+ AutoMutex lock(mLock);
+ mCblk->stepUser(audioBuffer->frameCount);
}
// -------------------------------------------------------------------------
@@ -903,6 +947,13 @@
LOGV("write %p: %d bytes, mActive=%d", this, userSize, mActive);
+ // acquire a strong reference on the IMemory and IAudioTrack so that they cannot be destroyed
+ // while we are accessing the cblk
+ mLock.lock();
+ sp <IAudioTrack> audioTrack = mAudioTrack;
+ sp <IMemory> iMem = mCblkMemory;
+ mLock.unlock();
+
ssize_t written = 0;
const int8_t *src = (const int8_t *)buffer;
Buffer audioBuffer;
@@ -953,21 +1004,29 @@
uint32_t frames;
size_t writtenSize;
+ mLock.lock();
+ // acquire a strong reference on the IMemory and IAudioTrack so that they cannot be destroyed
+ // while we are accessing the cblk
+ sp <IAudioTrack> audioTrack = mAudioTrack;
+ sp <IMemory> iMem = mCblkMemory;
+ audio_track_cblk_t* cblk = mCblk;
+ mLock.unlock();
+
// Manage underrun callback
- if (mActive && (mCblk->framesReady() == 0)) {
- LOGV("Underrun user: %x, server: %x, flags %04x", mCblk->user, mCblk->server, mCblk->flags);
- if ((mCblk->flags & CBLK_UNDERRUN_MSK) == CBLK_UNDERRUN_OFF) {
+ if (mActive && (cblk->framesReady() == 0)) {
+ LOGV("Underrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags);
+ if ((cblk->flags & CBLK_UNDERRUN_MSK) == CBLK_UNDERRUN_OFF) {
mCbf(EVENT_UNDERRUN, mUserData, 0);
- if (mCblk->server == mCblk->frameCount) {
+ if (cblk->server == cblk->frameCount) {
mCbf(EVENT_BUFFER_END, mUserData, 0);
}
- mCblk->flags |= CBLK_UNDERRUN_ON;
+ cblk->flags |= CBLK_UNDERRUN_ON;
if (mSharedBuffer != 0) return false;
}
}
// Manage loop end callback
- while (mLoopCount > mCblk->loopCount) {
+ while (mLoopCount > cblk->loopCount) {
int loopCount = -1;
mLoopCount--;
if (mLoopCount >= 0) loopCount = mLoopCount;
@@ -977,7 +1036,7 @@
// Manage marker callback
if (!mMarkerReached && (mMarkerPosition > 0)) {
- if (mCblk->server >= mMarkerPosition) {
+ if (cblk->server >= mMarkerPosition) {
mCbf(EVENT_MARKER, mUserData, (void *)&mMarkerPosition);
mMarkerReached = true;
}
@@ -985,7 +1044,7 @@
// Manage new position callback
if (mUpdatePeriod > 0) {
- while (mCblk->server >= mNewPosition) {
+ while (cblk->server >= mNewPosition) {
mCbf(EVENT_NEW_POS, mUserData, (void *)&mNewPosition);
mNewPosition += mUpdatePeriod;
}
@@ -1068,6 +1127,84 @@
return true;
}
+// must be called with mLock and cblk.lock held. Callers must also hold strong references on
+// the IAudioTrack and IMemory in case they are recreated here.
+// If the IAudioTrack is successfully restored, the cblk pointer is updated
+status_t AudioTrack::restoreTrack_l(audio_track_cblk_t*& cblk, bool fromStart)
+{
+ status_t result;
+
+ if (!(cblk->flags & CBLK_RESTORING_MSK)) {
+ LOGW("dead IAudioTrack, creating a new one from %s",
+ fromStart ? "start()" : "obtainBuffer()");
+
+ cblk->flags |= CBLK_RESTORING_ON;
+ // signal old cblk condition so that other threads waiting for available buffers stop
+ // waiting now
+ cblk->cv.broadcast();
+ cblk->lock.unlock();
+
+ // if the new IAudioTrack is created, createTrack_l() will modify the
+ // following member variables: mAudioTrack, mCblkMemory and mCblk.
+ // It will also delete the strong references on previous IAudioTrack and IMemory
+ result = createTrack_l(mStreamType,
+ cblk->sampleRate,
+ mFormat,
+ mChannelCount,
+ mFrameCount,
+ mFlags,
+ mSharedBuffer,
+ getOutput_l(),
+ false);
+
+ if (result == NO_ERROR) {
+ if (!fromStart) {
+ mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
+ }
+ result = mAudioTrack->start();
+ if (fromStart && result == NO_ERROR) {
+ mNewPosition = mCblk->server + mUpdatePeriod;
+ }
+ }
+ if (result != NO_ERROR) {
+ mActive = false;
+ }
+
+ // signal old cblk condition for other threads waiting for restore completion
+ cblk->lock.lock();
+ cblk->flags |= CBLK_RESTORED_MSK;
+ cblk->cv.broadcast();
+ cblk->lock.unlock();
+ } else {
+ if (!(cblk->flags & CBLK_RESTORED_MSK)) {
+ LOGW("dead IAudioTrack, waiting for a new one");
+ mLock.unlock();
+ result = cblk->cv.waitRelative(cblk->lock, milliseconds(RESTORE_TIMEOUT_MS));
+ cblk->lock.unlock();
+ mLock.lock();
+ } else {
+ LOGW("dead IAudioTrack, already restored");
+ result = NO_ERROR;
+ cblk->lock.unlock();
+ }
+ if (result != NO_ERROR || mActive == 0) {
+ result = status_t(STOPPED);
+ }
+ }
+ LOGV("restoreTrack_l() status %d mActive %d cblk %p, old cblk %p flags %08x old flags %08x",
+ result, mActive, mCblk, cblk, mCblk->flags, cblk->flags);
+
+ if (result == NO_ERROR) {
+ // from now on we switch to the newly created cblk
+ cblk = mCblk;
+ }
+ cblk->lock.lock();
+
+ LOGW_IF(result != NO_ERROR, "restoreTrack_l() error %d", result);
+
+ return result;
+}
+
status_t AudioTrack::dump(int fd, const Vector<String16>& args) const
{
@@ -1197,7 +1334,9 @@
this->server = s;
- cv.signal();
+ if (!(flags & CBLK_INVALID_MSK)) {
+ cv.signal();
+ }
lock.unlock();
return true;
}
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index 7fb7aed..ca5bc38 100644
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -721,6 +721,9 @@
createDefaultCamcorderTimeLapseHighProfiles(&highTimeLapseProfile, &highSpecificTimeLapseProfile);
profiles->mCamcorderProfiles.add(highTimeLapseProfile);
profiles->mCamcorderProfiles.add(highSpecificTimeLapseProfile);
+
+ // We only have the back-facing camera support by default.
+ profiles->mCameraIds.add(0);
}
/*static*/ void
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 88069e9..e445b74 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -19,6 +19,7 @@
ESDS.cpp \
FileSource.cpp \
FLACExtractor.cpp \
+ HTTPBase.cpp \
HTTPStream.cpp \
JPEGSource.cpp \
MP3Extractor.cpp \
@@ -75,7 +76,7 @@
libdrmframework \
libcrypto \
libssl \
- libgui
+ libgui \
LOCAL_STATIC_LIBRARIES := \
libstagefright_color_conversion \
@@ -101,6 +102,60 @@
libstagefright_g711dec \
libFLAC \
+################################################################################
+
+# The following was shamelessly copied from external/webkit/Android.mk and
+# currently must follow the same logic to determine how webkit was built and
+# if it's safe to link against libchromium.net
+
+# V8 also requires an ARMv7 CPU, and since we must use jsc, we cannot
+# use the Chrome http stack either.
+ifneq ($(strip $(ARCH_ARM_HAVE_ARMV7A)),true)
+ USE_ALT_HTTP := true
+endif
+
+# See if the user has specified a stack they want to use
+HTTP_STACK = $(HTTP)
+# We default to the Chrome HTTP stack.
+DEFAULT_HTTP = chrome
+ALT_HTTP = android
+
+ifneq ($(HTTP_STACK),chrome)
+ ifneq ($(HTTP_STACK),android)
+ # No HTTP stack is specified, pickup the one we want as default.
+ ifeq ($(USE_ALT_HTTP),true)
+ HTTP_STACK = $(ALT_HTTP)
+ else
+ HTTP_STACK = $(DEFAULT_HTTP)
+ endif
+ endif
+endif
+
+ifeq ($(HTTP_STACK),chrome)
+
+LOCAL_SHARED_LIBRARIES += \
+ liblog \
+ libicuuc \
+ libicui18n \
+ libz \
+ libdl \
+
+LOCAL_STATIC_LIBRARIES += \
+ libstagefright_chromium_http \
+ libchromium_net \
+ libwebcore \
+
+ifneq ($(TARGET_SIMULATOR),true)
+LOCAL_SHARED_LIBRARIES += libstlport
+include external/stlport/libstlport.mk
+endif
+
+LOCAL_CPPFLAGS += -DCHROMIUM_AVAILABLE=1
+
+endif # ifeq ($(HTTP_STACK),chrome)
+
+################################################################################
+
LOCAL_SHARED_LIBRARIES += \
libstagefright_amrnb_common \
libstagefright_enc_common \
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 4c744bd..0de1988 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -45,6 +45,7 @@
#include <surfaceflinger/Surface.h>
#include <gui/ISurfaceTexture.h>
#include <gui/SurfaceTextureClient.h>
+#include <surfaceflinger/ISurfaceComposer.h>
#include <media/stagefright/foundation/ALooper.h>
#include <media/stagefright/foundation/AMessage.h>
@@ -303,7 +304,7 @@
return UNKNOWN_ERROR;
}
- dataSource->getDrmInfo(&mDecryptHandle, &mDrmManagerClient);
+ dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
if (mDecryptHandle != NULL) {
CHECK(mDrmManagerClient);
if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
@@ -1189,6 +1190,19 @@
}
status_t AwesomePlayer::initVideoDecoder(uint32_t flags) {
+
+ // Either the application or the DRM system can independently say
+ // that there must be a hardware-protected path to an external video sink.
+ // For now we always require a hardware-protected path to external video sink
+ // if content is DRMed, but eventually this could be optional per DRM agent.
+ // When the application wants protection, then
+ // (USE_SURFACE_ALLOC && (mSurface != 0) &&
+ // (mSurface->getFlags() & ISurfaceComposer::eProtectedByApp))
+ // will be true, but that part is already handled by SurfaceFlinger.
+ if (mDecryptHandle != NULL) {
+ flags |= OMXCodec::kEnableGrallocUsageProtected;
+ }
+ LOGV("initVideoDecoder flags=0x%x", flags);
mVideoSource = OMXCodec::Create(
mClient.interface(), mVideoTrack->getFormat(),
false, // createEncoder
@@ -1597,8 +1611,10 @@
if (!strncasecmp("http://", mUri.string(), 7)
|| !strncasecmp("https://", mUri.string(), 8)) {
- mConnectingDataSource = new NuHTTPDataSource(
- (mFlags & INCOGNITO) ? NuHTTPDataSource::kFlagIncognito : 0);
+ mConnectingDataSource = HTTPBase::Create(
+ (mFlags & INCOGNITO)
+ ? HTTPBase::kFlagIncognito
+ : 0);
mLock.unlock();
status_t err = mConnectingDataSource->connect(mUri, &mUriHeaders);
@@ -1687,7 +1703,8 @@
return UNKNOWN_ERROR;
}
- dataSource->getDrmInfo(&mDecryptHandle, &mDrmManagerClient);
+ dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
+
if (mDecryptHandle != NULL) {
CHECK(mDrmManagerClient);
if (RightsStatus::RIGHTS_VALID == mDecryptHandle->status) {
diff --git a/media/libstagefright/DRMExtractor.cpp b/media/libstagefright/DRMExtractor.cpp
index 2809df5..c4ed516 100644
--- a/media/libstagefright/DRMExtractor.cpp
+++ b/media/libstagefright/DRMExtractor.cpp
@@ -41,7 +41,7 @@
class DRMSource : public MediaSource {
public:
DRMSource(const sp<MediaSource> &mediaSource,
- DecryptHandle *decryptHandle,
+ const sp<DecryptHandle> &decryptHandle,
DrmManagerClient *managerClient,
int32_t trackId, DrmBuffer *ipmpBox);
@@ -56,7 +56,7 @@
private:
sp<MediaSource> mOriginalMediaSource;
- DecryptHandle* mDecryptHandle;
+ sp<DecryptHandle> mDecryptHandle;
DrmManagerClient* mDrmManagerClient;
size_t mTrackId;
mutable Mutex mDRMLock;
@@ -70,7 +70,7 @@
////////////////////////////////////////////////////////////////////////////////
DRMSource::DRMSource(const sp<MediaSource> &mediaSource,
- DecryptHandle *decryptHandle,
+ const sp<DecryptHandle> &decryptHandle,
DrmManagerClient *managerClient,
int32_t trackId, DrmBuffer *ipmpBox)
: mOriginalMediaSource(mediaSource),
@@ -245,7 +245,7 @@
mOriginalExtractor->setDrmFlag(true);
mOriginalExtractor->getMetaData()->setInt32(kKeyIsDRM, 1);
- source->getDrmInfo(&mDecryptHandle, &mDrmManagerClient);
+ source->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
}
DRMExtractor::~DRMExtractor() {
@@ -281,7 +281,7 @@
bool SniffDRM(
const sp<DataSource> &source, String8 *mimeType, float *confidence,
sp<AMessage> *) {
- DecryptHandle *decryptHandle = source->DrmInitialization();
+ sp<DecryptHandle> decryptHandle = source->DrmInitialization();
if (decryptHandle != NULL) {
if (decryptHandle->decryptApiType == DecryptApiType::CONTAINER_BASED) {
diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp
index 3b38208..b5c51f4 100644
--- a/media/libstagefright/DataSource.cpp
+++ b/media/libstagefright/DataSource.cpp
@@ -21,7 +21,7 @@
#include "include/OggExtractor.h"
#include "include/MPEG2TSExtractor.h"
#include "include/NuCachedSource2.h"
-#include "include/NuHTTPDataSource.h"
+#include "include/HTTPBase.h"
#include "include/DRMExtractor.h"
#include "include/FLACExtractor.h"
#include "include/AACExtractor.h"
@@ -127,7 +127,7 @@
source = new FileSource(uri + 7);
} else if (!strncasecmp("http://", uri, 7)
|| !strncasecmp("https://", uri, 8)) {
- sp<NuHTTPDataSource> httpSource = new NuHTTPDataSource;
+ sp<HTTPBase> httpSource = HTTPBase::Create();
if (httpSource->connect(uri, headers) != OK) {
return NULL;
}
diff --git a/media/libstagefright/FileSource.cpp b/media/libstagefright/FileSource.cpp
index 02a78c9..f2f3500 100644
--- a/media/libstagefright/FileSource.cpp
+++ b/media/libstagefright/FileSource.cpp
@@ -125,7 +125,7 @@
return OK;
}
-DecryptHandle* FileSource::DrmInitialization() {
+sp<DecryptHandle> FileSource::DrmInitialization() {
if (mDrmManagerClient == NULL) {
mDrmManagerClient = new DrmManagerClient();
}
@@ -147,8 +147,8 @@
return mDecryptHandle;
}
-void FileSource::getDrmInfo(DecryptHandle **handle, DrmManagerClient **client) {
- *handle = mDecryptHandle;
+void FileSource::getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client) {
+ handle = mDecryptHandle;
*client = mDrmManagerClient;
}
diff --git a/media/libstagefright/HTTPBase.cpp b/media/libstagefright/HTTPBase.cpp
new file mode 100644
index 0000000..58b17a7
--- /dev/null
+++ b/media/libstagefright/HTTPBase.cpp
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+#include "include/HTTPBase.h"
+
+#if CHROMIUM_AVAILABLE
+#include "include/ChromiumHTTPDataSource.h"
+#endif
+
+#include "include/NuHTTPDataSource.h"
+
+#include <cutils/properties.h>
+
+namespace android {
+
+HTTPBase::HTTPBase() {}
+
+// static
+sp<HTTPBase> HTTPBase::Create(uint32_t flags) {
+#if CHROMIUM_AVAILABLE
+ char value[PROPERTY_VALUE_MAX];
+ if (!property_get("media.stagefright.use-chromium", value, NULL)
+ || (strcasecmp("false", value) && strcmp("0", value))) {
+ return new ChromiumHTTPDataSource(flags);
+ } else
+#endif
+ {
+ return new NuHTTPDataSource(flags);
+ }
+}
+
+} // namespace android
diff --git a/media/libstagefright/HTTPStream.cpp b/media/libstagefright/HTTPStream.cpp
index 498c7b8..2caf211 100644
--- a/media/libstagefright/HTTPStream.cpp
+++ b/media/libstagefright/HTTPStream.cpp
@@ -220,40 +220,58 @@
return ERROR_ALREADY_CONNECTED;
}
- struct hostent *ent = gethostbyname(server);
- if (ent == NULL) {
+ if (port < 0 || port > (int) USHRT_MAX) {
+ return UNKNOWN_ERROR;
+ }
+
+ char service[sizeof("65536")];
+ sprintf(service, "%d", port);
+ struct addrinfo hints, *ai;
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV;
+ hints.ai_socktype = SOCK_STREAM;
+
+ int ret = getaddrinfo(server, service, &hints, &ai);
+ if (ret) {
return ERROR_UNKNOWN_HOST;
}
CHECK_EQ(mSocket, -1);
- mSocket = socket(AF_INET, SOCK_STREAM, 0);
-
- if (mSocket < 0) {
- return UNKNOWN_ERROR;
- }
-
- setReceiveTimeout(30); // Time out reads after 30 secs by default
mState = CONNECTING;
+ status_t res = -1;
+ struct addrinfo *tmp;
+ for (tmp = ai; tmp; tmp = tmp->ai_next) {
+ mSocket = socket(tmp->ai_family, tmp->ai_socktype, tmp->ai_protocol);
+ if (mSocket < 0) {
+ continue;
+ }
- int s = mSocket;
+ setReceiveTimeout(30); // Time out reads after 30 secs by default.
- mLock.unlock();
+ int s = mSocket;
- struct sockaddr_in addr;
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
- addr.sin_addr.s_addr = *(in_addr_t *)ent->h_addr;
- memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
+ mLock.unlock();
- status_t res = MyConnect(s, (const struct sockaddr *)&addr, sizeof(addr));
+ res = MyConnect(s, tmp->ai_addr, tmp->ai_addrlen);
- mLock.lock();
+ mLock.lock();
- if (mState != CONNECTING) {
- return UNKNOWN_ERROR;
+ if (mState != CONNECTING) {
+ close(s);
+ freeaddrinfo(ai);
+ return UNKNOWN_ERROR;
+ }
+
+ if (res == OK) {
+ break;
+ }
+
+ close(s);
}
+ freeaddrinfo(ai);
+
if (res != OK) {
close(mSocket);
mSocket = -1;
diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp
index c7b99b9..7c65612 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libstagefright/NuCachedSource2.cpp
@@ -477,11 +477,11 @@
restartPrefetcherIfNecessary_l(true /* ignore low water threshold */);
}
-DecryptHandle* NuCachedSource2::DrmInitialization() {
+sp<DecryptHandle> NuCachedSource2::DrmInitialization() {
return mSource->DrmInitialization();
}
-void NuCachedSource2::getDrmInfo(DecryptHandle **handle, DrmManagerClient **client) {
+void NuCachedSource2::getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client) {
mSource->getDrmInfo(handle, client);
}
diff --git a/media/libstagefright/NuHTTPDataSource.cpp b/media/libstagefright/NuHTTPDataSource.cpp
index dbbf3b4..73daf12 100644
--- a/media/libstagefright/NuHTTPDataSource.cpp
+++ b/media/libstagefright/NuHTTPDataSource.cpp
@@ -1,3 +1,19 @@
+/*
+ * 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.
+ * 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.
+ */
+
//#define LOG_NDEBUG 0
#define LOG_TAG "NuHTTPDataSource"
#include <utils/Log.h>
@@ -514,7 +530,7 @@
}
}
-DecryptHandle* NuHTTPDataSource::DrmInitialization() {
+sp<DecryptHandle> NuHTTPDataSource::DrmInitialization() {
if (mDrmManagerClient == NULL) {
mDrmManagerClient = new DrmManagerClient();
}
@@ -538,8 +554,8 @@
return mDecryptHandle;
}
-void NuHTTPDataSource::getDrmInfo(DecryptHandle **handle, DrmManagerClient **client) {
- *handle = mDecryptHandle;
+void NuHTTPDataSource::getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client) {
+ handle = mDecryptHandle;
*client = mDrmManagerClient;
}
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 4a94e0d..3e26a95 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -528,6 +528,12 @@
mOnlySubmitOneBufferAtOneTime = true;
}
+ mEnableGrallocUsageProtected = false;
+ if (flags & kEnableGrallocUsageProtected) {
+ mEnableGrallocUsageProtected = true;
+ }
+ LOGV("configureCodec protected=%d", mEnableGrallocUsageProtected);
+
if (!(flags & kIgnoreCodecSpecificData)) {
uint32_t type;
const void *data;
@@ -1751,7 +1757,11 @@
// XXX: Currently this error is logged, but not fatal.
usage = 0;
}
+ if (mEnableGrallocUsageProtected) {
+ usage |= GRALLOC_USAGE_PROTECTED;
+ }
+ LOGV("native_window_set_usage usage=0x%x", usage);
err = native_window_set_usage(
mNativeWindow.get(), usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
if (err != 0) {
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index ea3b801..c371cd0 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -411,6 +411,12 @@
mMetaData.add(METADATA_KEY_NUM_TRACKS, String8(tmp));
+ bool hasAudio = false;
+ bool hasVideo = false;
+ int32_t videoWidth = -1;
+ int32_t videoHeight = -1;
+ int32_t audioBitrate = -1;
+
// The overall duration is the duration of the longest track.
int64_t maxDurationUs = 0;
for (size_t i = 0; i < numTracks; ++i) {
@@ -422,12 +428,55 @@
maxDurationUs = durationUs;
}
}
+
+ const char *mime;
+ if (trackMeta->findCString(kKeyMIMEType, &mime)) {
+ if (!hasAudio && !strncasecmp("audio/", mime, 6)) {
+ hasAudio = true;
+
+ if (!trackMeta->findInt32(kKeyBitRate, &audioBitrate)) {
+ audioBitrate = -1;
+ }
+ } else if (!hasVideo && !strncasecmp("video/", mime, 6)) {
+ hasVideo = true;
+
+ CHECK(trackMeta->findInt32(kKeyWidth, &videoWidth));
+ CHECK(trackMeta->findInt32(kKeyHeight, &videoHeight));
+ }
+ }
}
// The duration value is a string representing the duration in ms.
sprintf(tmp, "%lld", (maxDurationUs + 500) / 1000);
mMetaData.add(METADATA_KEY_DURATION, String8(tmp));
+ if (hasAudio) {
+ mMetaData.add(METADATA_KEY_HAS_AUDIO, String8("yes"));
+ }
+
+ if (hasVideo) {
+ mMetaData.add(METADATA_KEY_HAS_VIDEO, String8("yes"));
+
+ sprintf(tmp, "%d", videoWidth);
+ mMetaData.add(METADATA_KEY_VIDEO_WIDTH, String8(tmp));
+
+ sprintf(tmp, "%d", videoHeight);
+ mMetaData.add(METADATA_KEY_VIDEO_HEIGHT, String8(tmp));
+ }
+
+ if (numTracks == 1 && hasAudio && audioBitrate >= 0) {
+ sprintf(tmp, "%ld", audioBitrate);
+ mMetaData.add(METADATA_KEY_BITRATE, String8(tmp));
+ } else {
+ off64_t sourceSize;
+ if (mSource->getSize(&sourceSize) == OK) {
+ int64_t avgBitRate = (int64_t)(sourceSize * 8E6 / maxDurationUs);
+
+ sprintf(tmp, "%lld", avgBitRate);
+ mMetaData.add(METADATA_KEY_BITRATE, String8(tmp));
+ }
+ }
+
if (numTracks == 1) {
const char *fileMIME;
CHECK(meta->findCString(kKeyMIMEType, &fileMIME));
diff --git a/media/libstagefright/chromium_http/Android.mk b/media/libstagefright/chromium_http/Android.mk
new file mode 100644
index 0000000..80b2478
--- /dev/null
+++ b/media/libstagefright/chromium_http/Android.mk
@@ -0,0 +1,25 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ ChromiumHTTPDataSource.cpp \
+ support.cpp \
+
+LOCAL_C_INCLUDES:= \
+ $(JNI_H_INCLUDE) \
+ frameworks/base/media/libstagefright \
+ $(TOP)/frameworks/base/include/media/stagefright/openmax \
+ external/chromium \
+ external/chromium/android
+
+LOCAL_CFLAGS += -Wno-multichar
+
+ifneq ($(TARGET_SIMULATOR),true)
+LOCAL_SHARED_LIBRARIES += libstlport
+include external/stlport/libstlport.mk
+endif
+
+LOCAL_MODULE:= libstagefright_chromium_http
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp b/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp
new file mode 100644
index 0000000..949a5e4
--- /dev/null
+++ b/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp
@@ -0,0 +1,327 @@
+/*
+ * 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ChromiumHTTPDataSource"
+#include <media/stagefright/foundation/ADebug.h>
+
+#include "include/ChromiumHTTPDataSource.h"
+
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/MediaErrors.h>
+
+#include "support.h"
+
+namespace android {
+
+ChromiumHTTPDataSource::ChromiumHTTPDataSource(uint32_t flags)
+ : mFlags(flags),
+ mState(DISCONNECTED),
+ mDelegate(new SfDelegate),
+ mCurrentOffset(0),
+ mIOResult(OK),
+ mContentSize(-1),
+ mNumBandwidthHistoryItems(0),
+ mTotalTransferTimeUs(0),
+ mTotalTransferBytes(0),
+ mDecryptHandle(NULL),
+ mDrmManagerClient(NULL) {
+ mDelegate->setOwner(this);
+}
+
+ChromiumHTTPDataSource::~ChromiumHTTPDataSource() {
+ disconnect();
+
+ delete mDelegate;
+ mDelegate = NULL;
+
+ if (mDrmManagerClient != NULL) {
+ delete mDrmManagerClient;
+ mDrmManagerClient = NULL;
+ }
+}
+
+status_t ChromiumHTTPDataSource::connect(
+ const char *uri,
+ const KeyedVector<String8, String8> *headers,
+ off64_t offset) {
+ Mutex::Autolock autoLock(mLock);
+
+ return connect_l(uri, headers, offset);
+}
+
+status_t ChromiumHTTPDataSource::connect_l(
+ const char *uri,
+ const KeyedVector<String8, String8> *headers,
+ off64_t offset) {
+ if (mState != DISCONNECTED) {
+ disconnect_l();
+ }
+
+ if (!(mFlags & kFlagIncognito)) {
+ LOG_PRI(ANDROID_LOG_INFO, LOG_TAG, "connect to %s @%lld", uri, offset);
+ } else {
+ LOG_PRI(ANDROID_LOG_INFO, LOG_TAG,
+ "connect to <URL suppressed> @%lld", offset);
+ }
+
+ mURI = uri;
+
+ if (headers != NULL) {
+ mHeaders = *headers;
+ } else {
+ mHeaders.clear();
+ }
+
+ mState = CONNECTING;
+ mContentSize = -1;
+ mCurrentOffset = offset;
+
+ mDelegate->initiateConnection(mURI.c_str(), &mHeaders, offset);
+
+ while (mState == CONNECTING) {
+ mCondition.wait(mLock);
+ }
+
+ return mState == CONNECTED ? OK : mIOResult;
+}
+
+void ChromiumHTTPDataSource::onConnectionEstablished(int64_t contentSize) {
+ Mutex::Autolock autoLock(mLock);
+ mState = CONNECTED;
+ mContentSize = (contentSize < 0) ? -1 : contentSize + mCurrentOffset;
+ mCondition.broadcast();
+}
+
+void ChromiumHTTPDataSource::onConnectionFailed(status_t err) {
+ Mutex::Autolock autoLock(mLock);
+ mState = DISCONNECTED;
+ mCondition.broadcast();
+
+ mURI.clear();
+
+ mIOResult = err;
+
+ clearDRMState_l();
+}
+
+void ChromiumHTTPDataSource::disconnect() {
+ Mutex::Autolock autoLock(mLock);
+ disconnect_l();
+}
+
+void ChromiumHTTPDataSource::disconnect_l() {
+ if (mState == DISCONNECTED) {
+ return;
+ }
+
+ mState = DISCONNECTING;
+ mIOResult = -EINTR;
+
+ mDelegate->initiateDisconnect();
+
+ while (mState == DISCONNECTING) {
+ mCondition.wait(mLock);
+ }
+
+ CHECK_EQ((int)mState, (int)DISCONNECTED);
+}
+
+status_t ChromiumHTTPDataSource::initCheck() const {
+ Mutex::Autolock autoLock(mLock);
+
+ return mState == CONNECTED ? OK : NO_INIT;
+}
+
+ssize_t ChromiumHTTPDataSource::readAt(off64_t offset, void *data, size_t size) {
+ Mutex::Autolock autoLock(mLock);
+
+ if (mState != CONNECTED) {
+ return ERROR_NOT_CONNECTED;
+ }
+
+ if (offset != mCurrentOffset) {
+ AString tmp = mURI;
+ KeyedVector<String8, String8> tmpHeaders = mHeaders;
+
+ disconnect_l();
+
+ status_t err = connect_l(tmp.c_str(), &tmpHeaders, offset);
+
+ if (err != OK) {
+ return err;
+ }
+ }
+
+ mState = READING;
+
+ int64_t startTimeUs = ALooper::GetNowUs();
+
+ mDelegate->initiateRead(data, size);
+
+ while (mState == READING) {
+ mCondition.wait(mLock);
+ }
+
+ if (mIOResult < OK) {
+ return mIOResult;
+ }
+
+ if (mState == CONNECTED) {
+ int64_t delayUs = ALooper::GetNowUs() - startTimeUs;
+
+ // The read operation was successful, mIOResult contains
+ // the number of bytes read.
+ addBandwidthMeasurement_l(mIOResult, delayUs);
+
+ mCurrentOffset += mIOResult;
+ return mIOResult;
+ }
+
+ return ERROR_IO;
+}
+
+void ChromiumHTTPDataSource::onReadCompleted(ssize_t size) {
+ Mutex::Autolock autoLock(mLock);
+
+ mIOResult = size;
+
+ if (mState == READING) {
+ mState = CONNECTED;
+ mCondition.broadcast();
+ }
+}
+
+status_t ChromiumHTTPDataSource::getSize(off64_t *size) {
+ Mutex::Autolock autoLock(mLock);
+
+ if (mContentSize < 0) {
+ return ERROR_UNSUPPORTED;
+ }
+
+ *size = mContentSize;
+
+ return OK;
+}
+
+uint32_t ChromiumHTTPDataSource::flags() {
+ return kWantsPrefetching;
+}
+
+// static
+void ChromiumHTTPDataSource::InitiateRead(
+ ChromiumHTTPDataSource *me, void *data, size_t size) {
+ me->initiateRead(data, size);
+}
+
+void ChromiumHTTPDataSource::initiateRead(void *data, size_t size) {
+ mDelegate->initiateRead(data, size);
+}
+
+void ChromiumHTTPDataSource::onDisconnectComplete() {
+ Mutex::Autolock autoLock(mLock);
+ CHECK_EQ((int)mState, (int)DISCONNECTING);
+
+ mState = DISCONNECTED;
+ mURI.clear();
+
+ mCondition.broadcast();
+
+ clearDRMState_l();
+}
+
+void ChromiumHTTPDataSource::addBandwidthMeasurement_l(
+ size_t numBytes, int64_t delayUs) {
+ BandwidthEntry entry;
+ entry.mDelayUs = delayUs;
+ entry.mNumBytes = numBytes;
+ mTotalTransferTimeUs += delayUs;
+ mTotalTransferBytes += numBytes;
+
+ mBandwidthHistory.push_back(entry);
+ if (++mNumBandwidthHistoryItems > 100) {
+ BandwidthEntry *entry = &*mBandwidthHistory.begin();
+ mTotalTransferTimeUs -= entry->mDelayUs;
+ mTotalTransferBytes -= entry->mNumBytes;
+ mBandwidthHistory.erase(mBandwidthHistory.begin());
+ --mNumBandwidthHistoryItems;
+ }
+}
+
+bool ChromiumHTTPDataSource::estimateBandwidth(int32_t *bandwidth_bps) {
+ Mutex::Autolock autoLock(mLock);
+
+ if (mNumBandwidthHistoryItems < 2) {
+ return false;
+ }
+
+ *bandwidth_bps = ((double)mTotalTransferBytes * 8E6 / mTotalTransferTimeUs);
+
+ return true;
+}
+
+sp<DecryptHandle> ChromiumHTTPDataSource::DrmInitialization() {
+ Mutex::Autolock autoLock(mLock);
+
+ if (mDrmManagerClient == NULL) {
+ mDrmManagerClient = new DrmManagerClient();
+ }
+
+ if (mDrmManagerClient == NULL) {
+ return NULL;
+ }
+
+ if (mDecryptHandle == NULL) {
+ /* Note if redirect occurs, mUri is the redirect uri instead of the
+ * original one
+ */
+ mDecryptHandle = mDrmManagerClient->openDecryptSession(
+ String8(mURI.c_str()));
+ }
+
+ if (mDecryptHandle == NULL) {
+ delete mDrmManagerClient;
+ mDrmManagerClient = NULL;
+ }
+
+ return mDecryptHandle;
+}
+
+void ChromiumHTTPDataSource::getDrmInfo(
+ sp<DecryptHandle> &handle, DrmManagerClient **client) {
+ Mutex::Autolock autoLock(mLock);
+
+ handle = mDecryptHandle;
+ *client = mDrmManagerClient;
+}
+
+String8 ChromiumHTTPDataSource::getUri() {
+ Mutex::Autolock autoLock(mLock);
+
+ return String8(mURI.c_str());
+}
+
+void ChromiumHTTPDataSource::clearDRMState_l() {
+ if (mDecryptHandle != NULL) {
+ // To release mDecryptHandle
+ CHECK(mDrmManagerClient);
+ mDrmManagerClient->closeDecryptSession(mDecryptHandle);
+ mDecryptHandle = NULL;
+ }
+}
+
+} // namespace android
+
diff --git a/media/libstagefright/chromium_http/support.cpp b/media/libstagefright/chromium_http/support.cpp
new file mode 100644
index 0000000..7ac56e8
--- /dev/null
+++ b/media/libstagefright/chromium_http/support.cpp
@@ -0,0 +1,457 @@
+/*
+ * 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ChromiumHTTPDataSourceSupport"
+#include <utils/Log.h>
+
+#include <media/stagefright/foundation/AString.h>
+
+#include "support.h"
+
+#include "android/net/android_network_library_impl.h"
+#include "base/thread.h"
+#include "net/base/host_resolver.h"
+#include "net/base/ssl_config_service.h"
+#include "net/http/http_auth_handler_factory.h"
+#include "net/http/http_cache.h"
+#include "net/proxy/proxy_config_service_android.h"
+
+#include "include/ChromiumHTTPDataSource.h"
+
+#include <cutils/properties.h>
+#include <media/stagefright/MediaErrors.h>
+
+namespace android {
+
+static Mutex gNetworkThreadLock;
+static base::Thread *gNetworkThread = NULL;
+static scoped_refptr<URLRequestContext> gReqContext;
+
+static void InitializeNetworkThreadIfNecessary() {
+ Mutex::Autolock autoLock(gNetworkThreadLock);
+ if (gNetworkThread == NULL) {
+ gNetworkThread = new base::Thread("network");
+ base::Thread::Options options;
+ options.message_loop_type = MessageLoop::TYPE_IO;
+ CHECK(gNetworkThread->StartWithOptions(options));
+
+ gReqContext = new SfRequestContext;
+
+ net::AndroidNetworkLibrary::RegisterSharedInstance(
+ new SfNetworkLibrary);
+ }
+}
+
+static void MY_LOGI(const char *s) {
+ LOG_PRI(ANDROID_LOG_INFO, LOG_TAG, "%s", s);
+}
+
+static void MY_LOGV(const char *s) {
+#if !defined(LOG_NDEBUG) || LOG_NDEBUG == 0
+ LOG_PRI(ANDROID_LOG_VERBOSE, LOG_TAG, "%s", s);
+#endif
+}
+
+SfNetLog::SfNetLog()
+ : mNextID(1) {
+}
+
+void SfNetLog::AddEntry(
+ EventType type,
+ const base::TimeTicks &time,
+ const Source &source,
+ EventPhase phase,
+ EventParameters *params) {
+#if 0
+ MY_LOGI(StringPrintf(
+ "AddEntry time=%s type=%s source=%s phase=%s\n",
+ TickCountToString(time).c_str(),
+ EventTypeToString(type),
+ SourceTypeToString(source.type),
+ EventPhaseToString(phase)).c_str());
+#endif
+}
+
+uint32 SfNetLog::NextID() {
+ return mNextID++;
+}
+
+net::NetLog::LogLevel SfNetLog::GetLogLevel() const {
+ return LOG_ALL;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+SfRequestContext::SfRequestContext() {
+ AString ua;
+ ua.append("stagefright/1.2 (Linux;Android ");
+
+#if (PROPERTY_VALUE_MAX < 8)
+#error "PROPERTY_VALUE_MAX must be at least 8"
+#endif
+
+ char value[PROPERTY_VALUE_MAX];
+ property_get("ro.build.version.release", value, "Unknown");
+ ua.append(value);
+ ua.append(")");
+
+ mUserAgent = ua.c_str();
+
+ net_log_ = new SfNetLog;
+
+ host_resolver_ =
+ net::CreateSystemHostResolver(
+ net::HostResolver::kDefaultParallelism,
+ NULL /* resolver_proc */,
+ net_log_);
+
+ ssl_config_service_ =
+ net::SSLConfigService::CreateSystemSSLConfigService();
+
+ proxy_service_ = net::ProxyService::CreateWithoutProxyResolver(
+ new net::ProxyConfigServiceAndroid, net_log_);
+
+ http_transaction_factory_ = new net::HttpCache(
+ host_resolver_,
+ dnsrr_resolver_,
+ dns_cert_checker_.get(),
+ proxy_service_.get(),
+ ssl_config_service_.get(),
+ net::HttpAuthHandlerFactory::CreateDefault(host_resolver_),
+ network_delegate_,
+ net_log_,
+ NULL); // backend_factory
+}
+
+const std::string &SfRequestContext::GetUserAgent(const GURL &url) const {
+ return mUserAgent;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+SfNetworkLibrary::SfNetworkLibrary() {}
+
+SfNetworkLibrary::VerifyResult SfNetworkLibrary::VerifyX509CertChain(
+ const std::vector<std::string>& cert_chain,
+ const std::string& hostname,
+ const std::string& auth_type) {
+ return VERIFY_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+SfDelegate::SfDelegate()
+ : mOwner(NULL),
+ mURLRequest(NULL),
+ mReadBuffer(new net::IOBufferWithSize(8192)),
+ mNumBytesRead(0),
+ mNumBytesTotal(0),
+ mDataDestination(NULL),
+ mAtEOS(false) {
+ InitializeNetworkThreadIfNecessary();
+}
+
+SfDelegate::~SfDelegate() {
+ CHECK(mURLRequest == NULL);
+}
+
+void SfDelegate::setOwner(ChromiumHTTPDataSource *owner) {
+ mOwner = owner;
+}
+
+void SfDelegate::OnReceivedRedirect(
+ URLRequest *request, const GURL &new_url, bool *defer_redirect) {
+ MY_LOGI("OnReceivedRedirect");
+}
+
+void SfDelegate::OnAuthRequired(
+ URLRequest *request, net::AuthChallengeInfo *auth_info) {
+ MY_LOGI("OnAuthRequired");
+
+ inherited::OnAuthRequired(request, auth_info);
+}
+
+void SfDelegate::OnCertificateRequested(
+ URLRequest *request, net::SSLCertRequestInfo *cert_request_info) {
+ MY_LOGI("OnCertificateRequested");
+
+ inherited::OnCertificateRequested(request, cert_request_info);
+}
+
+void SfDelegate::OnSSLCertificateError(
+ URLRequest *request, int cert_error, net::X509Certificate *cert) {
+ fprintf(stderr, "OnSSLCertificateError cert_error=%d\n", cert_error);
+
+ inherited::OnSSLCertificateError(request, cert_error, cert);
+}
+
+void SfDelegate::OnGetCookies(URLRequest *request, bool blocked_by_policy) {
+ MY_LOGI("OnGetCookies");
+}
+
+void SfDelegate::OnSetCookie(
+ URLRequest *request,
+ const std::string &cookie_line,
+ const net::CookieOptions &options,
+ bool blocked_by_policy) {
+ MY_LOGI("OnSetCookie");
+}
+
+void SfDelegate::OnResponseStarted(URLRequest *request) {
+ if (request->status().status() != URLRequestStatus::SUCCESS) {
+ MY_LOGI(StringPrintf(
+ "Request failed with status %d and os_error %d",
+ request->status().status(),
+ request->status().os_error()).c_str());
+
+ delete mURLRequest;
+ mURLRequest = NULL;
+
+ mOwner->onConnectionFailed(ERROR_IO);
+ return;
+ } else if (mRangeRequested && request->GetResponseCode() != 206) {
+ MY_LOGI(StringPrintf(
+ "We requested a content range, but server didn't "
+ "support that. (responded with %d)",
+ request->GetResponseCode()).c_str());
+
+ delete mURLRequest;
+ mURLRequest = NULL;
+
+ mOwner->onConnectionFailed(-EPIPE);
+ return;
+ } else if ((request->GetResponseCode() / 100) != 2) {
+ MY_LOGI(StringPrintf(
+ "Server responded with http status %d",
+ request->GetResponseCode()).c_str());
+
+ delete mURLRequest;
+ mURLRequest = NULL;
+
+ mOwner->onConnectionFailed(ERROR_IO);
+ return;
+ }
+
+ MY_LOGV("OnResponseStarted");
+
+ std::string headers;
+ request->GetAllResponseHeaders(&headers);
+
+ MY_LOGV(StringPrintf("response headers: %s", headers.c_str()).c_str());
+
+ mOwner->onConnectionEstablished(request->GetExpectedContentSize());
+}
+
+void SfDelegate::OnReadCompleted(URLRequest *request, int bytes_read) {
+ if (bytes_read == -1) {
+ MY_LOGI(StringPrintf(
+ "OnReadCompleted, read failed, status %d",
+ request->status().status()).c_str());
+
+ mOwner->onReadCompleted(ERROR_IO);
+ return;
+ }
+
+ MY_LOGV(StringPrintf("OnReadCompleted, read %d bytes", bytes_read).c_str());
+
+ if (bytes_read < 0) {
+ MY_LOGI(StringPrintf(
+ "Read failed w/ status %d\n",
+ request->status().status()).c_str());
+
+ mOwner->onReadCompleted(ERROR_IO);
+ return;
+ } else if (bytes_read == 0) {
+ mAtEOS = true;
+ mOwner->onReadCompleted(mNumBytesRead);
+ return;
+ }
+
+ CHECK_GT(bytes_read, 0);
+ CHECK_LE(mNumBytesRead + bytes_read, mNumBytesTotal);
+
+ memcpy((uint8_t *)mDataDestination + mNumBytesRead,
+ mReadBuffer->data(),
+ bytes_read);
+
+ mNumBytesRead += bytes_read;
+
+ readMore(request);
+}
+
+void SfDelegate::readMore(URLRequest *request) {
+ while (mNumBytesRead < mNumBytesTotal) {
+ size_t copy = mNumBytesTotal - mNumBytesRead;
+ if (copy > mReadBuffer->size()) {
+ copy = mReadBuffer->size();
+ }
+
+ int n;
+ if (request->Read(mReadBuffer, copy, &n)) {
+ MY_LOGV(StringPrintf("Read %d bytes directly.", n).c_str());
+
+ CHECK_LE((size_t)n, copy);
+
+ memcpy((uint8_t *)mDataDestination + mNumBytesRead,
+ mReadBuffer->data(),
+ n);
+
+ mNumBytesRead += n;
+
+ if (n == 0) {
+ mAtEOS = true;
+ break;
+ }
+ } else {
+ MY_LOGV("readMore pending read");
+
+ if (request->status().status() != URLRequestStatus::IO_PENDING) {
+ MY_LOGI(StringPrintf(
+ "Direct read failed w/ status %d\n",
+ request->status().status()).c_str());
+
+ mOwner->onReadCompleted(ERROR_IO);
+ return;
+ }
+
+ return;
+ }
+ }
+
+ mOwner->onReadCompleted(mNumBytesRead);
+}
+
+void SfDelegate::initiateConnection(
+ const char *uri,
+ const KeyedVector<String8, String8> *headers,
+ off64_t offset) {
+ GURL url(uri);
+
+ MessageLoop *loop = gNetworkThread->message_loop();
+ loop->PostTask(
+ FROM_HERE,
+ NewRunnableFunction(
+ &SfDelegate::OnInitiateConnectionWrapper,
+ this,
+ url,
+ headers,
+ offset));
+
+}
+
+// static
+void SfDelegate::OnInitiateConnectionWrapper(
+ SfDelegate *me, GURL url,
+ const KeyedVector<String8, String8> *headers,
+ off64_t offset) {
+ me->onInitiateConnection(url, headers, offset);
+}
+
+void SfDelegate::onInitiateConnection(
+ const GURL &url,
+ const KeyedVector<String8, String8> *extra,
+ off64_t offset) {
+ CHECK(mURLRequest == NULL);
+
+ mURLRequest = new URLRequest(url, this);
+ mAtEOS = false;
+
+ mRangeRequested = false;
+
+ if (offset != 0 || extra != NULL) {
+ net::HttpRequestHeaders headers =
+ mURLRequest->extra_request_headers();
+
+ if (offset != 0) {
+ headers.AddHeaderFromString(
+ StringPrintf("Range: bytes=%lld-", offset).c_str());
+
+ mRangeRequested = true;
+ }
+
+ if (extra != NULL) {
+ for (size_t i = 0; i < extra->size(); ++i) {
+ AString s;
+ s.append(extra->keyAt(i).string());
+ s.append(": ");
+ s.append(extra->valueAt(i).string());
+
+ headers.AddHeaderFromString(s.c_str());
+ }
+ }
+
+ mURLRequest->SetExtraRequestHeaders(headers);
+ }
+
+ mURLRequest->set_context(gReqContext);
+
+ mURLRequest->Start();
+}
+
+void SfDelegate::initiateDisconnect() {
+ MessageLoop *loop = gNetworkThread->message_loop();
+ loop->PostTask(
+ FROM_HERE,
+ NewRunnableFunction(
+ &SfDelegate::OnInitiateDisconnectWrapper, this));
+}
+
+// static
+void SfDelegate::OnInitiateDisconnectWrapper(SfDelegate *me) {
+ me->onInitiateDisconnect();
+}
+
+void SfDelegate::onInitiateDisconnect() {
+ mURLRequest->Cancel();
+
+ delete mURLRequest;
+ mURLRequest = NULL;
+
+ mOwner->onDisconnectComplete();
+}
+
+void SfDelegate::initiateRead(void *data, size_t size) {
+ MessageLoop *loop = gNetworkThread->message_loop();
+ loop->PostTask(
+ FROM_HERE,
+ NewRunnableFunction(
+ &SfDelegate::OnInitiateReadWrapper, this, data, size));
+}
+
+// static
+void SfDelegate::OnInitiateReadWrapper(
+ SfDelegate *me, void *data, size_t size) {
+ me->onInitiateRead(data, size);
+}
+
+void SfDelegate::onInitiateRead(void *data, size_t size) {
+ CHECK(mURLRequest != NULL);
+
+ mNumBytesRead = 0;
+ mNumBytesTotal = size;
+ mDataDestination = data;
+
+ if (mAtEOS) {
+ mOwner->onReadCompleted(0);
+ return;
+ }
+
+ readMore(mURLRequest);
+}
+
+} // namespace android
+
diff --git a/media/libstagefright/chromium_http/support.h b/media/libstagefright/chromium_http/support.h
new file mode 100644
index 0000000..634ac93
--- /dev/null
+++ b/media/libstagefright/chromium_http/support.h
@@ -0,0 +1,159 @@
+/*
+ * 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.
+ */
+
+#ifndef SUPPORT_H_
+
+#define SUPPORT_H_
+
+#include <assert.h>
+
+#include "net/base/net_log.h"
+#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_context.h"
+#include "net/base/android_network_library.h"
+#include "net/base/io_buffer.h"
+
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+
+namespace android {
+
+struct SfNetLog : public net::NetLog {
+ SfNetLog();
+
+ virtual void AddEntry(
+ EventType type,
+ const base::TimeTicks &time,
+ const Source &source,
+ EventPhase phase,
+ EventParameters *params);
+
+ virtual uint32 NextID();
+ virtual LogLevel GetLogLevel() const;
+
+private:
+ uint32 mNextID;
+
+ DISALLOW_EVIL_CONSTRUCTORS(SfNetLog);
+};
+
+struct SfRequestContext : public URLRequestContext {
+ SfRequestContext();
+
+ virtual const std::string &GetUserAgent(const GURL &url) const;
+
+private:
+ std::string mUserAgent;
+
+ DISALLOW_EVIL_CONSTRUCTORS(SfRequestContext);
+};
+
+// This is required for https support, we don't really verify certificates,
+// we accept anything...
+struct SfNetworkLibrary : public net::AndroidNetworkLibrary {
+ SfNetworkLibrary();
+
+ virtual VerifyResult VerifyX509CertChain(
+ const std::vector<std::string>& cert_chain,
+ const std::string& hostname,
+ const std::string& auth_type);
+
+private:
+ DISALLOW_EVIL_CONSTRUCTORS(SfNetworkLibrary);
+};
+
+struct ChromiumHTTPDataSource;
+
+struct SfDelegate : public URLRequest::Delegate {
+ SfDelegate();
+ virtual ~SfDelegate();
+
+ void initiateConnection(
+ const char *uri,
+ const KeyedVector<String8, String8> *headers,
+ off64_t offset);
+
+ void initiateDisconnect();
+ void initiateRead(void *data, size_t size);
+
+ void setOwner(ChromiumHTTPDataSource *mOwner);
+
+ virtual void OnReceivedRedirect(
+ URLRequest *request, const GURL &new_url, bool *defer_redirect);
+
+ virtual void OnAuthRequired(
+ URLRequest *request, net::AuthChallengeInfo *auth_info);
+
+ virtual void OnCertificateRequested(
+ URLRequest *request, net::SSLCertRequestInfo *cert_request_info);
+
+ virtual void OnSSLCertificateError(
+ URLRequest *request, int cert_error, net::X509Certificate *cert);
+
+ virtual void OnGetCookies(URLRequest *request, bool blocked_by_policy);
+
+ virtual void OnSetCookie(
+ URLRequest *request,
+ const std::string &cookie_line,
+ const net::CookieOptions &options,
+ bool blocked_by_policy);
+
+ virtual void OnResponseStarted(URLRequest *request);
+
+ virtual void OnReadCompleted(URLRequest *request, int bytes_read);
+
+private:
+ typedef Delegate inherited;
+
+ ChromiumHTTPDataSource *mOwner;
+
+ URLRequest *mURLRequest;
+ scoped_refptr<net::IOBufferWithSize> mReadBuffer;
+
+ size_t mNumBytesRead;
+ size_t mNumBytesTotal;
+ void *mDataDestination;
+
+ bool mRangeRequested;
+ bool mAtEOS;
+
+ void readMore(URLRequest *request);
+
+ static void OnInitiateConnectionWrapper(
+ SfDelegate *me,
+ GURL url,
+ const KeyedVector<String8, String8> *headers,
+ off64_t offset);
+
+ static void OnInitiateDisconnectWrapper(SfDelegate *me);
+
+ static void OnInitiateReadWrapper(
+ SfDelegate *me, void *data, size_t size);
+
+ void onInitiateConnection(
+ const GURL &url,
+ const KeyedVector<String8, String8> *headers,
+ off64_t offset);
+
+ void onInitiateDisconnect();
+ void onInitiateRead(void *data, size_t size);
+
+ DISALLOW_EVIL_CONSTRUCTORS(SfDelegate);
+};
+
+} // namespace android
+
+#endif // SUPPORT_H_
diff --git a/media/libstagefright/codecs/aacenc/AACEncoder.cpp b/media/libstagefright/codecs/aacenc/AACEncoder.cpp
index a8b1292..e4ff128 100644
--- a/media/libstagefright/codecs/aacenc/AACEncoder.cpp
+++ b/media/libstagefright/codecs/aacenc/AACEncoder.cpp
@@ -189,6 +189,9 @@
delete mApiHandle;
mApiHandle = NULL;
+ delete mMemOperator;
+ mMemOperator = NULL;
+
mStarted = false;
return OK;
diff --git a/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp b/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp
index 59dd740..0ba42ff 100644
--- a/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp
+++ b/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp
@@ -14,6 +14,9 @@
* limitations under the License.
*/
+//#define LOG_NDEBUG 0
+#define LOG_TAG "MP3Decoder"
+
#include "MP3Decoder.h"
#include "include/pvmp3decoder_api.h"
@@ -175,7 +178,12 @@
!= NO_DECODING_ERROR) {
LOGV("mp3 decoder returned error %d", decoderErr);
- if (decoderErr != NO_ENOUGH_MAIN_DATA_ERROR) {
+ if (decoderErr != NO_ENOUGH_MAIN_DATA_ERROR ||
+ mConfig->outputFrameSize == 0) {
+
+ if (mConfig->outputFrameSize == 0) {
+ LOGE("Output frame size is 0");
+ }
buffer->release();
buffer = NULL;
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index f0cd6a0..8e1bdf3 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -23,7 +23,7 @@
#include "LiveDataSource.h"
#include "include/M3UParser.h"
-#include "include/NuHTTPDataSource.h"
+#include "include/HTTPBase.h"
#include <cutils/properties.h>
#include <media/stagefright/foundation/hexdump.h>
@@ -45,9 +45,9 @@
: mFlags(flags),
mDataSource(new LiveDataSource),
mHTTPDataSource(
- new NuHTTPDataSource(
+ HTTPBase::Create(
(mFlags & kFlagIncognito)
- ? NuHTTPDataSource::kFlagIncognito
+ ? HTTPBase::kFlagIncognito
: 0)),
mPrevBandwidthIndex(-1),
mLastPlaylistFetchTimeUs(-1),
@@ -625,7 +625,12 @@
} else {
key = new ABuffer(16);
- sp<NuHTTPDataSource> keySource = new NuHTTPDataSource;
+ sp<HTTPBase> keySource =
+ HTTPBase::Create(
+ (mFlags & kFlagIncognito)
+ ? HTTPBase::kFlagIncognito
+ : 0);
+
status_t err = keySource->connect(keyURI.c_str());
if (err == OK) {
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index 4e6f75c..b26f202 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -18,7 +18,7 @@
#define AWESOME_PLAYER_H_
-#include "NuHTTPDataSource.h"
+#include "HTTPBase.h"
#include "TimedEventQueue.h"
#include <media/MediaPlayerInterface.h>
@@ -209,7 +209,7 @@
MediaBuffer *mVideoBuffer;
- sp<NuHTTPDataSource> mConnectingDataSource;
+ sp<HTTPBase> mConnectingDataSource;
sp<NuCachedSource2> mCachedSource;
sp<ALooper> mLooper;
@@ -217,7 +217,7 @@
sp<ARTSPController> mConnectingRTSPController;
DrmManagerClient *mDrmManagerClient;
- DecryptHandle *mDecryptHandle;
+ sp<DecryptHandle> mDecryptHandle;
status_t setDataSource_l(
const char *uri,
diff --git a/media/libstagefright/include/ChromiumHTTPDataSource.h b/media/libstagefright/include/ChromiumHTTPDataSource.h
new file mode 100644
index 0000000..af49059
--- /dev/null
+++ b/media/libstagefright/include/ChromiumHTTPDataSource.h
@@ -0,0 +1,127 @@
+/*
+ * 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.
+ */
+
+#ifndef CHROME_HTTP_DATA_SOURCE_H_
+
+#define CHROME_HTTP_DATA_SOURCE_H_
+
+#include <media/stagefright/foundation/AString.h>
+#include <utils/threads.h>
+
+#include "HTTPBase.h"
+
+namespace android {
+
+struct SfDelegate;
+
+struct ChromiumHTTPDataSource : public HTTPBase {
+ ChromiumHTTPDataSource(uint32_t flags = 0);
+
+ virtual status_t connect(
+ const char *uri,
+ const KeyedVector<String8, String8> *headers = NULL,
+ off64_t offset = 0);
+
+ virtual void disconnect();
+
+ virtual status_t initCheck() const;
+
+ virtual ssize_t readAt(off64_t offset, void *data, size_t size);
+ virtual status_t getSize(off64_t *size);
+ virtual uint32_t flags();
+
+ virtual bool estimateBandwidth(int32_t *bandwidth_bps);
+
+ virtual sp<DecryptHandle> DrmInitialization();
+
+ virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client);
+
+ virtual String8 getUri();
+
+protected:
+ virtual ~ChromiumHTTPDataSource();
+
+private:
+ friend struct SfDelegate;
+
+ enum State {
+ DISCONNECTED,
+ CONNECTING,
+ CONNECTED,
+ READING,
+ DISCONNECTING
+ };
+
+ struct BandwidthEntry {
+ int64_t mDelayUs;
+ size_t mNumBytes;
+ };
+
+ const uint32_t mFlags;
+
+ mutable Mutex mLock;
+ Condition mCondition;
+
+ State mState;
+
+ SfDelegate *mDelegate;
+
+ AString mURI;
+ KeyedVector<String8, String8> mHeaders;
+
+ off64_t mCurrentOffset;
+
+ // Any connection error or the result of a read operation
+ // (for the lattter this is the number of bytes read, if successful).
+ ssize_t mIOResult;
+
+ int64_t mContentSize;
+
+ List<BandwidthEntry> mBandwidthHistory;
+ size_t mNumBandwidthHistoryItems;
+ int64_t mTotalTransferTimeUs;
+ size_t mTotalTransferBytes;
+
+ sp<DecryptHandle> mDecryptHandle;
+ DrmManagerClient *mDrmManagerClient;
+
+ void disconnect_l();
+
+ status_t connect_l(
+ const char *uri,
+ const KeyedVector<String8, String8> *headers,
+ off64_t offset);
+
+ static void InitiateRead(
+ ChromiumHTTPDataSource *me, void *data, size_t size);
+
+ void initiateRead(void *data, size_t size);
+
+ void onConnectionEstablished(int64_t contentSize);
+ void onConnectionFailed(status_t err);
+ void onReadCompleted(ssize_t size);
+ void onDisconnectComplete();
+
+ void addBandwidthMeasurement_l(size_t numBytes, int64_t delayUs);
+
+ void clearDRMState_l();
+
+ DISALLOW_EVIL_CONSTRUCTORS(ChromiumHTTPDataSource);
+};
+
+} // namespace android
+
+#endif // CHROME_HTTP_DATA_SOURCE_H_
diff --git a/media/libstagefright/include/DRMExtractor.h b/media/libstagefright/include/DRMExtractor.h
index 9881cc1..b4e4afb 100644
--- a/media/libstagefright/include/DRMExtractor.h
+++ b/media/libstagefright/include/DRMExtractor.h
@@ -45,7 +45,7 @@
sp<DataSource> mDataSource;
sp<MediaExtractor> mOriginalExtractor;
- DecryptHandle* mDecryptHandle;
+ sp<DecryptHandle> mDecryptHandle;
DrmManagerClient* mDrmManagerClient;
DRMExtractor(const DRMExtractor &);
diff --git a/media/libstagefright/include/HTTPBase.h b/media/libstagefright/include/HTTPBase.h
new file mode 100644
index 0000000..6cec390
--- /dev/null
+++ b/media/libstagefright/include/HTTPBase.h
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+#ifndef HTTP_BASE_H_
+
+#define HTTP_BASE_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/DataSource.h>
+
+namespace android {
+
+struct HTTPBase : public DataSource {
+ enum Flags {
+ // Don't log any URLs.
+ kFlagIncognito = 1
+ };
+
+ HTTPBase();
+
+ virtual status_t connect(
+ const char *uri,
+ const KeyedVector<String8, String8> *headers = NULL,
+ off64_t offset = 0) = 0;
+
+ virtual void disconnect() = 0;
+
+ // Returns true if bandwidth could successfully be estimated,
+ // false otherwise.
+ virtual bool estimateBandwidth(int32_t *bandwidth_bps) = 0;
+
+ static sp<HTTPBase> Create(uint32_t flags = 0);
+
+private:
+ DISALLOW_EVIL_CONSTRUCTORS(HTTPBase);
+};
+
+} // namespace android
+
+#endif // HTTP_BASE_H_
diff --git a/media/libstagefright/include/LiveSession.h b/media/libstagefright/include/LiveSession.h
index 3fe5d4e..2b5ea0e 100644
--- a/media/libstagefright/include/LiveSession.h
+++ b/media/libstagefright/include/LiveSession.h
@@ -26,7 +26,7 @@
struct DataSource;
struct LiveDataSource;
struct M3UParser;
-struct NuHTTPDataSource;
+struct HTTPBase;
struct LiveSession : public AHandler {
enum Flags {
@@ -75,7 +75,7 @@
sp<LiveDataSource> mDataSource;
- sp<NuHTTPDataSource> mHTTPDataSource;
+ sp<HTTPBase> mHTTPDataSource;
AString mMasterURL;
Vector<BandwidthItem> mBandwidthItems;
diff --git a/media/libstagefright/include/NuCachedSource2.h b/media/libstagefright/include/NuCachedSource2.h
index 022804c..02d5817 100644
--- a/media/libstagefright/include/NuCachedSource2.h
+++ b/media/libstagefright/include/NuCachedSource2.h
@@ -37,8 +37,8 @@
virtual status_t getSize(off64_t *size);
virtual uint32_t flags();
- virtual DecryptHandle* DrmInitialization();
- virtual void getDrmInfo(DecryptHandle **handle, DrmManagerClient **client);
+ virtual sp<DecryptHandle> DrmInitialization();
+ virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client);
virtual String8 getUri();
////////////////////////////////////////////////////////////////////////////
diff --git a/media/libstagefright/include/NuHTTPDataSource.h b/media/libstagefright/include/NuHTTPDataSource.h
index 082b589..7dd5d59 100644
--- a/media/libstagefright/include/NuHTTPDataSource.h
+++ b/media/libstagefright/include/NuHTTPDataSource.h
@@ -1,29 +1,41 @@
+/*
+ * 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.
+ * 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.
+ */
+
#ifndef NU_HTTP_DATA_SOURCE_H_
#define NU_HTTP_DATA_SOURCE_H_
-#include <media/stagefright/DataSource.h>
#include <utils/List.h>
#include <utils/String8.h>
#include <utils/threads.h>
#include "HTTPStream.h"
+#include "include/HTTPBase.h"
namespace android {
-struct NuHTTPDataSource : public DataSource {
- enum Flags {
- // Don't log any URLs.
- kFlagIncognito = 1
- };
+struct NuHTTPDataSource : public HTTPBase {
NuHTTPDataSource(uint32_t flags = 0);
- status_t connect(
+ virtual status_t connect(
const char *uri,
const KeyedVector<String8, String8> *headers = NULL,
off64_t offset = 0);
- void disconnect();
+ virtual void disconnect();
virtual status_t initCheck() const;
@@ -33,10 +45,10 @@
// Returns true if bandwidth could successfully be estimated,
// false otherwise.
- bool estimateBandwidth(int32_t *bandwidth_bps);
+ virtual bool estimateBandwidth(int32_t *bandwidth_bps);
- virtual DecryptHandle* DrmInitialization();
- virtual void getDrmInfo(DecryptHandle **handle, DrmManagerClient **client);
+ virtual sp<DecryptHandle> DrmInitialization();
+ virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client);
virtual String8 getUri();
protected:
@@ -82,7 +94,7 @@
int64_t mTotalTransferTimeUs;
size_t mTotalTransferBytes;
- DecryptHandle *mDecryptHandle;
+ sp<DecryptHandle> mDecryptHandle;
DrmManagerClient *mDrmManagerClient;
status_t connect(
diff --git a/media/mtp/MtpDataPacket.cpp b/media/mtp/MtpDataPacket.cpp
index 801edb0..0b0c80d 100644
--- a/media/mtp/MtpDataPacket.cpp
+++ b/media/mtp/MtpDataPacket.cpp
@@ -28,7 +28,7 @@
namespace android {
MtpDataPacket::MtpDataPacket()
- : MtpPacket(512),
+ : MtpPacket(16384), // MAX_USBFS_BUFFER_SIZE
mOffset(MTP_CONTAINER_HEADER_SIZE)
{
}
@@ -399,10 +399,10 @@
if (length >= MTP_CONTAINER_HEADER_SIZE) {
// look at the length field to see if the data spans multiple packets
uint32_t totalLength = MtpPacket::getUInt32(MTP_CONTAINER_LENGTH_OFFSET);
+ allocate(totalLength);
while (totalLength > length) {
- allocate(length + mAllocationIncrement);
request->buffer = mBuffer + length;
- request->buffer_length = mAllocationIncrement;
+ request->buffer_length = totalLength - length;
int ret = transfer(request);
if (ret >= 0)
length += ret;
diff --git a/media/tests/CameraBrowser/Android.mk b/media/tests/CameraBrowser/Android.mk
index 1d81129..46596a7 100644
--- a/media/tests/CameraBrowser/Android.mk
+++ b/media/tests/CameraBrowser/Android.mk
@@ -7,4 +7,6 @@
LOCAL_PACKAGE_NAME := CameraBrowser
+LOCAL_SDK_VERSION := current
+
include $(BUILD_PACKAGE)
diff --git a/media/tests/CameraBrowser/src/com/android/camerabrowser/CameraBrowser.java b/media/tests/CameraBrowser/src/com/android/camerabrowser/CameraBrowser.java
index f642d93..af17ded 100644
--- a/media/tests/CameraBrowser/src/com/android/camerabrowser/CameraBrowser.java
+++ b/media/tests/CameraBrowser/src/com/android/camerabrowser/CameraBrowser.java
@@ -20,7 +20,6 @@
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
-import android.mtp.MtpClient;
import android.mtp.MtpDevice;
import android.mtp.MtpDeviceInfo;
import android.os.Bundle;
@@ -79,8 +78,8 @@
view = (TwoLineListItem)convertView;
}
- TextView textView1 = (TextView)view.findViewById(com.android.internal.R.id.text1);
- TextView textView2 = (TextView)view.findViewById(com.android.internal.R.id.text2);
+ TextView textView1 = (TextView)view.findViewById(android.R.id.text1);
+ TextView textView2 = (TextView)view.findViewById(android.R.id.text2);
MtpDevice device = mDeviceList.get(position);
MtpDeviceInfo info = device.getDeviceInfo();
if (info != null) {
diff --git a/media/tests/CameraBrowser/src/com/android/camerabrowser/CameraBrowserApplication.java b/media/tests/CameraBrowser/src/com/android/camerabrowser/CameraBrowserApplication.java
index 6f1edfea..8075862 100644
--- a/media/tests/CameraBrowser/src/com/android/camerabrowser/CameraBrowserApplication.java
+++ b/media/tests/CameraBrowser/src/com/android/camerabrowser/CameraBrowserApplication.java
@@ -17,8 +17,6 @@
package com.android.camerabrowser;
import android.app.Application;
-import android.mtp.MtpClient;
-
public class CameraBrowserApplication extends Application {
diff --git a/media/java/android/mtp/MtpClient.java b/media/tests/CameraBrowser/src/com/android/camerabrowser/MtpClient.java
similarity index 77%
rename from media/java/android/mtp/MtpClient.java
rename to media/tests/CameraBrowser/src/com/android/camerabrowser/MtpClient.java
index c4ee19e..edb5e37 100644
--- a/media/java/android/mtp/MtpClient.java
+++ b/media/tests/CameraBrowser/src/com/android/camerabrowser/MtpClient.java
@@ -14,21 +14,28 @@
* limitations under the License.
*/
-package android.mtp;
+package com.android.camerabrowser;
+import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
+import android.mtp.MtpDevice;
+import android.mtp.MtpDeviceInfo;
+import android.mtp.MtpObjectInfo;
+import android.mtp.MtpStorageInfo;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
/**
@@ -40,34 +47,58 @@
private static final String TAG = "MtpClient";
+ private static final String ACTION_USB_PERMISSION =
+ "android.mtp.MtpClient.action.USB_PERMISSION";
+
private final Context mContext;
private final UsbManager mUsbManager;
private final ArrayList<Listener> mListeners = new ArrayList<Listener>();
- private final ArrayList<MtpDevice> mDeviceList = new ArrayList<MtpDevice>();
+ // mDevices contains all MtpDevices that have been seen by our client,
+ // so we can inform when the device has been detached.
+ // mDevices is also used for synchronization in this class.
+ private final HashMap<String, MtpDevice> mDevices = new HashMap<String, MtpDevice>();
+
+ private final PendingIntent mPermissionIntent;
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
UsbDevice usbDevice = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
String deviceName = usbDevice.getDeviceName();
- synchronized (mDeviceList) {
- MtpDevice mtpDevice = getDeviceLocked(deviceName);
+ synchronized (mDevices) {
+ MtpDevice mtpDevice = mDevices.get(deviceName);
- if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(intent.getAction())) {
+ if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
if (mtpDevice == null) {
- mtpDevice = openDevice(usbDevice);
+ mtpDevice = openDeviceLocked(usbDevice);
}
if (mtpDevice != null) {
- mDeviceList.add(mtpDevice);
for (Listener listener : mListeners) {
listener.deviceAdded(mtpDevice);
}
}
- } else if (mtpDevice != null) {
- mDeviceList.remove(mtpDevice);
- for (Listener listener : mListeners) {
- listener.deviceRemoved(mtpDevice);
+ } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
+ if (mtpDevice != null) {
+ mDevices.remove(deviceName);
+ for (Listener listener : mListeners) {
+ listener.deviceRemoved(mtpDevice);
+ }
+ }
+ } else if (ACTION_USB_PERMISSION.equals(action)) {
+ boolean permission = intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED,
+ false);
+ Log.d(TAG, "ACTION_USB_PERMISSION: " + permission);
+ if (permission) {
+ if (mtpDevice == null) {
+ mtpDevice = openDeviceLocked(usbDevice);
+ }
+ if (mtpDevice != null) {
+ for (Listener listener : mListeners) {
+ listener.deviceAdded(mtpDevice);
+ }
+ }
}
}
}
@@ -122,21 +153,12 @@
public MtpClient(Context context) {
mContext = context;
mUsbManager = (UsbManager)context.getSystemService(Context.USB_SERVICE);
-
+ mPermissionIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter();
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
+ filter.addAction(ACTION_USB_PERMISSION);
context.registerReceiver(mUsbReceiver, filter);
-
- for (UsbDevice usbDevice : mUsbManager.getDeviceList().values()) {
- MtpDevice mtpDevice = getDeviceLocked(usbDevice.getDeviceName());
- if (mtpDevice == null) {
- mtpDevice = openDevice(usbDevice);
- }
- if (mtpDevice != null) {
- mDeviceList.add(mtpDevice);
- }
- }
}
/**
@@ -146,11 +168,19 @@
* @param device the device to open
* @return an MtpDevice for the device.
*/
- private MtpDevice openDevice(UsbDevice usbDevice) {
+ private MtpDevice openDeviceLocked(UsbDevice usbDevice) {
if (isCamera(usbDevice)) {
- MtpDevice mtpDevice = new MtpDevice(usbDevice);
- if (mtpDevice.open(mUsbManager)) {
- return mtpDevice;
+ if (!mUsbManager.hasPermission(usbDevice)) {
+ mUsbManager.requestPermission(usbDevice, mPermissionIntent);
+ } else {
+ UsbDeviceConnection connection = mUsbManager.openDevice(usbDevice);
+ if (connection != null) {
+ MtpDevice mtpDevice = new MtpDevice(usbDevice);
+ if (mtpDevice.open(connection)) {
+ mDevices.put(usbDevice.getDeviceName(), mtpDevice);
+ return mtpDevice;
+ }
+ }
}
}
return null;
@@ -170,7 +200,7 @@
* @param listener the listener to register
*/
public void addListener(Listener listener) {
- synchronized (mDeviceList) {
+ synchronized (mDevices) {
if (!mListeners.contains(listener)) {
mListeners.add(listener);
}
@@ -183,7 +213,7 @@
* @param listener the listener to unregister
*/
public void removeListener(Listener listener) {
- synchronized (mDeviceList) {
+ synchronized (mDevices) {
mListeners.remove(listener);
}
}
@@ -196,8 +226,8 @@
* @return the MtpDevice, or null if it does not exist
*/
public MtpDevice getDevice(String deviceName) {
- synchronized (mDeviceList) {
- return getDeviceLocked(deviceName);
+ synchronized (mDevices) {
+ return mDevices.get(deviceName);
}
}
@@ -209,28 +239,27 @@
* @return the MtpDevice, or null if it does not exist
*/
public MtpDevice getDevice(int id) {
- synchronized (mDeviceList) {
- return getDeviceLocked(UsbDevice.getDeviceName(id));
+ synchronized (mDevices) {
+ return mDevices.get(UsbDevice.getDeviceName(id));
}
}
- private MtpDevice getDeviceLocked(String deviceName) {
- for (MtpDevice device : mDeviceList) {
- if (device.getDeviceName().equals(deviceName)) {
- return device;
- }
- }
- return null;
- }
-
/**
* Retrieves a list of all currently connected {@link android.mtp.MtpDevice}.
*
* @return the list of MtpDevices
*/
public List<MtpDevice> getDeviceList() {
- synchronized (mDeviceList) {
- return new ArrayList<MtpDevice>(mDeviceList);
+ synchronized (mDevices) {
+ // Query the USB manager since devices might have attached
+ // before we added our listener.
+ for (UsbDevice usbDevice : mUsbManager.getDeviceList().values()) {
+ if (mDevices.get(usbDevice.getDeviceName()) == null) {
+ openDeviceLocked(usbDevice);
+ }
+ }
+
+ return new ArrayList<MtpDevice>(mDevices.values());
}
}
diff --git a/media/tests/CameraBrowser/src/com/android/camerabrowser/ObjectBrowser.java b/media/tests/CameraBrowser/src/com/android/camerabrowser/ObjectBrowser.java
index 82251d9..68fed7b 100644
--- a/media/tests/CameraBrowser/src/com/android/camerabrowser/ObjectBrowser.java
+++ b/media/tests/CameraBrowser/src/com/android/camerabrowser/ObjectBrowser.java
@@ -22,7 +22,6 @@
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
-import android.mtp.MtpClient;
import android.mtp.MtpConstants;
import android.mtp.MtpDevice;
import android.mtp.MtpObjectInfo;
diff --git a/media/tests/CameraBrowser/src/com/android/camerabrowser/ObjectViewer.java b/media/tests/CameraBrowser/src/com/android/camerabrowser/ObjectViewer.java
index e9ea9f3..ef69c44 100644
--- a/media/tests/CameraBrowser/src/com/android/camerabrowser/ObjectViewer.java
+++ b/media/tests/CameraBrowser/src/com/android/camerabrowser/ObjectViewer.java
@@ -23,7 +23,6 @@
import android.graphics.BitmapFactory;
import android.media.MediaScannerConnection;
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
-import android.mtp.MtpClient;
import android.mtp.MtpConstants;
import android.mtp.MtpObjectInfo;
import android.net.Uri;
diff --git a/media/tests/CameraBrowser/src/com/android/camerabrowser/StorageBrowser.java b/media/tests/CameraBrowser/src/com/android/camerabrowser/StorageBrowser.java
index 7d5a5da..64320fe 100644
--- a/media/tests/CameraBrowser/src/com/android/camerabrowser/StorageBrowser.java
+++ b/media/tests/CameraBrowser/src/com/android/camerabrowser/StorageBrowser.java
@@ -19,7 +19,6 @@
import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
-import android.mtp.MtpClient;
import android.mtp.MtpDevice;
import android.mtp.MtpStorageInfo;
import android.os.Bundle;
diff --git a/media/tests/omxjpegdecoder/Android.mk b/media/tests/omxjpegdecoder/Android.mk
index 7802efd..81c6167 100644
--- a/media/tests/omxjpegdecoder/Android.mk
+++ b/media/tests/omxjpegdecoder/Android.mk
@@ -22,11 +22,6 @@
SkOmxPixelRef.cpp \
StreamSource.cpp
-
-# add external/skia/src/images/SkImageDecoder_libjpeg.cpp
-LOCAL_SRC_FILES += \
- ../../../../../external/skia/src/images/SkImageDecoder_libjpeg.cpp
-
LOCAL_SHARED_LIBRARIES := \
libcutils \
libskia \
diff --git a/native/android/native_window.cpp b/native/android/native_window.cpp
index 7f92eec..219cd19 100644
--- a/native/android/native_window.cpp
+++ b/native/android/native_window.cpp
@@ -20,6 +20,7 @@
#include <android/native_window_jni.h>
#include <surfaceflinger/Surface.h>
#include <android_runtime/android_view_Surface.h>
+#include <android_runtime/android_graphics_SurfaceTexture.h>
using namespace android;
@@ -31,6 +32,14 @@
return win.get();
}
+ANativeWindow* ANativeWindow_fromSurfaceTexture(JNIEnv* env, jobject surfaceTexture) {
+ sp<ANativeWindow> win = android_SurfaceTexture_getNativeWindow(env, surfaceTexture);
+ if (win != NULL) {
+ win->incStrong((void*)ANativeWindow_acquire);
+ }
+ return win.get();
+}
+
void ANativeWindow_acquire(ANativeWindow* window) {
window->incStrong((void*)ANativeWindow_acquire);
}
diff --git a/native/include/android/input.h b/native/include/android/input.h
index f19e8be..86be54a 100644
--- a/native/include/android/input.h
+++ b/native/include/android/input.h
@@ -359,6 +359,11 @@
AMOTION_EVENT_AXIS_HAT_Y = 16,
AMOTION_EVENT_AXIS_LTRIGGER = 17,
AMOTION_EVENT_AXIS_RTRIGGER = 18,
+ AMOTION_EVENT_AXIS_THROTTLE = 19,
+ AMOTION_EVENT_AXIS_RUDDER = 20,
+ AMOTION_EVENT_AXIS_WHEEL = 21,
+ AMOTION_EVENT_AXIS_GAS = 22,
+ AMOTION_EVENT_AXIS_BRAKE = 23,
AMOTION_EVENT_AXIS_GENERIC_1 = 32,
AMOTION_EVENT_AXIS_GENERIC_2 = 33,
AMOTION_EVENT_AXIS_GENERIC_3 = 34,
diff --git a/native/include/android/native_window_jni.h b/native/include/android/native_window_jni.h
index b9e72ef..408c263 100644
--- a/native/include/android/native_window_jni.h
+++ b/native/include/android/native_window_jni.h
@@ -33,6 +33,14 @@
*/
ANativeWindow* ANativeWindow_fromSurface(JNIEnv* env, jobject surface);
+/**
+ * Return the ANativeWindow associated with a Java SurfaceTexture object,
+ * for interacting with it through native code. This acquires a reference
+ * on the ANativeWindow that is returned; be sure to use ANativeWindow_release()
+ * when done with it so that it doesn't leak.
+ */
+ANativeWindow* ANativeWindow_fromSurfaceTexture(JNIEnv* env, jobject surfaceTexture);
+
#ifdef __cplusplus
};
#endif
diff --git a/opengl/java/com/google/android/gles_jni/EGLContextImpl.java b/opengl/java/com/google/android/gles_jni/EGLContextImpl.java
index 9cf5de7..cd36099 100644
--- a/opengl/java/com/google/android/gles_jni/EGLContextImpl.java
+++ b/opengl/java/com/google/android/gles_jni/EGLContextImpl.java
@@ -32,4 +32,19 @@
public GL getGL() {
return mGLContext;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ EGLContextImpl that = (EGLContextImpl) o;
+
+ return mEGLContext == that.mEGLContext;
+ }
+
+ @Override
+ public int hashCode() {
+ return mEGLContext;
+ }
}
diff --git a/opengl/java/com/google/android/gles_jni/EGLDisplayImpl.java b/opengl/java/com/google/android/gles_jni/EGLDisplayImpl.java
index cb94888..e6c9817 100644
--- a/opengl/java/com/google/android/gles_jni/EGLDisplayImpl.java
+++ b/opengl/java/com/google/android/gles_jni/EGLDisplayImpl.java
@@ -24,4 +24,20 @@
public EGLDisplayImpl(int dpy) {
mEGLDisplay = dpy;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ EGLDisplayImpl that = (EGLDisplayImpl) o;
+
+ return mEGLDisplay == that.mEGLDisplay;
+
+ }
+
+ @Override
+ public int hashCode() {
+ return mEGLDisplay;
+ }
}
diff --git a/opengl/java/com/google/android/gles_jni/EGLSurfaceImpl.java b/opengl/java/com/google/android/gles_jni/EGLSurfaceImpl.java
index f6b90ab..e7f15dc 100644
--- a/opengl/java/com/google/android/gles_jni/EGLSurfaceImpl.java
+++ b/opengl/java/com/google/android/gles_jni/EGLSurfaceImpl.java
@@ -29,4 +29,20 @@
mEGLSurface = surface;
mNativePixelRef = 0;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ EGLSurfaceImpl that = (EGLSurfaceImpl) o;
+
+ return mEGLSurface == that.mEGLSurface;
+
+ }
+
+ @Override
+ public int hashCode() {
+ return mEGLSurface;
+ }
}
diff --git a/opengl/libagl2/Android.mk b/opengl/libagl2/Android.mk
new file mode 100644
index 0000000..564932f
--- /dev/null
+++ b/opengl/libagl2/Android.mk
@@ -0,0 +1,58 @@
+LOCAL_PATH:= $(call my-dir)
+
+#
+# Build the software OpenGL ES library
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ src/api.cpp \
+ src/egl.cpp \
+ src/get.cpp \
+ src/shader.cpp \
+ src/state.cpp \
+ src/texture.cpp \
+ src/vertex.cpp
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ external/mesa3d/include \
+ external/mesa3d/src \
+ external/stlport/stlport \
+ bionic
+
+#LOCAL_CFLAGS += -DLOG_TAG=\"libagl2\"
+#LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+#LOCAL_CFLAGS += -fvisibility=hidden
+#LOCAL_CFLAGS += -O0 -g -DDEBUG -UNDEBUG
+LOCAL_CFLAGS += -O3
+LOCAL_STATIC_LIBRARIES := libMesa
+LOCAL_SHARED_LIBRARIES := libstlport libcutils libhardware libutils libbcc libdl
+LOCAL_LDLIBS := -lpthread
+
+ifeq ($(TARGET_ARCH),arm)
+ LOCAL_CFLAGS += -fstrict-aliasing
+endif
+
+ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true)
+ LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER
+endif
+
+ifneq ($(TARGET_SIMULATOR),true)
+ # we need to access the private Bionic header <bionic_tls.h>
+ # on ARM platforms, we need to mirror the ARCH_ARM_HAVE_TLS_REGISTER
+ # behavior from the bionic Android.mk file
+ ifeq ($(TARGET_ARCH)-$(ARCH_ARM_HAVE_TLS_REGISTER),arm-true)
+ LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER
+ endif
+ LOCAL_C_INCLUDES += bionic/libc/private
+endif
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl
+#replace libagl for now
+LOCAL_MODULE:= libGLES_android
+LOCAL_MODULE_TAGS := eng
+
+## Disable this makefile for now
+## include $(BUILD_SHARED_LIBRARY)
diff --git a/opengl/libagl2/README b/opengl/libagl2/README
new file mode 100644
index 0000000..34746d3
--- /dev/null
+++ b/opengl/libagl2/README
@@ -0,0 +1,26 @@
+libAgl2 provides software GL ES 2.0 implementation using Pixelflinger2 in external/mesa3d
+
+To build, enable Android.mk, which builds libGLES_android.so, then replace the one built from libAgl in system/lib/egl.
+ES 1.0 functions are not implemented and will cause exit, so do not setprop debug.egl.hw 0 until launcher is loaded.
+
+All functions have little to none error checking.
+Not thread safe, Pixelflinger2 uses some static data.
+
+Most shader functions are implemented, however, most Get* functions for shaders/programs/uniforms/attribs are not.
+No name system for shaders/programs, just using the pointers as names.
+
+Basic glTexImage2D, glTexSubImage2D, glCopyImage2D and glCopySubImage2D are implemented, with a range of 8/16/24/32bpp formats.
+Cube map support is minimal. No mipmapping.
+TexParameter is mostly implemented, supports texcoord wrap modes, and only linear for both min and mag, or nearest for both min and mag filtering.
+Texture names are implemented, but bad.
+
+Frame buffer and render buffers are not implemented.
+
+Depth and stencil are implemented, but not tested.
+Blending seems to work.
+Colorbuffer supports RGBA_8888 and RGB_565.
+
+Vertex buffer objects are implemented.
+Some GL_TRIANGLES and GL_TRIANGLE_STRIPS modes for glDrawArrays and glDrawElements are implemented, but vertex order is probably wrong so culling is disabled.
+
+Basic apps should work, and some libhwui should work, except for frame buffer operations, which will cause exit.
diff --git a/opengl/libagl2/libagl2.project b/opengl/libagl2/libagl2.project
new file mode 100644
index 0000000..f234421
--- /dev/null
+++ b/opengl/libagl2/libagl2.project
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="utf-8"?>
+<CodeLite_Project Name="libagl2" InternalType="Console">
+ <Plugins>
+ <Plugin Name="qmake">
+ <![CDATA[00010001N0005Debug000000000000]]>
+ </Plugin>
+ </Plugins>
+ <Description/>
+ <Dependencies/>
+ <Dependencies Name="Release"/>
+ <VirtualDirectory Name="src">
+ <File Name="src/egl.cpp"/>
+ <File Name="src/api.cpp"/>
+ <File Name="src/gles2context.h"/>
+ <File Name="src/shader.cpp"/>
+ <File Name="src/vertex.cpp"/>
+ <File Name="src/state.cpp"/>
+ <File Name="src/texture.cpp"/>
+ <File Name="src/get.cpp"/>
+ </VirtualDirectory>
+ <VirtualDirectory Name="include"/>
+ <Settings Type="Executable">
+ <Configuration Name="Debug" CompilerType="gnu gcc" DebuggerType="GNU gdb debugger" Type="Executable" BuildCmpWithGlobalSettings="append" BuildLnkWithGlobalSettings="append" BuildResWithGlobalSettings="append">
+ <Compiler Options="-g;-m32" Required="yes" PreCompiledHeader="">
+ <IncludePath Value="/usr/include/c++/4.4"/>
+ <IncludePath Value="/usr/include/c++/4.4/ext"/>
+ <IncludePath Value="."/>
+ <IncludePath Value="include"/>
+ <IncludePath Value="../../../../external/mesa3d/include"/>
+ <IncludePath Value="../../../../external/mesa3d/src"/>
+ <IncludePath Value="../../../../hardware/libhardware/include"/>
+ <IncludePath Value="../../../../system/core/include"/>
+ <IncludePath Value="../include"/>
+ <IncludePath Value="../../include"/>
+ <IncludePath Value="../../../../development/ndk/platforms/android-9/include"/>
+ <IncludePath Value="../../../../bionic/libc/include/"/>
+ <IncludePath Value="/../../../../development/ndk/platforms/android-5/arch-x86/include"/>
+ <IncludePath Value="../../../../bionic/libc/arch-x86/include"/>
+ <IncludePath Value="../../../../bionic/libc/kernel/arch-x86"/>
+ <IncludePath Value="/../../../../external/kernel-headers/original"/>
+ <IncludePath Value="../../../../prebuilt/ndk/android-ndk-r4/platforms/android-8/arch-x86/usr/include"/>
+ </Compiler>
+ <Linker Options="-m32;-lstdc++" Required="yes"/>
+ <ResourceCompiler Options="" Required="no"/>
+ <General OutputFile="$(IntermediateDirectory)/$(ProjectName)" IntermediateDirectory="./Debug" Command="./$(ProjectName)" CommandArguments="" WorkingDirectory="$(IntermediateDirectory)" PauseExecWhenProcTerminates="yes"/>
+ <Debugger IsRemote="no" RemoteHostName="" RemoteHostPort="" DebuggerPath="">
+ <PostConnectCommands/>
+ <StartupCommands/>
+ </Debugger>
+ <PreBuild/>
+ <PostBuild/>
+ <CustomBuild Enabled="no">
+ <RebuildCommand/>
+ <CleanCommand/>
+ <BuildCommand/>
+ <PreprocessFileCommand/>
+ <SingleFileCommand/>
+ <MakefileGenerationCommand/>
+ <ThirdPartyToolName>None</ThirdPartyToolName>
+ <WorkingDirectory/>
+ </CustomBuild>
+ <AdditionalRules>
+ <CustomPostBuild/>
+ <CustomPreBuild/>
+ </AdditionalRules>
+ </Configuration>
+ <Configuration Name="Release" CompilerType="gnu gcc" DebuggerType="GNU gdb debugger" Type="" BuildCmpWithGlobalSettings="append" BuildLnkWithGlobalSettings="append" BuildResWithGlobalSettings="append">
+ <Compiler Options="" Required="yes" PreCompiledHeader="">
+ <IncludePath Value="."/>
+ </Compiler>
+ <Linker Options="-O2" Required="yes"/>
+ <ResourceCompiler Options="" Required="no"/>
+ <General OutputFile="$(IntermediateDirectory)/$(ProjectName)" IntermediateDirectory="./Release" Command="./$(ProjectName)" CommandArguments="" WorkingDirectory="$(IntermediateDirectory)" PauseExecWhenProcTerminates="yes"/>
+ <Debugger IsRemote="no" RemoteHostName="" RemoteHostPort="" DebuggerPath="">
+ <PostConnectCommands/>
+ <StartupCommands/>
+ </Debugger>
+ <PreBuild/>
+ <PostBuild/>
+ <CustomBuild Enabled="no">
+ <RebuildCommand/>
+ <CleanCommand/>
+ <BuildCommand/>
+ <PreprocessFileCommand/>
+ <SingleFileCommand/>
+ <MakefileGenerationCommand/>
+ <ThirdPartyToolName>None</ThirdPartyToolName>
+ <WorkingDirectory/>
+ </CustomBuild>
+ <AdditionalRules>
+ <CustomPostBuild/>
+ <CustomPreBuild/>
+ </AdditionalRules>
+ </Configuration>
+ <GlobalSettings>
+ <Compiler Options="">
+ <IncludePath Value="."/>
+ </Compiler>
+ <Linker Options="">
+ <LibraryPath Value="."/>
+ </Linker>
+ <ResourceCompiler Options=""/>
+ </GlobalSettings>
+ </Settings>
+ <Dependencies Name="Debug">
+ <Project Name="libMesa"/>
+ </Dependencies>
+</CodeLite_Project>
diff --git a/opengl/libagl2/src/api.cpp b/opengl/libagl2/src/api.cpp
new file mode 100644
index 0000000..bb8d62b
--- /dev/null
+++ b/opengl/libagl2/src/api.cpp
@@ -0,0 +1,266 @@
+#include "gles2context.h"
+
+#define API_ENTRY
+#define CALL_GL_API(NAME,...) LOGD("?"#NAME); assert(0);
+#define CALL_GL_API_RETURN(NAME,...) LOGD("?"#NAME); assert(0); return 0;
+
+
+void API_ENTRY(glBindFramebuffer)(GLenum target, GLuint framebuffer)
+{
+ CALL_GL_API(glBindFramebuffer, target, framebuffer);
+}
+void API_ENTRY(glBindRenderbuffer)(GLenum target, GLuint renderbuffer)
+{
+ CALL_GL_API(glBindRenderbuffer, target, renderbuffer);
+}
+GLenum API_ENTRY(glCheckFramebufferStatus)(GLenum target)
+{
+ CALL_GL_API_RETURN(glCheckFramebufferStatus, target);
+}
+void API_ENTRY(glColorMask)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+ CALL_GL_API(glColorMask, red, green, blue, alpha);
+}
+void API_ENTRY(glDeleteFramebuffers)(GLsizei n, const GLuint* framebuffers)
+{
+ CALL_GL_API(glDeleteFramebuffers, n, framebuffers);
+}
+void API_ENTRY(glDeleteRenderbuffers)(GLsizei n, const GLuint* renderbuffers)
+{
+ CALL_GL_API(glDeleteRenderbuffers, n, renderbuffers);
+}
+void API_ENTRY(glDepthFunc)(GLenum func)
+{
+ CALL_GL_API(glDepthFunc, func);
+}
+void API_ENTRY(glDepthMask)(GLboolean flag)
+{
+ CALL_GL_API(glDepthMask, flag);
+}
+void API_ENTRY(glDepthRangef)(GLclampf zNear, GLclampf zFar)
+{
+ CALL_GL_API(glDepthRangef, zNear, zFar);
+}
+void API_ENTRY(glFramebufferRenderbuffer)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+{
+ CALL_GL_API(glFramebufferRenderbuffer, target, attachment, renderbuffertarget, renderbuffer);
+}
+void API_ENTRY(glFramebufferTexture2D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+ CALL_GL_API(glFramebufferTexture2D, target, attachment, textarget, texture, level);
+}
+void glGenerateMipmap(GLenum target)
+{
+ //CALL_GL_API(glGenerateMipmap, target);
+ LOGD("agl2: glGenerateMipmap not implemented");
+}
+void API_ENTRY(glGenFramebuffers)(GLsizei n, GLuint* framebuffers)
+{
+ CALL_GL_API(glGenFramebuffers, n, framebuffers);
+}
+void API_ENTRY(glGenRenderbuffers)(GLsizei n, GLuint* renderbuffers)
+{
+ CALL_GL_API(glGenRenderbuffers, n, renderbuffers);
+}
+void API_ENTRY(glGetActiveAttrib)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
+{
+ CALL_GL_API(glGetActiveAttrib, program, index, bufsize, length, size, type, name);
+}
+void API_ENTRY(glGetActiveUniform)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
+{
+ CALL_GL_API(glGetActiveUniform, program, index, bufsize, length, size, type, name);
+}
+void API_ENTRY(glGetAttachedShaders)(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
+{
+ CALL_GL_API(glGetAttachedShaders, program, maxcount, count, shaders);
+}
+void API_ENTRY(glGetBooleanv)(GLenum pname, GLboolean* params)
+{
+ CALL_GL_API(glGetBooleanv, pname, params);
+}
+void API_ENTRY(glGetBufferParameteriv)(GLenum target, GLenum pname, GLint* params)
+{
+ CALL_GL_API(glGetBufferParameteriv, target, pname, params);
+}
+GLenum glGetError(void)
+{
+ puts("agl2: glGetError");
+ return GL_NO_ERROR;
+ //CALL_GL_API_RETURN(glGetError);
+}
+void API_ENTRY(glGetFloatv)(GLenum pname, GLfloat* params)
+{
+ CALL_GL_API(glGetFloatv, pname, params);
+}
+void API_ENTRY(glGetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, GLenum pname, GLint* params)
+{
+ CALL_GL_API(glGetFramebufferAttachmentParameteriv, target, attachment, pname, params);
+}
+void API_ENTRY(glGetRenderbufferParameteriv)(GLenum target, GLenum pname, GLint* params)
+{
+ CALL_GL_API(glGetRenderbufferParameteriv, target, pname, params);
+}
+void API_ENTRY(glGetShaderPrecisionFormat)(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
+{
+ CALL_GL_API(glGetShaderPrecisionFormat, shadertype, precisiontype, range, precision);
+}
+void API_ENTRY(glGetShaderSource)(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
+{
+ CALL_GL_API(glGetShaderSource, shader, bufsize, length, source);
+}
+void API_ENTRY(glGetUniformfv)(GLuint program, GLint location, GLfloat* params)
+{
+ CALL_GL_API(glGetUniformfv, program, location, params);
+}
+void API_ENTRY(glGetUniformiv)(GLuint program, GLint location, GLint* params)
+{
+ CALL_GL_API(glGetUniformiv, program, location, params);
+}
+void API_ENTRY(glGetVertexAttribfv)(GLuint index, GLenum pname, GLfloat* params)
+{
+ CALL_GL_API(glGetVertexAttribfv, index, pname, params);
+}
+void API_ENTRY(glGetVertexAttribiv)(GLuint index, GLenum pname, GLint* params)
+{
+ CALL_GL_API(glGetVertexAttribiv, index, pname, params);
+}
+void API_ENTRY(glGetVertexAttribPointerv)(GLuint index, GLenum pname, GLvoid** pointer)
+{
+ CALL_GL_API(glGetVertexAttribPointerv, index, pname, pointer);
+}
+GLboolean API_ENTRY(glIsBuffer)(GLuint buffer)
+{
+ CALL_GL_API_RETURN(glIsBuffer, buffer);
+}
+GLboolean API_ENTRY(glIsEnabled)(GLenum cap)
+{
+ CALL_GL_API_RETURN(glIsEnabled, cap);
+}
+GLboolean API_ENTRY(glIsFramebuffer)(GLuint framebuffer)
+{
+ CALL_GL_API_RETURN(glIsFramebuffer, framebuffer);
+}
+GLboolean API_ENTRY(glIsProgram)(GLuint program)
+{
+ CALL_GL_API_RETURN(glIsProgram, program);
+}
+GLboolean API_ENTRY(glIsRenderbuffer)(GLuint renderbuffer)
+{
+ CALL_GL_API_RETURN(glIsRenderbuffer, renderbuffer);
+}
+GLboolean API_ENTRY(glIsShader)(GLuint shader)
+{
+ CALL_GL_API_RETURN(glIsShader, shader);
+}
+void API_ENTRY(glLineWidth)(GLfloat width)
+{
+ CALL_GL_API(glLineWidth, width);
+}
+void API_ENTRY(glPolygonOffset)(GLfloat factor, GLfloat units)
+{
+ CALL_GL_API(glPolygonOffset, factor, units);
+}
+void API_ENTRY(glReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
+{
+ CALL_GL_API(glReadPixels, x, y, width, height, format, type, pixels);
+}
+void API_ENTRY(glReleaseShaderCompiler)(void)
+{
+ CALL_GL_API(glReleaseShaderCompiler);
+}
+void API_ENTRY(glRenderbufferStorage)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ CALL_GL_API(glRenderbufferStorage, target, internalformat, width, height);
+}
+void API_ENTRY(glSampleCoverage)(GLclampf value, GLboolean invert)
+{
+ CALL_GL_API(glSampleCoverage, value, invert);
+}
+void API_ENTRY(glShaderBinary)(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
+{
+ CALL_GL_API(glShaderBinary, n, shaders, binaryformat, binary, length);
+}
+void API_ENTRY(glStencilFunc)(GLenum func, GLint ref, GLuint mask)
+{
+ CALL_GL_API(glStencilFunc, func, ref, mask);
+}
+void API_ENTRY(glStencilFuncSeparate)(GLenum face, GLenum func, GLint ref, GLuint mask)
+{
+ CALL_GL_API(glStencilFuncSeparate, face, func, ref, mask);
+}
+void API_ENTRY(glStencilMask)(GLuint mask)
+{
+ CALL_GL_API(glStencilMask, mask);
+}
+void API_ENTRY(glStencilMaskSeparate)(GLenum face, GLuint mask)
+{
+ CALL_GL_API(glStencilMaskSeparate, face, mask);
+}
+void API_ENTRY(glStencilOp)(GLenum fail, GLenum zfail, GLenum zpass)
+{
+ CALL_GL_API(glStencilOp, fail, zfail, zpass);
+}
+void API_ENTRY(glStencilOpSeparate)(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+{
+ CALL_GL_API(glStencilOpSeparate, face, fail, zfail, zpass);
+}
+void API_ENTRY(glUniform1fv)(GLint location, GLsizei count, const GLfloat* v)
+{
+ CALL_GL_API(glUniform1fv, location, count, v);
+}
+void API_ENTRY(glUniform1iv)(GLint location, GLsizei count, const GLint* v)
+{
+ CALL_GL_API(glUniform1iv, location, count, v);
+}
+void API_ENTRY(glUniform2fv)(GLint location, GLsizei count, const GLfloat* v)
+{
+ CALL_GL_API(glUniform2fv, location, count, v);
+}
+void API_ENTRY(glUniform2i)(GLint location, GLint x, GLint y)
+{
+ CALL_GL_API(glUniform2i, location, x, y);
+}
+void API_ENTRY(glUniform2iv)(GLint location, GLsizei count, const GLint* v)
+{
+ CALL_GL_API(glUniform2iv, location, count, v);
+}
+void API_ENTRY(glUniform3f)(GLint location, GLfloat x, GLfloat y, GLfloat z)
+{
+ CALL_GL_API(glUniform3f, location, x, y, z);
+}
+void API_ENTRY(glUniform3fv)(GLint location, GLsizei count, const GLfloat* v)
+{
+ CALL_GL_API(glUniform3fv, location, count, v);
+}
+void API_ENTRY(glUniform3i)(GLint location, GLint x, GLint y, GLint z)
+{
+ CALL_GL_API(glUniform3i, location, x, y, z);
+}
+void API_ENTRY(glUniform3iv)(GLint location, GLsizei count, const GLint* v)
+{
+ CALL_GL_API(glUniform3iv, location, count, v);
+}
+void API_ENTRY(glUniform4fv)(GLint location, GLsizei count, const GLfloat* v)
+{
+ CALL_GL_API(glUniform4fv, location, count, v);
+}
+void API_ENTRY(glUniform4i)(GLint location, GLint x, GLint y, GLint z, GLint w)
+{
+ CALL_GL_API(glUniform4i, location, x, y, z, w);
+}
+void API_ENTRY(glUniform4iv)(GLint location, GLsizei count, const GLint* v)
+{
+ CALL_GL_API(glUniform4iv, location, count, v);
+}
+void API_ENTRY(glUniformMatrix2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ CALL_GL_API(glUniformMatrix2fv, location, count, transpose, value);
+}
+void API_ENTRY(glUniformMatrix3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ CALL_GL_API(glUniformMatrix3fv, location, count, transpose, value);
+}
+void API_ENTRY(glValidateProgram)(GLuint program)
+{
+ CALL_GL_API(glValidateProgram, program);
+}
diff --git a/opengl/libagl2/src/egl.cpp b/opengl/libagl2/src/egl.cpp
new file mode 100644
index 0000000..6184644
--- /dev/null
+++ b/opengl/libagl2/src/egl.cpp
@@ -0,0 +1,2232 @@
+/*
+**
+** Copyright 2007 The Android Open Source Project
+**
+** Licensed under the Apache License Version 2.0(the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** 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.
+*/
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <cutils/atomic.h>
+
+
+#include <private/ui/android_natives_priv.h>
+
+#include <hardware/copybit.h>
+
+#include "gles2context.h"
+
+// ----------------------------------------------------------------------------
+namespace android
+{
+// ----------------------------------------------------------------------------
+
+const unsigned int NUM_DISPLAYS = 1;
+
+static pthread_mutex_t gInitMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t gErrorKeyMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_key_t gEGLErrorKey = -1;
+#ifndef HAVE_ANDROID_OS
+namespace gl {
+pthread_key_t gGLKey = -1;
+}; // namespace gl
+#endif
+
+template<typename T>
+static T setError(GLint error, T returnValue)
+{
+ if (ggl_unlikely(gEGLErrorKey == -1)) {
+ pthread_mutex_lock(&gErrorKeyMutex);
+ if (gEGLErrorKey == -1)
+ pthread_key_create(&gEGLErrorKey, NULL);
+ pthread_mutex_unlock(&gErrorKeyMutex);
+ }
+ pthread_setspecific(gEGLErrorKey, (void*)error);
+ return returnValue;
+}
+
+static GLint getError()
+{
+ if (ggl_unlikely(gEGLErrorKey == -1))
+ return EGL_SUCCESS;
+ GLint error = (GLint)pthread_getspecific(gEGLErrorKey);
+ if (error == 0) {
+ // The TLS key has been created by another thread, but the value for
+ // this thread has not been initialized.
+ return EGL_SUCCESS;
+ }
+ pthread_setspecific(gEGLErrorKey, (void*)EGL_SUCCESS);
+ return error;
+}
+
+// ----------------------------------------------------------------------------
+
+struct egl_display_t {
+ egl_display_t() : type(0), initialized(0) { }
+
+ static egl_display_t& get_display(EGLDisplay dpy);
+
+ static EGLBoolean is_valid(EGLDisplay dpy) {
+ return ((uintptr_t(dpy)-1U) >= NUM_DISPLAYS) ? EGL_FALSE : EGL_TRUE;
+ }
+
+ NativeDisplayType type;
+ volatile int32_t initialized;
+};
+
+static egl_display_t gDisplays[NUM_DISPLAYS];
+
+egl_display_t& egl_display_t::get_display(EGLDisplay dpy)
+{
+ return gDisplays[uintptr_t(dpy)-1U];
+}
+
+// ----------------------------------------------------------------------------
+
+struct egl_surface_t {
+ enum {
+ PAGE_FLIP = 0x00000001,
+ MAGIC = 0x31415265
+ };
+
+ uint32_t magic;
+ EGLDisplay dpy;
+ EGLConfig config;
+ EGLContext ctx;
+
+ egl_surface_t(EGLDisplay dpy, EGLConfig config, int32_t depthFormat);
+ virtual ~egl_surface_t();
+ bool isValid() const;
+ virtual bool initCheck() const = 0;
+
+ virtual EGLBoolean bindDrawSurface(GLES2Context* gl) = 0;
+ virtual EGLBoolean bindReadSurface(GLES2Context* gl) = 0;
+ virtual EGLBoolean connect() {
+ return EGL_TRUE;
+ }
+ virtual void disconnect() {}
+ virtual EGLint getWidth() const = 0;
+ virtual EGLint getHeight() const = 0;
+
+ virtual EGLint getHorizontalResolution() const;
+ virtual EGLint getVerticalResolution() const;
+ virtual EGLint getRefreshRate() const;
+ virtual EGLint getSwapBehavior() const;
+ virtual EGLBoolean swapBuffers();
+ virtual EGLBoolean setSwapRectangle(EGLint l, EGLint t, EGLint w, EGLint h);
+protected:
+ GGLSurface depth;
+};
+
+egl_surface_t::egl_surface_t(EGLDisplay dpy,
+ EGLConfig config,
+ int32_t depthFormat)
+ : magic(MAGIC), dpy(dpy), config(config), ctx(0)
+{
+ depth.version = sizeof(GGLSurface);
+ depth.data = 0;
+ depth.format = (GGLPixelFormat)depthFormat;
+}
+egl_surface_t::~egl_surface_t()
+{
+ magic = 0;
+ free(depth.data);
+}
+bool egl_surface_t::isValid() const
+{
+ LOGE_IF(magic != MAGIC, "invalid EGLSurface (%p)", this);
+ return magic == MAGIC;
+}
+
+EGLBoolean egl_surface_t::swapBuffers()
+{
+ return EGL_FALSE;
+}
+EGLint egl_surface_t::getHorizontalResolution() const
+{
+ return (0 * EGL_DISPLAY_SCALING) * (1.0f / 25.4f);
+}
+EGLint egl_surface_t::getVerticalResolution() const
+{
+ return (0 * EGL_DISPLAY_SCALING) * (1.0f / 25.4f);
+}
+EGLint egl_surface_t::getRefreshRate() const
+{
+ return (60 * EGL_DISPLAY_SCALING);
+}
+EGLint egl_surface_t::getSwapBehavior() const
+{
+ return EGL_BUFFER_PRESERVED;
+}
+EGLBoolean egl_surface_t::setSwapRectangle(
+ EGLint l, EGLint t, EGLint w, EGLint h)
+{
+ return EGL_FALSE;
+}
+
+// ----------------------------------------------------------------------------
+
+struct egl_window_surface_v2_t : public egl_surface_t {
+ egl_window_surface_v2_t(
+ EGLDisplay dpy, EGLConfig config,
+ int32_t depthFormat,
+ ANativeWindow* window);
+
+ ~egl_window_surface_v2_t();
+
+ virtual bool initCheck() const {
+ return true; // TODO: report failure if ctor fails
+ }
+ virtual EGLBoolean swapBuffers();
+ virtual EGLBoolean bindDrawSurface(GLES2Context* gl);
+ virtual EGLBoolean bindReadSurface(GLES2Context* gl);
+ virtual EGLBoolean connect();
+ virtual void disconnect();
+ virtual EGLint getWidth() const {
+ return width;
+ }
+ virtual EGLint getHeight() const {
+ return height;
+ }
+ virtual EGLint getHorizontalResolution() const;
+ virtual EGLint getVerticalResolution() const;
+ virtual EGLint getRefreshRate() const;
+ virtual EGLint getSwapBehavior() const;
+ virtual EGLBoolean setSwapRectangle(EGLint l, EGLint t, EGLint w, EGLint h);
+
+private:
+ status_t lock(android_native_buffer_t* buf, int usage, void** vaddr);
+ status_t unlock(android_native_buffer_t* buf);
+ ANativeWindow* nativeWindow;
+ android_native_buffer_t* buffer;
+ android_native_buffer_t* previousBuffer;
+ gralloc_module_t const* module;
+ copybit_device_t* blitengine;
+ int width;
+ int height;
+ void* bits;
+ GGLFormat const* pixelFormatTable;
+
+ struct Rect {
+ inline Rect() { };
+ inline Rect(int32_t w, int32_t h)
+ : left(0), top(0), right(w), bottom(h) { }
+ inline Rect(int32_t l, int32_t t, int32_t r, int32_t b)
+ : left(l), top(t), right(r), bottom(b) { }
+ Rect& andSelf(const Rect& r) {
+ left = max(left, r.left);
+ top = max(top, r.top);
+ right = min(right, r.right);
+ bottom = min(bottom, r.bottom);
+ return *this;
+ }
+ bool isEmpty() const {
+ return (left>=right || top>=bottom);
+ }
+ void dump(char const* what) {
+ LOGD("%s { %5d, %5d, w=%5d, h=%5d }",
+ what, left, top, right-left, bottom-top);
+ }
+
+ int32_t left;
+ int32_t top;
+ int32_t right;
+ int32_t bottom;
+ };
+
+ struct Region {
+ inline Region() : count(0) { }
+ typedef Rect const* const_iterator;
+ const_iterator begin() const {
+ return storage;
+ }
+ const_iterator end() const {
+ return storage+count;
+ }
+ static Region subtract(const Rect& lhs, const Rect& rhs) {
+ Region reg;
+ Rect* storage = reg.storage;
+ if (!lhs.isEmpty()) {
+ if (lhs.top < rhs.top) { // top rect
+ storage->left = lhs.left;
+ storage->top = lhs.top;
+ storage->right = lhs.right;
+ storage->bottom = rhs.top;
+ storage++;
+ }
+ const int32_t top = max(lhs.top, rhs.top);
+ const int32_t bot = min(lhs.bottom, rhs.bottom);
+ if (top < bot) {
+ if (lhs.left < rhs.left) { // left-side rect
+ storage->left = lhs.left;
+ storage->top = top;
+ storage->right = rhs.left;
+ storage->bottom = bot;
+ storage++;
+ }
+ if (lhs.right > rhs.right) { // right-side rect
+ storage->left = rhs.right;
+ storage->top = top;
+ storage->right = lhs.right;
+ storage->bottom = bot;
+ storage++;
+ }
+ }
+ if (lhs.bottom > rhs.bottom) { // bottom rect
+ storage->left = lhs.left;
+ storage->top = rhs.bottom;
+ storage->right = lhs.right;
+ storage->bottom = lhs.bottom;
+ storage++;
+ }
+ reg.count = storage - reg.storage;
+ }
+ return reg;
+ }
+ bool isEmpty() const {
+ return count<=0;
+ }
+private:
+ Rect storage[4];
+ ssize_t count;
+ };
+
+ struct region_iterator : public copybit_region_t {
+ region_iterator(const Region& region)
+ : b(region.begin()), e(region.end()) {
+ this->next = iterate;
+ }
+private:
+ static int iterate(copybit_region_t const * self, copybit_rect_t* rect) {
+ region_iterator const* me = static_cast<region_iterator const*>(self);
+ if (me->b != me->e) {
+ *reinterpret_cast<Rect*>(rect) = *me->b++;
+ return 1;
+ }
+ return 0;
+ }
+ mutable Region::const_iterator b;
+ Region::const_iterator const e;
+ };
+
+ void copyBlt(
+ android_native_buffer_t* dst, void* dst_vaddr,
+ android_native_buffer_t* src, void const* src_vaddr,
+ const Region& clip);
+
+ Rect dirtyRegion;
+ Rect oldDirtyRegion;
+};
+
+egl_window_surface_v2_t::egl_window_surface_v2_t(EGLDisplay dpy,
+ EGLConfig config,
+ int32_t depthFormat,
+ ANativeWindow* window)
+ : egl_surface_t(dpy, config, depthFormat),
+ nativeWindow(window), buffer(0), previousBuffer(0), module(0),
+ blitengine(0), bits(NULL)
+{
+ hw_module_t const* pModule;
+ hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule);
+ module = reinterpret_cast<gralloc_module_t const*>(pModule);
+
+ if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &pModule) == 0) {
+ copybit_open(pModule, &blitengine);
+ }
+
+ pixelFormatTable = gglGetPixelFormatTable();
+
+ // keep a reference on the window
+ nativeWindow->common.incRef(&nativeWindow->common);
+ nativeWindow->query(nativeWindow, NATIVE_WINDOW_WIDTH, &width);
+ nativeWindow->query(nativeWindow, NATIVE_WINDOW_HEIGHT, &height);
+ int format = 0;
+ nativeWindow->query(nativeWindow, NATIVE_WINDOW_FORMAT, &format);
+ LOGD("agl2: egl_window_surface_v2_t format=0x%.4X", format);
+// assert(0);
+}
+
+egl_window_surface_v2_t::~egl_window_surface_v2_t()
+{
+ if (buffer) {
+ buffer->common.decRef(&buffer->common);
+ }
+ if (previousBuffer) {
+ previousBuffer->common.decRef(&previousBuffer->common);
+ }
+ nativeWindow->common.decRef(&nativeWindow->common);
+ if (blitengine) {
+ copybit_close(blitengine);
+ }
+}
+
+EGLBoolean egl_window_surface_v2_t::connect()
+{
+ // we're intending to do software rendering
+ native_window_set_usage(nativeWindow,
+ GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
+
+ // dequeue a buffer
+ if (nativeWindow->dequeueBuffer(nativeWindow, &buffer) != NO_ERROR) {
+ return setError(EGL_BAD_ALLOC, EGL_FALSE);
+ }
+
+ // allocate a corresponding depth-buffer
+ width = buffer->width;
+ height = buffer->height;
+ if (depth.format) {
+ depth.width = width;
+ depth.height = height;
+ depth.stride = depth.width; // use the width here
+ assert(GGL_PIXEL_FORMAT_Z_32 == depth.format);
+ depth.data = (GGLubyte*)malloc(depth.stride*depth.height*4);
+ if (depth.data == 0) {
+ return setError(EGL_BAD_ALLOC, EGL_FALSE);
+ }
+ }
+
+ // keep a reference on the buffer
+ buffer->common.incRef(&buffer->common);
+
+ // Lock the buffer
+ nativeWindow->lockBuffer(nativeWindow, buffer);
+ // pin the buffer down
+ if (lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN |
+ GRALLOC_USAGE_SW_WRITE_OFTEN, &bits) != NO_ERROR) {
+ LOGE("connect() failed to lock buffer %p (%ux%u)",
+ buffer, buffer->width, buffer->height);
+ return setError(EGL_BAD_ACCESS, EGL_FALSE);
+ // FIXME: we should make sure we're not accessing the buffer anymore
+ }
+ return EGL_TRUE;
+}
+
+void egl_window_surface_v2_t::disconnect()
+{
+ if (buffer && bits) {
+ bits = NULL;
+ unlock(buffer);
+ }
+ // enqueue the last frame
+ if (buffer)
+ nativeWindow->queueBuffer(nativeWindow, buffer);
+ if (buffer) {
+ buffer->common.decRef(&buffer->common);
+ buffer = 0;
+ }
+ if (previousBuffer) {
+ previousBuffer->common.decRef(&previousBuffer->common);
+ previousBuffer = 0;
+ }
+}
+
+status_t egl_window_surface_v2_t::lock(
+ android_native_buffer_t* buf, int usage, void** vaddr)
+{
+ int err;
+
+ err = module->lock(module, buf->handle,
+ usage, 0, 0, buf->width, buf->height, vaddr);
+
+ return err;
+}
+
+status_t egl_window_surface_v2_t::unlock(android_native_buffer_t* buf)
+{
+ if (!buf) return BAD_VALUE;
+ int err = NO_ERROR;
+
+ err = module->unlock(module, buf->handle);
+
+ return err;
+}
+
+void egl_window_surface_v2_t::copyBlt(
+ android_native_buffer_t* dst, void* dst_vaddr,
+ android_native_buffer_t* src, void const* src_vaddr,
+ const Region& clip)
+{
+ // FIXME: use copybit if possible
+ // NOTE: dst and src must be the same format
+
+ status_t err = NO_ERROR;
+ copybit_device_t* const copybit = blitengine;
+ if (copybit) {
+ copybit_image_t simg;
+ simg.w = src->stride;
+ simg.h = src->height;
+ simg.format = src->format;
+ simg.handle = const_cast<native_handle_t*>(src->handle);
+
+ copybit_image_t dimg;
+ dimg.w = dst->stride;
+ dimg.h = dst->height;
+ dimg.format = dst->format;
+ dimg.handle = const_cast<native_handle_t*>(dst->handle);
+
+ copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
+ copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 255);
+ copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE);
+ region_iterator it(clip);
+ err = copybit->blit(copybit, &dimg, &simg, &it);
+ if (err != NO_ERROR) {
+ LOGE("copybit failed (%s)", strerror(err));
+ }
+ }
+
+ if (!copybit || err) {
+ Region::const_iterator cur = clip.begin();
+ Region::const_iterator end = clip.end();
+
+ const size_t bpp = pixelFormatTable[src->format].size;
+ const size_t dbpr = dst->stride * bpp;
+ const size_t sbpr = src->stride * bpp;
+
+ uint8_t const * const src_bits = (uint8_t const *)src_vaddr;
+ uint8_t * const dst_bits = (uint8_t *)dst_vaddr;
+
+ while (cur != end) {
+ const Rect& r(*cur++);
+ ssize_t w = r.right - r.left;
+ ssize_t h = r.bottom - r.top;
+ if (w <= 0 || h<=0) continue;
+ size_t size = w * bpp;
+ uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp;
+ uint8_t * d = dst_bits + (r.left + dst->stride * r.top) * bpp;
+ if (dbpr==sbpr && size==sbpr) {
+ size *= h;
+ h = 1;
+ }
+ do {
+ memcpy(d, s, size);
+ d += dbpr;
+ s += sbpr;
+ } while (--h > 0);
+ }
+ }
+}
+
+EGLBoolean egl_window_surface_v2_t::swapBuffers()
+{
+ if (!buffer) {
+ return setError(EGL_BAD_ACCESS, EGL_FALSE);
+ }
+
+ /*
+ * Handle eglSetSwapRectangleANDROID()
+ * We copyback from the front buffer
+ */
+ if (!dirtyRegion.isEmpty()) {
+ dirtyRegion.andSelf(Rect(buffer->width, buffer->height));
+ if (previousBuffer) {
+ // This was const Region copyBack, but that causes an
+ // internal compile error on simulator builds
+ /*const*/
+ Region copyBack(Region::subtract(oldDirtyRegion, dirtyRegion));
+ if (!copyBack.isEmpty()) {
+ void* prevBits;
+ if (lock(previousBuffer,
+ GRALLOC_USAGE_SW_READ_OFTEN, &prevBits) == NO_ERROR) {
+ // copy from previousBuffer to buffer
+ copyBlt(buffer, bits, previousBuffer, prevBits, copyBack);
+ unlock(previousBuffer);
+ }
+ }
+ }
+ oldDirtyRegion = dirtyRegion;
+ }
+
+ if (previousBuffer) {
+ previousBuffer->common.decRef(&previousBuffer->common);
+ previousBuffer = 0;
+ }
+
+ unlock(buffer);
+ previousBuffer = buffer;
+ nativeWindow->queueBuffer(nativeWindow, buffer);
+ buffer = 0;
+
+ // dequeue a new buffer
+ if (nativeWindow->dequeueBuffer(nativeWindow, &buffer) == NO_ERROR) {
+
+ // TODO: lockBuffer should rather be executed when the very first
+ // direct rendering occurs.
+ nativeWindow->lockBuffer(nativeWindow, buffer);
+
+ // reallocate the depth-buffer if needed
+ if ((width != buffer->width) || (height != buffer->height)) {
+ // TODO: we probably should reset the swap rect here
+ // if the window size has changed
+ width = buffer->width;
+ height = buffer->height;
+ if (depth.data) {
+ free(depth.data);
+ depth.width = width;
+ depth.height = height;
+ depth.stride = buffer->stride;
+ depth.data = (GGLubyte*)malloc(depth.stride*depth.height*2);
+ if (depth.data == 0) {
+ setError(EGL_BAD_ALLOC, EGL_FALSE);
+ return EGL_FALSE;
+ }
+ }
+ }
+
+ // keep a reference on the buffer
+ buffer->common.incRef(&buffer->common);
+
+ // finally pin the buffer down
+ if (lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN |
+ GRALLOC_USAGE_SW_WRITE_OFTEN, &bits) != NO_ERROR) {
+ LOGE("eglSwapBuffers() failed to lock buffer %p (%ux%u)",
+ buffer, buffer->width, buffer->height);
+ return setError(EGL_BAD_ACCESS, EGL_FALSE);
+ // FIXME: we should make sure we're not accessing the buffer anymore
+ }
+ } else {
+ return setError(EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
+ }
+
+ return EGL_TRUE;
+}
+
+EGLBoolean egl_window_surface_v2_t::setSwapRectangle(
+ EGLint l, EGLint t, EGLint w, EGLint h)
+{
+ dirtyRegion = Rect(l, t, l+w, t+h);
+ return EGL_TRUE;
+}
+
+EGLBoolean egl_window_surface_v2_t::bindDrawSurface(GLES2Context* gl)
+{
+ GGLSurface buffer;
+ buffer.version = sizeof(GGLSurface);
+ buffer.width = this->buffer->width;
+ buffer.height = this->buffer->height;
+ buffer.stride = this->buffer->stride;
+ buffer.data = (GGLubyte*)bits;
+ buffer.format = (GGLPixelFormat)this->buffer->format;
+ gl->rasterizer.interface.SetBuffer(&gl->rasterizer.interface, GL_COLOR_BUFFER_BIT, &buffer);
+ if (depth.data != gl->rasterizer.depthSurface.data)
+ gl->rasterizer.interface.SetBuffer(&gl->rasterizer.interface, GL_DEPTH_BUFFER_BIT, &depth);
+
+ return EGL_TRUE;
+}
+EGLBoolean egl_window_surface_v2_t::bindReadSurface(GLES2Context* gl)
+{
+ GGLSurface buffer;
+ buffer.version = sizeof(GGLSurface);
+ buffer.width = this->buffer->width;
+ buffer.height = this->buffer->height;
+ buffer.stride = this->buffer->stride;
+ buffer.data = (GGLubyte*)bits; // FIXME: hopefully is is LOCKED!!!
+ buffer.format = (GGLPixelFormat)this->buffer->format;
+ puts("agl2: readBuffer not implemented");
+ //gl->rasterizer.interface.readBuffer(gl, &buffer);
+ return EGL_TRUE;
+}
+EGLint egl_window_surface_v2_t::getHorizontalResolution() const
+{
+ return (nativeWindow->xdpi * EGL_DISPLAY_SCALING) * (1.0f / 25.4f);
+}
+EGLint egl_window_surface_v2_t::getVerticalResolution() const
+{
+ return (nativeWindow->ydpi * EGL_DISPLAY_SCALING) * (1.0f / 25.4f);
+}
+EGLint egl_window_surface_v2_t::getRefreshRate() const
+{
+ return (60 * EGL_DISPLAY_SCALING); // FIXME
+}
+EGLint egl_window_surface_v2_t::getSwapBehavior() const
+{
+ /*
+ * EGL_BUFFER_PRESERVED means that eglSwapBuffers() completely preserves
+ * the content of the swapped buffer.
+ *
+ * EGL_BUFFER_DESTROYED means that the content of the buffer is lost.
+ *
+ * However when ANDROID_swap_retcangle is supported, EGL_BUFFER_DESTROYED
+ * only applies to the area specified by eglSetSwapRectangleANDROID(), that
+ * is, everything outside of this area is preserved.
+ *
+ * This implementation of EGL assumes the later case.
+ *
+ */
+
+ return EGL_BUFFER_DESTROYED;
+}
+
+// ----------------------------------------------------------------------------
+
+struct egl_pixmap_surface_t : public egl_surface_t {
+ egl_pixmap_surface_t(
+ EGLDisplay dpy, EGLConfig config,
+ int32_t depthFormat,
+ egl_native_pixmap_t const * pixmap);
+
+ virtual ~egl_pixmap_surface_t() { }
+
+ virtual bool initCheck() const {
+ return !depth.format || depth.data!=0;
+ }
+ virtual EGLBoolean bindDrawSurface(GLES2Context* gl);
+ virtual EGLBoolean bindReadSurface(GLES2Context* gl);
+ virtual EGLint getWidth() const {
+ return nativePixmap.width;
+ }
+ virtual EGLint getHeight() const {
+ return nativePixmap.height;
+ }
+private:
+ egl_native_pixmap_t nativePixmap;
+};
+
+egl_pixmap_surface_t::egl_pixmap_surface_t(EGLDisplay dpy,
+ EGLConfig config,
+ int32_t depthFormat,
+ egl_native_pixmap_t const * pixmap)
+ : egl_surface_t(dpy, config, depthFormat), nativePixmap(*pixmap)
+{
+ if (depthFormat) {
+ depth.width = pixmap->width;
+ depth.height = pixmap->height;
+ depth.stride = depth.width; // use the width here
+ depth.data = (GGLubyte*)malloc(depth.stride*depth.height*2);
+ if (depth.data == 0) {
+ setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+ }
+ }
+}
+EGLBoolean egl_pixmap_surface_t::bindDrawSurface(GLES2Context* gl)
+{
+ GGLSurface buffer;
+ buffer.version = sizeof(GGLSurface);
+ buffer.width = nativePixmap.width;
+ buffer.height = nativePixmap.height;
+ buffer.stride = nativePixmap.stride;
+ buffer.data = nativePixmap.data;
+ buffer.format = (GGLPixelFormat)nativePixmap.format;
+
+ gl->rasterizer.interface.SetBuffer(&gl->rasterizer.interface, GL_COLOR_BUFFER_BIT, &buffer);
+ if (depth.data != gl->rasterizer.depthSurface.data)
+ gl->rasterizer.interface.SetBuffer(&gl->rasterizer.interface, GL_DEPTH_BUFFER_BIT, &depth);
+ return EGL_TRUE;
+}
+EGLBoolean egl_pixmap_surface_t::bindReadSurface(GLES2Context* gl)
+{
+ GGLSurface buffer;
+ buffer.version = sizeof(GGLSurface);
+ buffer.width = nativePixmap.width;
+ buffer.height = nativePixmap.height;
+ buffer.stride = nativePixmap.stride;
+ buffer.data = nativePixmap.data;
+ buffer.format = (GGLPixelFormat)nativePixmap.format;
+ puts("agl2: readBuffer not implemented");
+ //gl->rasterizer.interface.readBuffer(gl, &buffer);
+ return EGL_TRUE;
+}
+
+// ----------------------------------------------------------------------------
+
+struct egl_pbuffer_surface_t : public egl_surface_t {
+ egl_pbuffer_surface_t(
+ EGLDisplay dpy, EGLConfig config, int32_t depthFormat,
+ int32_t w, int32_t h, int32_t f);
+
+ virtual ~egl_pbuffer_surface_t();
+
+ virtual bool initCheck() const {
+ return pbuffer.data != 0;
+ }
+ virtual EGLBoolean bindDrawSurface(GLES2Context* gl);
+ virtual EGLBoolean bindReadSurface(GLES2Context* gl);
+ virtual EGLint getWidth() const {
+ return pbuffer.width;
+ }
+ virtual EGLint getHeight() const {
+ return pbuffer.height;
+ }
+private:
+ GGLSurface pbuffer;
+};
+
+egl_pbuffer_surface_t::egl_pbuffer_surface_t(EGLDisplay dpy,
+ EGLConfig config, int32_t depthFormat,
+ int32_t w, int32_t h, int32_t f)
+ : egl_surface_t(dpy, config, depthFormat)
+{
+ size_t size = w*h;
+ switch (f) {
+ case GGL_PIXEL_FORMAT_A_8:
+ size *= 1;
+ break;
+ case GGL_PIXEL_FORMAT_RGB_565:
+ size *= 2;
+ break;
+ case GGL_PIXEL_FORMAT_RGBA_8888:
+ size *= 4;
+ break;
+ case GGL_PIXEL_FORMAT_RGBX_8888:
+ size *= 4;
+ break;
+ default:
+ LOGE("incompatible pixel format for pbuffer (format=%d)", f);
+ pbuffer.data = 0;
+ break;
+ }
+ pbuffer.version = sizeof(GGLSurface);
+ pbuffer.width = w;
+ pbuffer.height = h;
+ pbuffer.stride = w;
+ pbuffer.data = (GGLubyte*)malloc(size);
+ pbuffer.format = (GGLPixelFormat)f;
+
+ if (depthFormat) {
+ depth.width = pbuffer.width;
+ depth.height = pbuffer.height;
+ depth.stride = depth.width; // use the width here
+ depth.data = (GGLubyte*)malloc(depth.stride*depth.height*2);
+ if (depth.data == 0) {
+ setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+ return;
+ }
+ }
+}
+egl_pbuffer_surface_t::~egl_pbuffer_surface_t()
+{
+ free(pbuffer.data);
+}
+EGLBoolean egl_pbuffer_surface_t::bindDrawSurface(GLES2Context* gl)
+{
+ gl->rasterizer.interface.SetBuffer(&gl->rasterizer.interface, GL_COLOR_BUFFER_BIT, &pbuffer);
+ if (depth.data != gl->rasterizer.depthSurface.data)
+ gl->rasterizer.interface.SetBuffer(&gl->rasterizer.interface, GL_DEPTH_BUFFER_BIT, &depth);
+ return EGL_TRUE;
+}
+EGLBoolean egl_pbuffer_surface_t::bindReadSurface(GLES2Context* gl)
+{
+ puts("agl2: readBuffer not implemented");
+ //gl->rasterizer.interface.readBuffer(gl, &pbuffer);
+ return EGL_TRUE;
+}
+
+// ----------------------------------------------------------------------------
+
+struct config_pair_t {
+ GLint key;
+ GLint value;
+};
+
+struct configs_t {
+ const config_pair_t* array;
+ int size;
+};
+
+struct config_management_t {
+ GLint key;
+ bool (*match)(GLint reqValue, GLint confValue);
+ static bool atLeast(GLint reqValue, GLint confValue) {
+ return (reqValue == EGL_DONT_CARE) || (confValue >= reqValue);
+ }
+ static bool exact(GLint reqValue, GLint confValue) {
+ return (reqValue == EGL_DONT_CARE) || (confValue == reqValue);
+ }
+ static bool mask(GLint reqValue, GLint confValue) {
+ return (confValue & reqValue) == reqValue;
+ }
+ static bool ignore(GLint reqValue, GLint confValue) {
+ return true;
+ }
+};
+
+// ----------------------------------------------------------------------------
+
+#define VERSION_MAJOR 1
+#define VERSION_MINOR 2
+static char const * const gVendorString = "Google Inc.";
+static char const * const gVersionString = "0.0 Android Driver 0.0.0";
+static char const * const gClientApiString = "OpenGL ES2";
+static char const * const gExtensionsString =
+ //"EGL_KHR_image_base "
+ // "KHR_image_pixmap "
+ //"EGL_ANDROID_image_native_buffer "
+ //"EGL_ANDROID_swap_rectangle "
+ "";
+
+// ----------------------------------------------------------------------------
+
+struct extention_map_t {
+ const char * const name;
+ __eglMustCastToProperFunctionPointerType address;
+};
+
+static const extention_map_t gExtentionMap[] = {
+// { "glDrawTexsOES",
+// (__eglMustCastToProperFunctionPointerType)&glDrawTexsOES },
+// { "glDrawTexiOES",
+// (__eglMustCastToProperFunctionPointerType)&glDrawTexiOES },
+// { "glDrawTexfOES",
+// (__eglMustCastToProperFunctionPointerType)&glDrawTexfOES },
+// { "glDrawTexxOES",
+// (__eglMustCastToProperFunctionPointerType)&glDrawTexxOES },
+// { "glDrawTexsvOES",
+// (__eglMustCastToProperFunctionPointerType)&glDrawTexsvOES },
+// { "glDrawTexivOES",
+// (__eglMustCastToProperFunctionPointerType)&glDrawTexivOES },
+// { "glDrawTexfvOES",
+// (__eglMustCastToProperFunctionPointerType)&glDrawTexfvOES },
+// { "glDrawTexxvOES",
+// (__eglMustCastToProperFunctionPointerType)&glDrawTexxvOES },
+// { "glQueryMatrixxOES",
+// (__eglMustCastToProperFunctionPointerType)&glQueryMatrixxOES },
+// { "glEGLImageTargetTexture2DOES",
+// (__eglMustCastToProperFunctionPointerType)&glEGLImageTargetTexture2DOES },
+// { "glEGLImageTargetRenderbufferStorageOES",
+// (__eglMustCastToProperFunctionPointerType)&glEGLImageTargetRenderbufferStorageOES },
+// { "glClipPlanef",
+// (__eglMustCastToProperFunctionPointerType)&glClipPlanef },
+// { "glClipPlanex",
+// (__eglMustCastToProperFunctionPointerType)&glClipPlanex },
+// { "glBindBuffer",
+// (__eglMustCastToProperFunctionPointerType)&glBindBuffer },
+// { "glBufferData",
+// (__eglMustCastToProperFunctionPointerType)&glBufferData },
+// { "glBufferSubData",
+// (__eglMustCastToProperFunctionPointerType)&glBufferSubData },
+// { "glDeleteBuffers",
+// (__eglMustCastToProperFunctionPointerType)&glDeleteBuffers },
+// { "glGenBuffers",
+// (__eglMustCastToProperFunctionPointerType)&glGenBuffers },
+// { "eglCreateImageKHR",
+// (__eglMustCastToProperFunctionPointerType)&eglCreateImageKHR },
+// { "eglDestroyImageKHR",
+// (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR },
+// { "eglSetSwapRectangleANDROID",
+// (__eglMustCastToProperFunctionPointerType)&eglSetSwapRectangleANDROID },
+};
+
+/*
+ * In the lists below, attributes names MUST be sorted.
+ * Additionally, all configs must be sorted according to
+ * the EGL specification.
+ */
+
+static config_pair_t const config_base_attribute_list[] = {
+ { EGL_STENCIL_SIZE, 0 },
+ { EGL_CONFIG_CAVEAT, EGL_SLOW_CONFIG },
+ { EGL_LEVEL, 0 },
+ { EGL_MAX_PBUFFER_HEIGHT, GGL_MAX_VIEWPORT_DIMS },
+ { EGL_MAX_PBUFFER_PIXELS,
+ GGL_MAX_VIEWPORT_DIMS*GGL_MAX_VIEWPORT_DIMS },
+ { EGL_MAX_PBUFFER_WIDTH, GGL_MAX_VIEWPORT_DIMS },
+ { EGL_NATIVE_RENDERABLE, EGL_TRUE },
+ { EGL_NATIVE_VISUAL_ID, 0 },
+ { EGL_NATIVE_VISUAL_TYPE, GGL_PIXEL_FORMAT_RGBA_8888 },
+ { EGL_SAMPLES, 0 },
+ { EGL_SAMPLE_BUFFERS, 0 },
+ { EGL_TRANSPARENT_TYPE, EGL_NONE },
+ { EGL_TRANSPARENT_BLUE_VALUE, 0 },
+ { EGL_TRANSPARENT_GREEN_VALUE, 0 },
+ { EGL_TRANSPARENT_RED_VALUE, 0 },
+ { EGL_BIND_TO_TEXTURE_RGBA, EGL_FALSE },
+ { EGL_BIND_TO_TEXTURE_RGB, EGL_FALSE },
+ { EGL_MIN_SWAP_INTERVAL, 1 },
+ { EGL_MAX_SWAP_INTERVAL, 1 },
+ { EGL_LUMINANCE_SIZE, 0 },
+ { EGL_ALPHA_MASK_SIZE, 0 },
+ { EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER },
+ { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT },
+ { EGL_CONFORMANT, 0 }
+};
+
+// These configs can override the base attribute list
+// NOTE: when adding a config here, don't forget to update eglCreate*Surface()
+
+// 565 configs
+static config_pair_t const config_0_attribute_list[] = {
+ { EGL_BUFFER_SIZE, 16 },
+ { EGL_ALPHA_SIZE, 0 },
+ { EGL_BLUE_SIZE, 5 },
+ { EGL_GREEN_SIZE, 6 },
+ { EGL_RED_SIZE, 5 },
+ { EGL_DEPTH_SIZE, 0 },
+ { EGL_CONFIG_ID, 0 },
+ { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_RGB_565 },
+ { EGL_SURFACE_TYPE, EGL_SWAP_BEHAVIOR_PRESERVED_BIT|EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
+};
+
+static config_pair_t const config_1_attribute_list[] = {
+ { EGL_BUFFER_SIZE, 16 },
+ { EGL_ALPHA_SIZE, 0 },
+ { EGL_BLUE_SIZE, 5 },
+ { EGL_GREEN_SIZE, 6 },
+ { EGL_RED_SIZE, 5 },
+ { EGL_DEPTH_SIZE, 16 },
+ { EGL_CONFIG_ID, 1 },
+ { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_RGB_565 },
+ { EGL_SURFACE_TYPE, EGL_SWAP_BEHAVIOR_PRESERVED_BIT|EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
+};
+
+// RGB 888 configs
+static config_pair_t const config_2_attribute_list[] = {
+ { EGL_BUFFER_SIZE, 32 },
+ { EGL_ALPHA_SIZE, 0 },
+ { EGL_BLUE_SIZE, 8 },
+ { EGL_GREEN_SIZE, 8 },
+ { EGL_RED_SIZE, 8 },
+ { EGL_DEPTH_SIZE, 0 },
+ { EGL_CONFIG_ID, 6 },
+ { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_RGBX_8888 },
+ { EGL_SURFACE_TYPE, EGL_SWAP_BEHAVIOR_PRESERVED_BIT|EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
+};
+
+static config_pair_t const config_3_attribute_list[] = {
+ { EGL_BUFFER_SIZE, 32 },
+ { EGL_ALPHA_SIZE, 0 },
+ { EGL_BLUE_SIZE, 8 },
+ { EGL_GREEN_SIZE, 8 },
+ { EGL_RED_SIZE, 8 },
+ { EGL_DEPTH_SIZE, 16 },
+ { EGL_CONFIG_ID, 7 },
+ { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_RGBX_8888 },
+ { EGL_SURFACE_TYPE, EGL_SWAP_BEHAVIOR_PRESERVED_BIT|EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
+};
+
+// 8888 configs
+static config_pair_t const config_4_attribute_list[] = {
+ { EGL_BUFFER_SIZE, 32 },
+ { EGL_ALPHA_SIZE, 8 },
+ { EGL_BLUE_SIZE, 8 },
+ { EGL_GREEN_SIZE, 8 },
+ { EGL_RED_SIZE, 8 },
+ { EGL_DEPTH_SIZE, 0 },
+ { EGL_CONFIG_ID, 2 },
+ { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_RGBA_8888 },
+ { EGL_SURFACE_TYPE, EGL_SWAP_BEHAVIOR_PRESERVED_BIT|EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
+};
+
+static config_pair_t const config_5_attribute_list[] = {
+ { EGL_BUFFER_SIZE, 32 },
+ { EGL_ALPHA_SIZE, 8 },
+ { EGL_BLUE_SIZE, 8 },
+ { EGL_GREEN_SIZE, 8 },
+ { EGL_RED_SIZE, 8 },
+ { EGL_DEPTH_SIZE, 16 },
+ { EGL_CONFIG_ID, 3 },
+ { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_RGBA_8888 },
+ { EGL_SURFACE_TYPE, EGL_SWAP_BEHAVIOR_PRESERVED_BIT|EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
+};
+
+// A8 configs
+static config_pair_t const config_6_attribute_list[] = {
+ { EGL_BUFFER_SIZE, 8 },
+ { EGL_ALPHA_SIZE, 8 },
+ { EGL_BLUE_SIZE, 0 },
+ { EGL_GREEN_SIZE, 0 },
+ { EGL_RED_SIZE, 0 },
+ { EGL_DEPTH_SIZE, 0 },
+ { EGL_CONFIG_ID, 4 },
+ { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_A_8 },
+ { EGL_SURFACE_TYPE, EGL_SWAP_BEHAVIOR_PRESERVED_BIT|EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
+};
+
+static config_pair_t const config_7_attribute_list[] = {
+ { EGL_BUFFER_SIZE, 8 },
+ { EGL_ALPHA_SIZE, 8 },
+ { EGL_BLUE_SIZE, 0 },
+ { EGL_GREEN_SIZE, 0 },
+ { EGL_RED_SIZE, 0 },
+ { EGL_DEPTH_SIZE, 16 },
+ { EGL_CONFIG_ID, 5 },
+ { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_A_8 },
+ { EGL_SURFACE_TYPE, EGL_SWAP_BEHAVIOR_PRESERVED_BIT|EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
+};
+
+static configs_t const gConfigs[] = {
+ { config_0_attribute_list, NELEM(config_0_attribute_list) },
+ { config_1_attribute_list, NELEM(config_1_attribute_list) },
+ { config_2_attribute_list, NELEM(config_2_attribute_list) },
+ { config_3_attribute_list, NELEM(config_3_attribute_list) },
+ { config_4_attribute_list, NELEM(config_4_attribute_list) },
+ { config_5_attribute_list, NELEM(config_5_attribute_list) },
+// { config_6_attribute_list, NELEM(config_6_attribute_list) },
+// { config_7_attribute_list, NELEM(config_7_attribute_list) },
+};
+
+static config_management_t const gConfigManagement[] = {
+ { EGL_BUFFER_SIZE, config_management_t::atLeast },
+ { EGL_ALPHA_SIZE, config_management_t::atLeast },
+ { EGL_BLUE_SIZE, config_management_t::atLeast },
+ { EGL_GREEN_SIZE, config_management_t::atLeast },
+ { EGL_RED_SIZE, config_management_t::atLeast },
+ { EGL_DEPTH_SIZE, config_management_t::atLeast },
+ { EGL_STENCIL_SIZE, config_management_t::atLeast },
+ { EGL_CONFIG_CAVEAT, config_management_t::exact },
+ { EGL_CONFIG_ID, config_management_t::exact },
+ { EGL_LEVEL, config_management_t::exact },
+ { EGL_MAX_PBUFFER_HEIGHT, config_management_t::ignore },
+ { EGL_MAX_PBUFFER_PIXELS, config_management_t::ignore },
+ { EGL_MAX_PBUFFER_WIDTH, config_management_t::ignore },
+ { EGL_NATIVE_RENDERABLE, config_management_t::exact },
+ { EGL_NATIVE_VISUAL_ID, config_management_t::ignore },
+ { EGL_NATIVE_VISUAL_TYPE, config_management_t::exact },
+ { EGL_SAMPLES, config_management_t::exact },
+ { EGL_SAMPLE_BUFFERS, config_management_t::exact },
+ { EGL_SURFACE_TYPE, config_management_t::mask },
+ { EGL_TRANSPARENT_TYPE, config_management_t::exact },
+ { EGL_TRANSPARENT_BLUE_VALUE, config_management_t::exact },
+ { EGL_TRANSPARENT_GREEN_VALUE, config_management_t::exact },
+ { EGL_TRANSPARENT_RED_VALUE, config_management_t::exact },
+ { EGL_BIND_TO_TEXTURE_RGBA, config_management_t::exact },
+ { EGL_BIND_TO_TEXTURE_RGB, config_management_t::exact },
+ { EGL_MIN_SWAP_INTERVAL, config_management_t::exact },
+ { EGL_MAX_SWAP_INTERVAL, config_management_t::exact },
+ { EGL_LUMINANCE_SIZE, config_management_t::atLeast },
+ { EGL_ALPHA_MASK_SIZE, config_management_t::atLeast },
+ { EGL_COLOR_BUFFER_TYPE, config_management_t::exact },
+ { EGL_RENDERABLE_TYPE, config_management_t::mask },
+ { EGL_CONFORMANT, config_management_t::mask }
+};
+
+
+static config_pair_t const config_defaults[] = {
+ // attributes that are not specified are simply ignored, if a particular
+ // one needs not be ignored, it must be specified here, eg:
+ // { EGL_SURFACE_TYPE, EGL_WINDOW_BIT },
+};
+
+// ----------------------------------------------------------------------------
+
+static status_t getConfigFormatInfo(EGLint configID,
+ int32_t& pixelFormat, int32_t& depthFormat)
+{
+ switch (configID) {
+ case 0:
+ pixelFormat = GGL_PIXEL_FORMAT_RGB_565;
+ depthFormat = 0;
+ break;
+ case 1:
+ pixelFormat = GGL_PIXEL_FORMAT_RGB_565;
+ depthFormat = GGL_PIXEL_FORMAT_Z_32;
+ break;
+ case 2:
+ pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888;
+ depthFormat = 0;
+ break;
+ case 3:
+ pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888;
+ depthFormat = GGL_PIXEL_FORMAT_Z_32;
+ break;
+ case 4:
+ pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888;
+ depthFormat = 0;
+ break;
+ case 5:
+ pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888;
+ depthFormat = GGL_PIXEL_FORMAT_Z_32;
+ break;
+ case 6:
+ pixelFormat = GGL_PIXEL_FORMAT_A_8;
+ depthFormat = 0;
+ break;
+ case 7:
+ pixelFormat = GGL_PIXEL_FORMAT_A_8;
+ depthFormat = GGL_PIXEL_FORMAT_Z_32;
+ break;
+ default:
+ return NAME_NOT_FOUND;
+ }
+ return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+template<typename T>
+static int binarySearch(T const sortedArray[], int first, int last, EGLint key)
+{
+ while (first <= last) {
+ int mid = (first + last) / 2;
+ if (key > sortedArray[mid].key) {
+ first = mid + 1;
+ } else if (key < sortedArray[mid].key) {
+ last = mid - 1;
+ } else {
+ return mid;
+ }
+ }
+ return -1;
+}
+
+static int isAttributeMatching(int i, EGLint attr, EGLint val)
+{
+ // look for the attribute in all of our configs
+ config_pair_t const* configFound = gConfigs[i].array;
+ int index = binarySearch<config_pair_t>(
+ gConfigs[i].array,
+ 0, gConfigs[i].size-1,
+ attr);
+ if (index < 0) {
+ configFound = config_base_attribute_list;
+ index = binarySearch<config_pair_t>(
+ config_base_attribute_list,
+ 0, NELEM(config_base_attribute_list)-1,
+ attr);
+ }
+ if (index >= 0) {
+ // attribute found, check if this config could match
+ int cfgMgtIndex = binarySearch<config_management_t>(
+ gConfigManagement,
+ 0, NELEM(gConfigManagement)-1,
+ attr);
+ if (cfgMgtIndex >= 0) {
+ bool match = gConfigManagement[cfgMgtIndex].match(
+ val, configFound[index].value);
+ if (match) {
+ // this config matches
+ return 1;
+ }
+ } else {
+ // attribute not found. this should NEVER happen.
+ }
+ } else {
+ // error, this attribute doesn't exist
+ }
+ return 0;
+}
+
+static int makeCurrent(GLES2Context* gl)
+{
+ GLES2Context* current = (GLES2Context*)getGlThreadSpecific();
+ if (gl) {
+ egl_context_t* c = egl_context_t::context(gl);
+ if (c->flags & egl_context_t::IS_CURRENT) {
+ if (current != gl) {
+ // it is an error to set a context current, if it's already
+ // current to another thread
+ return -1;
+ }
+ } else {
+ if (current) {
+ // mark the current context as not current, and flush
+ glFlush();
+ egl_context_t::context(current)->flags &= ~egl_context_t::IS_CURRENT;
+ }
+ }
+ if (!(c->flags & egl_context_t::IS_CURRENT)) {
+ // The context is not current, make it current!
+ setGlThreadSpecific(gl);
+ c->flags |= egl_context_t::IS_CURRENT;
+ }
+ } else {
+ if (current) {
+ // mark the current context as not current, and flush
+ glFlush();
+ egl_context_t::context(current)->flags &= ~egl_context_t::IS_CURRENT;
+ }
+ // this thread has no context attached to it
+ setGlThreadSpecific(0);
+ }
+ return 0;
+}
+
+static EGLBoolean getConfigAttrib(EGLDisplay dpy, EGLConfig config,
+ EGLint attribute, EGLint *value)
+{
+ size_t numConfigs = NELEM(gConfigs);
+ int index = (int)config;
+ if (uint32_t(index) >= numConfigs)
+ return setError(EGL_BAD_CONFIG, EGL_FALSE);
+
+ int attrIndex;
+ attrIndex = binarySearch<config_pair_t>(
+ gConfigs[index].array,
+ 0, gConfigs[index].size-1,
+ attribute);
+ if (attrIndex>=0) {
+ *value = gConfigs[index].array[attrIndex].value;
+ return EGL_TRUE;
+ }
+
+ attrIndex = binarySearch<config_pair_t>(
+ config_base_attribute_list,
+ 0, NELEM(config_base_attribute_list)-1,
+ attribute);
+ if (attrIndex>=0) {
+ *value = config_base_attribute_list[attrIndex].value;
+ return EGL_TRUE;
+ }
+ return setError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+}
+
+static EGLSurface createWindowSurface(EGLDisplay dpy, EGLConfig config,
+ NativeWindowType window, const EGLint *attrib_list)
+{
+ if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+ return setError(EGL_BAD_DISPLAY, EGL_NO_SURFACE);
+ if (window == 0)
+ return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+
+ EGLint surfaceType;
+ if (getConfigAttrib(dpy, config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE)
+ return EGL_FALSE;
+
+ if (!(surfaceType & EGL_WINDOW_BIT))
+ return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+
+ if (reinterpret_cast<ANativeWindow*>(window)->common.magic !=
+ ANDROID_NATIVE_WINDOW_MAGIC) {
+ return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+ }
+
+ EGLint configID;
+ if (getConfigAttrib(dpy, config, EGL_CONFIG_ID, &configID) == EGL_FALSE)
+ return EGL_FALSE;
+
+ int32_t depthFormat;
+ int32_t pixelFormat;
+ if (getConfigFormatInfo(configID, pixelFormat, depthFormat) != NO_ERROR) {
+ return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+ }
+
+ // FIXME: we don't have access to the pixelFormat here just yet.
+ // (it's possible that the surface is not fully initialized)
+ // maybe this should be done after the page-flip
+ //if (EGLint(info.format) != pixelFormat)
+ // return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+
+ egl_surface_t* surface;
+ surface = new egl_window_surface_v2_t(dpy, config, depthFormat,
+ reinterpret_cast<ANativeWindow*>(window));
+
+ if (!surface->initCheck()) {
+ // there was a problem in the ctor, the error
+ // flag has been set.
+ delete surface;
+ surface = 0;
+ }
+ return surface;
+}
+
+static EGLSurface createPixmapSurface(EGLDisplay dpy, EGLConfig config,
+ NativePixmapType pixmap, const EGLint *attrib_list)
+{
+ if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+ return setError(EGL_BAD_DISPLAY, EGL_NO_SURFACE);
+ if (pixmap == 0)
+ return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+
+ EGLint surfaceType;
+ if (getConfigAttrib(dpy, config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE)
+ return EGL_FALSE;
+
+ if (!(surfaceType & EGL_PIXMAP_BIT))
+ return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+
+ if (reinterpret_cast<egl_native_pixmap_t*>(pixmap)->version !=
+ sizeof(egl_native_pixmap_t)) {
+ return setError(EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
+ }
+
+ EGLint configID;
+ if (getConfigAttrib(dpy, config, EGL_CONFIG_ID, &configID) == EGL_FALSE)
+ return EGL_FALSE;
+
+ int32_t depthFormat;
+ int32_t pixelFormat;
+ if (getConfigFormatInfo(configID, pixelFormat, depthFormat) != NO_ERROR) {
+ return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+ }
+
+ if (reinterpret_cast<egl_native_pixmap_t *>(pixmap)->format != pixelFormat)
+ return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+
+ egl_surface_t* surface =
+ new egl_pixmap_surface_t(dpy, config, depthFormat,
+ reinterpret_cast<egl_native_pixmap_t*>(pixmap));
+
+ if (!surface->initCheck()) {
+ // there was a problem in the ctor, the error
+ // flag has been set.
+ delete surface;
+ surface = 0;
+ }
+ return surface;
+}
+
+static EGLSurface createPbufferSurface(EGLDisplay dpy, EGLConfig config,
+ const EGLint *attrib_list)
+{
+ if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+ return setError(EGL_BAD_DISPLAY, EGL_NO_SURFACE);
+
+ EGLint surfaceType;
+ if (getConfigAttrib(dpy, config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE)
+ return EGL_FALSE;
+
+ if (!(surfaceType & EGL_PBUFFER_BIT))
+ return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+
+ EGLint configID;
+ if (getConfigAttrib(dpy, config, EGL_CONFIG_ID, &configID) == EGL_FALSE)
+ return EGL_FALSE;
+
+ int32_t depthFormat;
+ int32_t pixelFormat;
+ if (getConfigFormatInfo(configID, pixelFormat, depthFormat) != NO_ERROR) {
+ return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+ }
+
+ int32_t w = 0;
+ int32_t h = 0;
+ while (attrib_list[0]) {
+ if (attrib_list[0] == EGL_WIDTH) w = attrib_list[1];
+ if (attrib_list[0] == EGL_HEIGHT) h = attrib_list[1];
+ attrib_list+=2;
+ }
+
+ egl_surface_t* surface =
+ new egl_pbuffer_surface_t(dpy, config, depthFormat, w, h, pixelFormat);
+
+ if (!surface->initCheck()) {
+ // there was a problem in the ctor, the error
+ // flag has been set.
+ delete surface;
+ surface = 0;
+ }
+ return surface;
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
+
+using namespace android;
+
+// ----------------------------------------------------------------------------
+// Initialization
+// ----------------------------------------------------------------------------
+
+EGLDisplay eglGetDisplay(NativeDisplayType display)
+{
+ puts("agl2:eglGetDisplay");
+#ifndef HAVE_ANDROID_OS
+ // this just needs to be done once
+ if (gGLKey == -1) {
+ pthread_mutex_lock(&gInitMutex);
+ if (gGLKey == -1)
+ pthread_key_create(&gGLKey, NULL);
+ pthread_mutex_unlock(&gInitMutex);
+ }
+#endif
+ if (display == EGL_DEFAULT_DISPLAY) {
+ EGLDisplay dpy = (EGLDisplay)1;
+ egl_display_t& d = egl_display_t::get_display(dpy);
+ d.type = display;
+ return dpy;
+ }
+ return EGL_NO_DISPLAY;
+}
+
+EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
+{
+ puts("agl2:eglInitialize");
+ if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+ return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+ EGLBoolean res = EGL_TRUE;
+ egl_display_t& d = egl_display_t::get_display(dpy);
+
+ if (android_atomic_inc(&d.initialized) == 0) {
+ // initialize stuff here if needed
+ //pthread_mutex_lock(&gInitMutex);
+ //pthread_mutex_unlock(&gInitMutex);
+ }
+
+ if (res == EGL_TRUE) {
+ if (major != NULL) *major = VERSION_MAJOR;
+ if (minor != NULL) *minor = VERSION_MINOR;
+ }
+ return res;
+}
+
+EGLBoolean eglTerminate(EGLDisplay dpy)
+{
+ puts("agl2:eglTerminate");
+ if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+ return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+ EGLBoolean res = EGL_TRUE;
+ egl_display_t& d = egl_display_t::get_display(dpy);
+ if (android_atomic_dec(&d.initialized) == 1) {
+ // TODO: destroy all resources (surfaces, contexts, etc...)
+ //pthread_mutex_lock(&gInitMutex);
+ //pthread_mutex_unlock(&gInitMutex);
+ }
+ return res;
+}
+
+// ----------------------------------------------------------------------------
+// configuration
+// ----------------------------------------------------------------------------
+
+EGLBoolean eglGetConfigs( EGLDisplay dpy,
+ EGLConfig *configs,
+ EGLint config_size, EGLint *num_config)
+{
+ puts("agl2:eglGetConfigs");
+ if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+ return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+ GLint numConfigs = NELEM(gConfigs);
+ if (!configs) {
+ *num_config = numConfigs;
+ return EGL_TRUE;
+ }
+ GLint i;
+ for (i=0 ; i<numConfigs && i<config_size ; i++) {
+ *configs++ = (EGLConfig)i;
+ }
+ *num_config = i;
+ return EGL_TRUE;
+}
+
+static const char * ATTRIBUTE_NAMES [] = {
+ "EGL_BUFFER_SIZE",
+ "EGL_ALPHA_SIZE",
+ "EGL_BLUE_SIZE",
+ "EGL_GREEN_SIZE",
+ "EGL_RED_SIZE",
+ "EGL_DEPTH_SIZE",
+ "EGL_STENCIL_SIZE",
+ "EGL_CONFIG_CAVEAT",
+ "EGL_CONFIG_ID",
+ "EGL_LEVEL",
+ "EGL_MAX_PBUFFER_HEIGHT",
+ "EGL_MAX_PBUFFER_PIXELS",
+ "EGL_MAX_PBUFFER_WIDTH",
+ "EGL_NATIVE_RENDERABLE",
+ "EGL_NATIVE_VISUAL_ID",
+ "EGL_NATIVE_VISUAL_TYPE",
+ "EGL_PRESERVED_RESOURCES",
+ "EGL_SAMPLES",
+ "EGL_SAMPLE_BUFFERS",
+ "EGL_SURFACE_TYPE",
+ "EGL_TRANSPARENT_TYPE",
+ "EGL_TRANSPARENT_BLUE_VALUE",
+ "EGL_TRANSPARENT_GREEN_VALUE",
+ "EGL_TRANSPARENT_RED_VALUE",
+ "EGL_NONE", /* Attrib list terminator */
+ "EGL_BIND_TO_TEXTURE_RGB",
+ "EGL_BIND_TO_TEXTURE_RGBA",
+ "EGL_MIN_SWAP_INTERVAL",
+ "EGL_MAX_SWAP_INTERVAL",
+ "EGL_LUMINANCE_SIZE",
+ "EGL_ALPHA_MASK_SIZE",
+ "EGL_COLOR_BUFFER_TYPE",
+ "EGL_RENDERABLE_TYPE",
+ "EGL_MATCH_NATIVE_PIXMAP", /* Pseudo-attribute (not queryable) */
+ "EGL_CONFORMANT",
+};
+
+EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list,
+ EGLConfig *configs, EGLint config_size,
+ EGLint *num_config)
+{
+ puts("agl2:eglChooseConfig");
+ LOGD("\n***\n***\n agl2:LOGD eglChooseConfig \n***\n***\n");
+ if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+ return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+ if (ggl_unlikely(num_config==0)) {
+ LOGD("\n***\n***\n num_config==0 \n***\n***\n");
+ return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+ }
+
+ if (ggl_unlikely(attrib_list==0)) {
+ /*
+ * A NULL attrib_list should be treated as though it was an empty
+ * one (terminated with EGL_NONE) as defined in
+ * section 3.4.1 "Querying Configurations" in the EGL specification.
+ */
+ LOGD("\n***\n***\n attrib_list==0 \n***\n***\n");
+ static const EGLint dummy = EGL_NONE;
+ attrib_list = &dummy;
+ }
+
+ for (const EGLint * attrib = attrib_list; *attrib != EGL_NONE; attrib += 2) {
+ LOGD("eglChooseConfig %s(%.4X): %d \n", ATTRIBUTE_NAMES[attrib[0] - EGL_BUFFER_SIZE], attrib[0], attrib[1]);
+ if (EGL_BUFFER_SIZE > attrib[0] || EGL_CONFORMANT < attrib[0])
+ LOGD("eglChooseConfig invalid config attrib: 0x%.4X=%d \n", attrib[0], attrib[1]);
+ }
+
+ int numAttributes = 0;
+ int numConfigs = NELEM(gConfigs);
+ uint32_t possibleMatch = (1<<numConfigs)-1;
+ while (possibleMatch && *attrib_list != EGL_NONE) {
+ numAttributes++;
+ EGLint attr = *attrib_list++;
+ EGLint val = *attrib_list++;
+ for (int i=0 ; possibleMatch && i<numConfigs ; i++) {
+ if (!(possibleMatch & (1<<i)))
+ continue;
+ if (isAttributeMatching(i, attr, val) == 0) {
+ LOGD("!isAttributeMatching config(%d) %s=%d \n", i, ATTRIBUTE_NAMES[attr - EGL_BUFFER_SIZE], val);
+ possibleMatch &= ~(1<<i);
+ }
+ }
+ }
+
+ LOGD("eglChooseConfig possibleMatch=%.4X \n", possibleMatch);
+
+ // now, handle the attributes which have a useful default value
+ for (size_t j=0 ; possibleMatch && j<NELEM(config_defaults) ; j++) {
+ // see if this attribute was specified, if not, apply its
+ // default value
+ if (binarySearch<config_pair_t>(
+ (config_pair_t const*)attrib_list,
+ 0, numAttributes-1,
+ config_defaults[j].key) < 0) {
+ for (int i=0 ; possibleMatch && i<numConfigs ; i++) {
+ if (!(possibleMatch & (1<<i)))
+ continue;
+ if (isAttributeMatching(i,
+ config_defaults[j].key,
+ config_defaults[j].value) == 0) {
+ possibleMatch &= ~(1<<i);
+ }
+ }
+ }
+ }
+
+ // return the configurations found
+ int n=0;
+ if (possibleMatch) {
+ if (configs) {
+ for (int i=0 ; config_size && i<numConfigs ; i++) {
+ if (possibleMatch & (1<<i)) {
+ *configs++ = (EGLConfig)i;
+ config_size--;
+ n++;
+ }
+ }
+ } else {
+ for (int i=0 ; i<numConfigs ; i++) {
+ if (possibleMatch & (1<<i)) {
+ n++;
+ }
+ }
+ }
+ }
+ *num_config = n;
+ LOGD("\n***\n***\n num_config==%d \n***\n***\n", *num_config);
+ return EGL_TRUE;
+}
+
+EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
+ EGLint attribute, EGLint *value)
+{
+ puts("agl2:eglGetConfigAttrib");
+ if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+ return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+ return getConfigAttrib(dpy, config, attribute, value);
+}
+
+// ----------------------------------------------------------------------------
+// surfaces
+// ----------------------------------------------------------------------------
+
+EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
+ NativeWindowType window,
+ const EGLint *attrib_list)
+{
+ puts("agl2:eglCreateWindowSurface");
+ return createWindowSurface(dpy, config, window, attrib_list);
+}
+
+EGLSurface eglCreatePixmapSurface( EGLDisplay dpy, EGLConfig config,
+ NativePixmapType pixmap,
+ const EGLint *attrib_list)
+{
+ puts("agl2:eglCreatePixmapSurface");
+ return createPixmapSurface(dpy, config, pixmap, attrib_list);
+}
+
+EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config,
+ const EGLint *attrib_list)
+{
+ puts("agl2:eglCreatePbufferSurface");
+ return createPbufferSurface(dpy, config, attrib_list);
+}
+
+EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface eglSurface)
+{
+ puts("agl2:eglDestroySurface");
+ if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+ return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+ if (eglSurface != EGL_NO_SURFACE) {
+ egl_surface_t* surface( static_cast<egl_surface_t*>(eglSurface) );
+ if (!surface->isValid())
+ return setError(EGL_BAD_SURFACE, EGL_FALSE);
+ if (surface->dpy != dpy)
+ return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+ if (surface->ctx) {
+ // FIXME: this surface is current check what the spec says
+ surface->disconnect();
+ surface->ctx = 0;
+ }
+ delete surface;
+ }
+ return EGL_TRUE;
+}
+
+EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface eglSurface,
+ EGLint attribute, EGLint *value)
+{
+ puts("agl2:eglQuerySurface");
+ if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+ return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+ egl_surface_t* surface = static_cast<egl_surface_t*>(eglSurface);
+ if (!surface->isValid())
+ return setError(EGL_BAD_SURFACE, EGL_FALSE);
+ if (surface->dpy != dpy)
+ return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+ EGLBoolean ret = EGL_TRUE;
+ switch (attribute) {
+ case EGL_CONFIG_ID:
+ ret = getConfigAttrib(dpy, surface->config, EGL_CONFIG_ID, value);
+ break;
+ case EGL_WIDTH:
+ *value = surface->getWidth();
+ break;
+ case EGL_HEIGHT:
+ *value = surface->getHeight();
+ break;
+ case EGL_LARGEST_PBUFFER:
+ // not modified for a window or pixmap surface
+ break;
+ case EGL_TEXTURE_FORMAT:
+ *value = EGL_NO_TEXTURE;
+ break;
+ case EGL_TEXTURE_TARGET:
+ *value = EGL_NO_TEXTURE;
+ break;
+ case EGL_MIPMAP_TEXTURE:
+ *value = EGL_FALSE;
+ break;
+ case EGL_MIPMAP_LEVEL:
+ *value = 0;
+ break;
+ case EGL_RENDER_BUFFER:
+ // TODO: return the real RENDER_BUFFER here
+ *value = EGL_BACK_BUFFER;
+ break;
+ case EGL_HORIZONTAL_RESOLUTION:
+ // pixel/mm * EGL_DISPLAY_SCALING
+ *value = surface->getHorizontalResolution();
+ break;
+ case EGL_VERTICAL_RESOLUTION:
+ // pixel/mm * EGL_DISPLAY_SCALING
+ *value = surface->getVerticalResolution();
+ break;
+ case EGL_PIXEL_ASPECT_RATIO: {
+ // w/h * EGL_DISPLAY_SCALING
+ int wr = surface->getHorizontalResolution();
+ int hr = surface->getVerticalResolution();
+ *value = (wr * EGL_DISPLAY_SCALING) / hr;
+ }
+ break;
+ case EGL_SWAP_BEHAVIOR:
+ *value = surface->getSwapBehavior();
+ break;
+ default:
+ ret = setError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+ }
+ return ret;
+}
+
+EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config,
+ EGLContext share_list, const EGLint *attrib_list)
+{
+ puts("agl2:eglCreateContext");
+ if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+ return setError(EGL_BAD_DISPLAY, EGL_NO_SURFACE);
+
+ GLES2Context* gl = new GLES2Context();//ogles_init(sizeof(egl_context_t));
+ if (!gl) return setError(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
+
+ //egl_context_t* c = static_cast<egl_context_t*>(gl->rasterizer.base);
+ egl_context_t * c = &gl->egl;
+ c->flags = egl_context_t::NEVER_CURRENT;
+ c->dpy = dpy;
+ c->config = config;
+ c->read = 0;
+ c->draw = 0;
+
+ c->frame = 0;
+ c->lastSwapTime = clock();
+ c->accumulateSeconds = 0;
+ return (EGLContext)gl;
+}
+
+EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
+{
+ puts("agl2:eglDestroyContext");
+ if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+ return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+ egl_context_t* c = egl_context_t::context(ctx);
+ if (c->flags & egl_context_t::IS_CURRENT)
+ setGlThreadSpecific(0);
+ //ogles_uninit((GLES2Context*)ctx);
+ delete (GLES2Context*)ctx;
+ return EGL_TRUE;
+}
+
+EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw,
+ EGLSurface read, EGLContext ctx)
+{
+ puts("agl2:eglMakeCurrent");
+ if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+ return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+ if (draw) {
+ egl_surface_t* s = (egl_surface_t*)draw;
+ if (!s->isValid())
+ return setError(EGL_BAD_SURFACE, EGL_FALSE);
+ if (s->dpy != dpy)
+ return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+ // TODO: check that draw is compatible with the context
+ }
+ if (read && read!=draw) {
+ egl_surface_t* s = (egl_surface_t*)read;
+ if (!s->isValid())
+ return setError(EGL_BAD_SURFACE, EGL_FALSE);
+ if (s->dpy != dpy)
+ return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+ // TODO: check that read is compatible with the context
+ }
+
+ EGLContext current_ctx = EGL_NO_CONTEXT;
+
+ if ((read == EGL_NO_SURFACE && draw == EGL_NO_SURFACE) && (ctx != EGL_NO_CONTEXT))
+ return setError(EGL_BAD_MATCH, EGL_FALSE);
+
+ if ((read != EGL_NO_SURFACE || draw != EGL_NO_SURFACE) && (ctx == EGL_NO_CONTEXT))
+ return setError(EGL_BAD_MATCH, EGL_FALSE);
+
+ if (ctx == EGL_NO_CONTEXT) {
+ // if we're detaching, we need the current context
+ current_ctx = (EGLContext)getGlThreadSpecific();
+ } else {
+ egl_context_t* c = egl_context_t::context(ctx);
+ egl_surface_t* d = (egl_surface_t*)draw;
+ egl_surface_t* r = (egl_surface_t*)read;
+ if ((d && d->ctx && d->ctx != ctx) ||
+ (r && r->ctx && r->ctx != ctx)) {
+ // one of the surface is bound to a context in another thread
+ return setError(EGL_BAD_ACCESS, EGL_FALSE);
+ }
+ }
+
+ GLES2Context* gl = (GLES2Context*)ctx;
+ if (makeCurrent(gl) == 0) {
+ if (ctx) {
+ egl_context_t* c = egl_context_t::context(ctx);
+ egl_surface_t* d = (egl_surface_t*)draw;
+ egl_surface_t* r = (egl_surface_t*)read;
+
+ if (c->draw) {
+ egl_surface_t* s = reinterpret_cast<egl_surface_t*>(c->draw);
+ s->disconnect();
+ }
+ if (c->read) {
+ // FIXME: unlock/disconnect the read surface too
+ }
+
+ c->draw = draw;
+ c->read = read;
+
+ if (c->flags & egl_context_t::NEVER_CURRENT) {
+ c->flags &= ~egl_context_t::NEVER_CURRENT;
+ GLint w = 0;
+ GLint h = 0;
+ if (draw) {
+ w = d->getWidth();
+ h = d->getHeight();
+ }
+ gl->rasterizer.interface.Viewport(&gl->rasterizer.interface, 0, 0, w, h);
+ //ogles_surfaceport(gl, 0, 0);
+ //ogles_viewport(gl, 0, 0, w, h);
+ //ogles_scissor(gl, 0, 0, w, h);
+ }
+ if (d) {
+ if (d->connect() == EGL_FALSE) {
+ return EGL_FALSE;
+ }
+ d->ctx = ctx;
+ d->bindDrawSurface(gl);
+ }
+ if (r) {
+ // FIXME: lock/connect the read surface too
+ r->ctx = ctx;
+ r->bindReadSurface(gl);
+ }
+ } else {
+ // if surfaces were bound to the context bound to this thread
+ // mark then as unbound.
+ if (current_ctx) {
+ egl_context_t* c = egl_context_t::context(current_ctx);
+ egl_surface_t* d = (egl_surface_t*)c->draw;
+ egl_surface_t* r = (egl_surface_t*)c->read;
+ if (d) {
+ c->draw = 0;
+ d->ctx = EGL_NO_CONTEXT;
+ d->disconnect();
+ }
+ if (r) {
+ c->read = 0;
+ r->ctx = EGL_NO_CONTEXT;
+ // FIXME: unlock/disconnect the read surface too
+ }
+ }
+ }
+ return EGL_TRUE;
+ }
+ return setError(EGL_BAD_ACCESS, EGL_FALSE);
+}
+
+EGLContext eglGetCurrentContext(void)
+{
+ // eglGetCurrentContext returns the current EGL rendering context,
+ // as specified by eglMakeCurrent. If no context is current,
+ // EGL_NO_CONTEXT is returned.
+ return (EGLContext)getGlThreadSpecific();
+}
+
+EGLSurface eglGetCurrentSurface(EGLint readdraw)
+{
+ // eglGetCurrentSurface returns the read or draw surface attached
+ // to the current EGL rendering context, as specified by eglMakeCurrent.
+ // If no context is current, EGL_NO_SURFACE is returned.
+ EGLContext ctx = (EGLContext)getGlThreadSpecific();
+ if (ctx == EGL_NO_CONTEXT) return EGL_NO_SURFACE;
+ egl_context_t* c = egl_context_t::context(ctx);
+ if (readdraw == EGL_READ) {
+ return c->read;
+ } else if (readdraw == EGL_DRAW) {
+ return c->draw;
+ }
+ return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+}
+
+EGLDisplay eglGetCurrentDisplay(void)
+{
+ // eglGetCurrentDisplay returns the current EGL display connection
+ // for the current EGL rendering context, as specified by eglMakeCurrent.
+ // If no context is current, EGL_NO_DISPLAY is returned.
+ EGLContext ctx = (EGLContext)getGlThreadSpecific();
+ if (ctx == EGL_NO_CONTEXT) return EGL_NO_DISPLAY;
+ egl_context_t* c = egl_context_t::context(ctx);
+ return c->dpy;
+}
+
+EGLBoolean eglQueryContext( EGLDisplay dpy, EGLContext ctx,
+ EGLint attribute, EGLint *value)
+{
+ if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+ return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+ egl_context_t* c = egl_context_t::context(ctx);
+ switch (attribute) {
+ case EGL_CONFIG_ID:
+ // Returns the ID of the EGL frame buffer configuration with
+ // respect to which the context was created
+ return getConfigAttrib(dpy, c->config, EGL_CONFIG_ID, value);
+ }
+ return setError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+}
+
+EGLBoolean eglWaitGL(void)
+{
+ return EGL_TRUE;
+}
+
+EGLBoolean eglWaitNative(EGLint engine)
+{
+ return EGL_TRUE;
+}
+
+EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
+{
+ if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+ return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+ egl_surface_t* d = static_cast<egl_surface_t*>(draw);
+ if (!d->isValid())
+ return setError(EGL_BAD_SURFACE, EGL_FALSE);
+ if (d->dpy != dpy)
+ return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+ // post the surface
+ d->swapBuffers();
+
+ // if it's bound to a context, update the buffer
+ if (d->ctx != EGL_NO_CONTEXT) {
+ d->bindDrawSurface((GLES2Context*)d->ctx);
+ // if this surface is also the read surface of the context
+ // it is bound to, make sure to update the read buffer as well.
+ // The EGL spec is a little unclear about this.
+ egl_context_t* c = egl_context_t::context(d->ctx);
+ if (c->read == draw) {
+ d->bindReadSurface((GLES2Context*)d->ctx);
+ }
+ clock_t time = clock();
+ float elapsed = (float)(time - c->lastSwapTime) / CLOCKS_PER_SEC;
+ c->accumulateSeconds += elapsed;
+ c->frame++;
+// LOGD("agl2: eglSwapBuffers elapsed=%.2fms \n*", elapsed * 1000);
+ if (20 == c->frame) {
+ float avg = c->accumulateSeconds / c->frame;
+ LOGD("\n*\n* agl2: eglSwapBuffers %u frame avg fps=%.1f elapsed=%.2fms \n*",
+ c->frame, 1 / avg, avg * 1000);
+ c->frame = 0;
+ c->accumulateSeconds = 0;
+ }
+ c->lastSwapTime = time;
+ }
+
+ return EGL_TRUE;
+}
+
+EGLBoolean eglCopyBuffers( EGLDisplay dpy, EGLSurface surface,
+ NativePixmapType target)
+{
+ if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+ return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+ // TODO: eglCopyBuffers()
+ return EGL_FALSE;
+}
+
+EGLint eglGetError(void)
+{
+ return getError();
+}
+
+const char* eglQueryString(EGLDisplay dpy, EGLint name)
+{
+ if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+ return setError(EGL_BAD_DISPLAY, (const char*)0);
+
+ switch (name) {
+ case EGL_VENDOR:
+ return gVendorString;
+ case EGL_VERSION:
+ return gVersionString;
+ case EGL_EXTENSIONS:
+ return gExtensionsString;
+ case EGL_CLIENT_APIS:
+ return gClientApiString;
+ }
+ return setError(EGL_BAD_PARAMETER, (const char *)0);
+}
+
+// ----------------------------------------------------------------------------
+// EGL 1.1
+// ----------------------------------------------------------------------------
+
+EGLBoolean eglSurfaceAttrib(
+ EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
+{
+ if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+ return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+ // TODO: eglSurfaceAttrib()
+ return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+}
+
+EGLBoolean eglBindTexImage(
+ EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+ if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+ return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+ // TODO: eglBindTexImage()
+ return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+}
+
+EGLBoolean eglReleaseTexImage(
+ EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+ if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+ return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+ // TODO: eglReleaseTexImage()
+ return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+}
+
+EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval)
+{
+ if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+ return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+ // TODO: eglSwapInterval()
+ return EGL_TRUE;
+}
+
+// ----------------------------------------------------------------------------
+// EGL 1.2
+// ----------------------------------------------------------------------------
+
+EGLBoolean eglBindAPI(EGLenum api)
+{
+ if (api != EGL_OPENGL_ES_API)
+ return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+ return EGL_TRUE;
+}
+
+EGLenum eglQueryAPI(void)
+{
+ return EGL_OPENGL_ES_API;
+}
+
+EGLBoolean eglWaitClient(void)
+{
+ glFinish();
+ return EGL_TRUE;
+}
+
+EGLBoolean eglReleaseThread(void)
+{
+ // TODO: eglReleaseThread()
+ return EGL_TRUE;
+}
+
+EGLSurface eglCreatePbufferFromClientBuffer(
+ EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
+ EGLConfig config, const EGLint *attrib_list)
+{
+ if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+ return setError(EGL_BAD_DISPLAY, EGL_NO_SURFACE);
+ // TODO: eglCreatePbufferFromClientBuffer()
+ return setError(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
+}
+
+// ----------------------------------------------------------------------------
+// EGL_EGLEXT_VERSION 3
+// ----------------------------------------------------------------------------
+
+void (*eglGetProcAddress (const char *procname))()
+{
+ extention_map_t const * const map = gExtentionMap;
+ for (uint32_t i=0 ; i<NELEM(gExtentionMap) ; i++) {
+ if (!strcmp(procname, map[i].name)) {
+ return map[i].address;
+ }
+ }
+ return NULL;
+}
+
+EGLBoolean eglLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface,
+ const EGLint *attrib_list)
+{
+ EGLBoolean result = EGL_FALSE;
+ return result;
+}
+
+EGLBoolean eglUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface)
+{
+ EGLBoolean result = EGL_FALSE;
+ return result;
+}
+
+EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
+ EGLClientBuffer buffer, const EGLint *attrib_list)
+{
+ if (egl_display_t::is_valid(dpy) == EGL_FALSE) {
+ return setError(EGL_BAD_DISPLAY, EGL_NO_IMAGE_KHR);
+ }
+ if (ctx != EGL_NO_CONTEXT) {
+ return setError(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
+ }
+ if (target != EGL_NATIVE_BUFFER_ANDROID) {
+ return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
+ }
+
+ android_native_buffer_t* native_buffer = (android_native_buffer_t*)buffer;
+
+ if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
+ return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
+
+ if (native_buffer->common.version != sizeof(android_native_buffer_t))
+ return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
+
+ switch (native_buffer->format) {
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ case HAL_PIXEL_FORMAT_RGB_888:
+ case HAL_PIXEL_FORMAT_RGB_565:
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ case HAL_PIXEL_FORMAT_RGBA_5551:
+ case HAL_PIXEL_FORMAT_RGBA_4444:
+ break;
+ default:
+ return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
+ }
+
+ native_buffer->common.incRef(&native_buffer->common);
+ return (EGLImageKHR)native_buffer;
+}
+
+EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img)
+{
+ if (egl_display_t::is_valid(dpy) == EGL_FALSE) {
+ return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+ }
+
+ android_native_buffer_t* native_buffer = (android_native_buffer_t*)img;
+
+ if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
+ return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+
+ if (native_buffer->common.version != sizeof(android_native_buffer_t))
+ return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+
+ native_buffer->common.decRef(&native_buffer->common);
+
+ return EGL_TRUE;
+}
+
+// ----------------------------------------------------------------------------
+// ANDROID extensions
+// ----------------------------------------------------------------------------
+
+EGLBoolean eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw,
+ EGLint left, EGLint top, EGLint width, EGLint height)
+{
+ if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+ return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+ egl_surface_t* d = static_cast<egl_surface_t*>(draw);
+ if (!d->isValid())
+ return setError(EGL_BAD_SURFACE, EGL_FALSE);
+ if (d->dpy != dpy)
+ return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+ // post the surface
+ d->setSwapRectangle(left, top, width, height);
+
+ return EGL_TRUE;
+}
diff --git a/opengl/libagl2/src/get.cpp b/opengl/libagl2/src/get.cpp
new file mode 100644
index 0000000..13c28ce
--- /dev/null
+++ b/opengl/libagl2/src/get.cpp
@@ -0,0 +1,79 @@
+#include "gles2context.h"
+
+static char const * const gVendorString = "Android";
+static char const * const gRendererString = "Android PixelFlinger2 0.0";
+static char const * const gVersionString = "OpenGL ES 2.0";
+static char const * const gExtensionsString =
+// "GL_OES_byte_coordinates " // OK
+// "GL_OES_fixed_point " // OK
+// "GL_OES_single_precision " // OK
+// "GL_OES_read_format " // OK
+// "GL_OES_compressed_paletted_texture " // OK
+// "GL_OES_draw_texture " // OK
+// "GL_OES_matrix_get " // OK
+// "GL_OES_query_matrix " // OK
+// // "GL_OES_point_size_array " // TODO
+// // "GL_OES_point_sprite " // TODO
+// "GL_OES_EGL_image " // OK
+//#ifdef GL_OES_compressed_ETC1_RGB8_texture
+// "GL_OES_compressed_ETC1_RGB8_texture " // OK
+//#endif
+// "GL_ARB_texture_compression " // OK
+// "GL_ARB_texture_non_power_of_two " // OK
+// "GL_ANDROID_user_clip_plane " // OK
+// "GL_ANDROID_vertex_buffer_object " // OK
+// "GL_ANDROID_generate_mipmap " // OK
+ ""
+ ;
+
+void glGetIntegerv(GLenum pname, GLint* params)
+{
+ switch (pname) {
+ case GL_MAX_TEXTURE_SIZE :
+ *params = 4096; // limit is in precision of texcoord calculation, which uses 16.16
+ break;
+ case GL_MAX_VERTEX_ATTRIBS:
+ *params = GGL_MAXVERTEXATTRIBS;
+ break;
+ case GL_MAX_VERTEX_UNIFORM_VECTORS:
+ *params = GGL_MAXVERTEXUNIFORMVECTORS;
+ break;
+ case GL_MAX_VARYING_VECTORS:
+ *params = GGL_MAXVARYINGVECTORS;
+ break;
+ case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
+ *params = GGL_MAXCOMBINEDTEXTUREIMAGEUNITS;
+ break;
+ case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
+ *params = GGL_MAXVERTEXTEXTUREIMAGEUNITS;
+ break;
+ case GL_MAX_TEXTURE_IMAGE_UNITS:
+ *params = GGL_MAXTEXTUREIMAGEUNITS;
+ break;
+ case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
+ *params = GGL_MAXFRAGMENTUNIFORMVECTORS;
+ break;
+ case GL_ALIASED_LINE_WIDTH_RANGE:
+ *params = 1; // TODO: not implemented
+ break;
+ default:
+ LOGD("agl2: glGetIntegerv 0x%.4X", pname);
+ assert(0);
+ }
+}
+
+const GLubyte* glGetString(GLenum name)
+{
+ switch (name) {
+ case GL_VENDOR:
+ return (const GLubyte*)gVendorString;
+ case GL_RENDERER:
+ return (const GLubyte*)gRendererString;
+ case GL_VERSION:
+ return (const GLubyte*)gVersionString;
+ case GL_EXTENSIONS:
+ return (const GLubyte*)gExtensionsString;
+ }
+ assert(0); //(c, GL_INVALID_ENUM);
+ return 0;
+}
diff --git a/opengl/libagl2/src/gles2context.h b/opengl/libagl2/src/gles2context.h
new file mode 100644
index 0000000..cec0340
--- /dev/null
+++ b/opengl/libagl2/src/gles2context.h
@@ -0,0 +1,166 @@
+#define _SIZE_T_DEFINED_
+typedef unsigned int size_t;
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+#include <utils/threads.h>
+#include <pthread.h>
+
+#include <cutils/log.h>
+
+#include <assert.h>
+
+#ifdef __arm__
+#ifndef __location__
+#define __HIERALLOC_STRING_0__(s) #s
+#define __HIERALLOC_STRING_1__(s) __HIERALLOC_STRING_0__(s)
+#define __HIERALLOC_STRING_2__ __HIERALLOC_STRING_1__(__LINE__)
+#define __location__ __FILE__ ":" __HIERALLOC_STRING_2__
+#endif
+#undef assert
+#define assert(EXPR) { do { if (!(EXPR)) {LOGD("\n*\n*\n*\n* assert fail: '"#EXPR"' at "__location__"\n*\n*\n*\n*"); exit(EXIT_FAILURE); } } while (false); }
+//#define printf LOGD
+#else // #ifdef __arm__
+//#define LOGD printf
+#endif // #ifdef __arm__
+
+
+#include <pixelflinger2/pixelflinger2_format.h>
+#include <pixelflinger2/pixelflinger2.h>
+
+#include <map>
+
+typedef uint8_t GGLubyte; // ub
+
+#define ggl_likely(x) __builtin_expect(!!(x), 1)
+#define ggl_unlikely(x) __builtin_expect(!!(x), 0)
+
+#undef NELEM
+#define NELEM(x) (sizeof(x)/sizeof(*(x)))
+
+template<typename T>
+inline T max(T a, T b)
+{
+ return a<b ? b : a;
+}
+
+template<typename T>
+inline T min(T a, T b)
+{
+ return a<b ? a : b;
+}
+
+struct egl_context_t {
+ enum {
+ IS_CURRENT = 0x00010000,
+ NEVER_CURRENT = 0x00020000
+ };
+ uint32_t flags;
+ EGLDisplay dpy;
+ EGLConfig config;
+ EGLSurface read;
+ EGLSurface draw;
+
+ unsigned frame;
+ clock_t lastSwapTime;
+ float accumulateSeconds;
+
+ static inline egl_context_t* context(EGLContext ctx);
+};
+
+struct GLES2Context;
+
+#ifdef HAVE_ANDROID_OS
+#include <bionic_tls.h>
+// We have a dedicated TLS slot in bionic
+inline void setGlThreadSpecific(GLES2Context *value)
+{
+ ((uint32_t *)__get_tls())[TLS_SLOT_OPENGL] = (uint32_t)value;
+}
+inline GLES2Context* getGlThreadSpecific()
+{
+ return (GLES2Context *)(((unsigned *)__get_tls())[TLS_SLOT_OPENGL]);
+}
+#else
+extern pthread_key_t gGLKey;
+inline void setGlThreadSpecific(GLES2Context *value)
+{
+ pthread_setspecific(gGLKey, value);
+}
+inline GLES2Context* getGlThreadSpecific()
+{
+ return static_cast<GLES2Context*>(pthread_getspecific(gGLKey));
+}
+#endif
+
+struct VBO {
+ unsigned size;
+ GLenum usage;
+ void * data;
+};
+
+struct GLES2Context {
+ GGLContext rasterizer;
+ egl_context_t egl;
+ GGLInterface * iface; // shortcut to &rasterizer.interface
+
+ struct VertexState {
+ struct VertAttribPointer {
+ unsigned size; // number of values per vertex
+ GLenum type; // data type
+ unsigned stride; // bytes
+ const void * ptr;
+bool normalized :
+ 1;
+bool enabled :
+ 1;
+ } attribs [GGL_MAXVERTEXATTRIBS];
+
+ VBO * vbo, * indices;
+ std::map<GLuint, VBO *> vbos;
+ GLuint free;
+
+ Vector4 defaultAttribs [GGL_MAXVERTEXATTRIBS];
+ } vert;
+
+ struct TextureState {
+ GGLTexture * tmus[GGL_MAXCOMBINEDTEXTUREIMAGEUNITS];
+ int sampler2tmu[GGL_MAXCOMBINEDTEXTUREIMAGEUNITS]; // sampler2tmu[sampler] is index of tmu, -1 means not used
+ unsigned active;
+ std::map<GLuint, GGLTexture *> textures;
+ GLuint free; // first possible free name
+ GGLTexture * tex2D, * texCube; // default textures
+ unsigned unpack;
+
+ void UpdateSampler(GGLInterface * iface, unsigned tmu);
+ } tex;
+
+ GLES2Context();
+ void InitializeTextures();
+ void InitializeVertices();
+
+ ~GLES2Context();
+ void UninitializeTextures();
+ void UninitializeVertices();
+
+ static inline GLES2Context* get() {
+ return getGlThreadSpecific();
+ }
+};
+
+inline egl_context_t* egl_context_t::context(EGLContext ctx)
+{
+ GLES2Context* const gl = static_cast<GLES2Context*>(ctx);
+ return static_cast<egl_context_t*>(&gl->egl);
+}
+
+#define GLES2_GET_CONTEXT(ctx) GLES2Context * ctx = GLES2Context::get(); \
+ /*puts(__FUNCTION__);*/
+#define GLES2_GET_CONST_CONTEXT(ctx) GLES2Context * ctx = GLES2Context::get(); \
+ /*puts(__FUNCTION__);*/
diff --git a/opengl/libagl2/src/shader.cpp b/opengl/libagl2/src/shader.cpp
new file mode 100644
index 0000000..076e388
--- /dev/null
+++ b/opengl/libagl2/src/shader.cpp
@@ -0,0 +1,191 @@
+#include "gles2context.h"
+
+//#undef LOGD
+//#define LOGD(...)
+
+static inline GLuint s2n(gl_shader * s)
+{
+ return (GLuint)s ^ 0xaf3c532d;
+}
+
+static inline gl_shader * n2s(GLuint n)
+{
+ return (gl_shader *)(n ^ 0xaf3c532d);
+}
+
+static inline GLuint p2n(gl_shader_program * p)
+{
+ return (GLuint)p ^ 0x04dc18f9;
+}
+
+static inline gl_shader_program * n2p(GLuint n)
+{
+ return (gl_shader_program *)(n ^ 0x04dc18f9);
+}
+
+void glAttachShader(GLuint program, GLuint shader)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ ctx->iface->ShaderAttach(ctx->iface, n2p(program), n2s(shader));
+}
+
+void glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ ctx->iface->ShaderAttributeBind(n2p(program), index, name);
+// assert(0);
+}
+
+GLuint glCreateShader(GLenum type)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ return s2n(ctx->iface->ShaderCreate(ctx->iface, type));
+}
+
+GLuint glCreateProgram(void)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ return p2n(ctx->iface->ShaderProgramCreate(ctx->iface));
+}
+
+void glCompileShader(GLuint shader)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ ctx->iface->ShaderCompile(ctx->iface, n2s(shader), NULL, NULL);
+}
+
+void glDeleteProgram(GLuint program)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ ctx->iface->ShaderProgramDelete(ctx->iface, n2p(program));
+}
+
+void glDeleteShader(GLuint shader)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ ctx->iface->ShaderDelete(ctx->iface, n2s(shader));
+}
+
+void glDetachShader(GLuint program, GLuint shader)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ ctx->iface->ShaderDetach(ctx->iface, n2p(program), n2s(shader));
+}
+
+GLint glGetAttribLocation(GLuint program, const GLchar* name)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ GLint location = ctx->iface->ShaderAttributeLocation(n2p(program), name);
+// LOGD("\n*\n*\n* agl2: glGetAttribLocation program=%u name=%s location=%d \n*\n*",
+// program, name, location);
+ return location;
+}
+
+void glGetProgramiv(GLuint program, GLenum pname, GLint* params)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ ctx->iface->ShaderProgramGetiv(n2p(program), pname, params);
+ LOGD("agl2: glGetProgramiv 0x%.4X=%d \n", pname, *params);
+}
+
+void glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ ctx->iface->ShaderProgramGetInfoLog(n2p(program), bufsize, length, infolog);
+}
+
+void glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ ctx->iface->ShaderGetiv(n2s(shader), pname, params);
+ LOGD("agl2: glGetShaderiv 0x%.4X=%d \n", pname, *params);
+}
+
+void glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ ctx->iface->ShaderGetInfoLog(n2s(shader), bufsize, length, infolog);
+}
+
+int glGetUniformLocation(GLuint program, const GLchar* name)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ return ctx->iface->ShaderUniformLocation(n2p(program), name);
+}
+
+void glLinkProgram(GLuint program)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ GLboolean linked = ctx->iface->ShaderProgramLink(n2p(program), NULL);
+ assert(linked);
+}
+
+void glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ ctx->iface->ShaderSource(n2s(shader), count, string, length);
+}
+
+void glUniform1f(GLint location, GLfloat x)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ int sampler = ctx->iface->ShaderUniform(ctx->rasterizer.CurrentProgram, location, 1, &x, GL_FLOAT);
+ assert(0 > sampler); // should be assigning to sampler
+}
+
+void glUniform1i(GLint location, GLint x)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ const float params[1] = {x};
+ int sampler = ctx->iface->ShaderUniform(ctx->rasterizer.CurrentProgram, location, 1, params, GL_INT);
+ if (0 <= sampler) {
+// LOGD("\n*\n* agl2: glUniform1i updated sampler=%d tmu=%d location=%d\n*", sampler, x, location);
+ assert(0 <= x && GGL_MAXCOMBINEDTEXTUREIMAGEUNITS > x);
+// LOGD("tmu%u: format=0x%.2X w=%u h=%u levels=%p", x, ctx->tex.tmus[x]->format,
+// ctx->tex.tmus[x]->width, ctx->tex.tmus[x]->height, ctx->tex.tmus[x]->format);
+ ctx->tex.sampler2tmu[sampler] = x;
+ ctx->tex.UpdateSampler(ctx->iface, x);
+ }
+}
+
+void glUniform2f(GLint location, GLfloat x, GLfloat y)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ const float params[4] = {x, y};
+ ctx->iface->ShaderUniform(ctx->rasterizer.CurrentProgram, location, 1, params, GL_FLOAT_VEC2);
+}
+
+void glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ const float params[4] = {x, y, z, w};
+// LOGD("agl2: glUniform4f location=%d %f,%f,%f,%f", location, x, y, z, w);
+ ctx->iface->ShaderUniform(ctx->rasterizer.CurrentProgram, location, 1, params, GL_FLOAT_VEC4);
+}
+
+void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+// const gl_shader_program * program = ctx->rasterizer.CurrentProgram;
+// if (strstr(program->Shaders[MESA_SHADER_FRAGMENT]->Source, ").a;")) {
+// LOGD("agl2: glUniformMatrix4fv location=%d count=%d transpose=%d", location, count, transpose);
+// for (unsigned i = 0; i < 4; i++)
+// LOGD("agl2: glUniformMatrix4fv %.2f \t %.2f \t %.2f \t %.2f", value[i * 4 + 0],
+// value[i * 4 + 1], value[i * 4 + 2], value[i * 4 + 3]);
+// }
+ ctx->iface->ShaderUniformMatrix(ctx->rasterizer.CurrentProgram, 4, 4, location, count, transpose, value);
+// while (true)
+// ;
+// assert(0);
+}
+
+void glUseProgram(GLuint program)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+// LOGD("\n*\n*\n* agl2: glUseProgram %d \n*\n*\n*", program);
+ ctx->iface->ShaderUse(ctx->iface, n2p(program));
+ ctx->iface->ShaderUniformGetSamplers(n2p(program), ctx->tex.sampler2tmu);
+ for (unsigned i = 0; i < GGL_MAXCOMBINEDTEXTUREIMAGEUNITS; i++)
+ if (0 <= ctx->tex.sampler2tmu[i])
+ ctx->iface->SetSampler(ctx->iface, i, ctx->tex.tmus[ctx->tex.sampler2tmu[i]]);
+}
diff --git a/opengl/libagl2/src/state.cpp b/opengl/libagl2/src/state.cpp
new file mode 100644
index 0000000..22e73fa
--- /dev/null
+++ b/opengl/libagl2/src/state.cpp
@@ -0,0 +1,129 @@
+#include "gles2context.h"
+
+GLES2Context::GLES2Context()
+{
+ memset(this, 0, sizeof *this);
+
+ assert((void *)&rasterizer == &rasterizer.interface);
+ InitializeGGLState(&rasterizer.interface);
+ iface = &rasterizer.interface;
+ printf("gl->rasterizer.PickScanLine(%p) = %p \n", &rasterizer.PickScanLine, rasterizer.PickScanLine);
+ assert(rasterizer.PickRaster);
+ assert(rasterizer.PickScanLine);
+
+ InitializeTextures();
+ InitializeVertices();
+}
+
+GLES2Context::~GLES2Context()
+{
+ UninitializeTextures();
+ UninitializeVertices();
+ UninitializeGGLState(&rasterizer.interface);
+}
+
+void glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ ctx->iface->BlendColor(ctx->iface, red, green, blue, alpha);
+}
+
+void glBlendEquation( GLenum mode )
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ ctx->iface->BlendEquationSeparate(ctx->iface, mode, mode);
+}
+
+void glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ ctx->iface->BlendEquationSeparate(ctx->iface, modeRGB, modeAlpha);
+}
+
+void glBlendFunc(GLenum sfactor, GLenum dfactor)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ ctx->iface->BlendFuncSeparate(ctx->iface, sfactor, dfactor, sfactor, dfactor);
+}
+
+void glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ ctx->iface->BlendFuncSeparate(ctx->iface, srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+
+void glClear(GLbitfield mask)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ ctx->iface->Clear(ctx->iface, mask);
+}
+
+void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ ctx->iface->ClearColor(ctx->iface, red, green, blue, alpha);
+}
+
+void glClearDepthf(GLclampf depth)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ ctx->iface->ClearDepthf(ctx->iface, depth);
+}
+
+void glClearStencil(GLint s)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ ctx->iface->ClearStencil(ctx->iface, s);
+}
+
+void glCullFace(GLenum mode)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ ctx->iface->CullFace(ctx->iface, mode);
+}
+
+void glDisable(GLenum cap)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ ctx->iface->EnableDisable(ctx->iface, cap, false);
+}
+
+void glEnable(GLenum cap)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ ctx->iface->EnableDisable(ctx->iface, cap, true);
+}
+
+void glFinish(void)
+{
+ // do nothing
+}
+
+void glFrontFace(GLenum mode)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ ctx->iface->FrontFace(ctx->iface, mode);
+}
+
+void glFlush(void)
+{
+ // do nothing
+}
+
+void glHint(GLenum target, GLenum mode)
+{
+ // do nothing
+}
+
+void glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+// LOGD("agl2: glScissor not implemented x=%d y=%d width=%d height=%d", x, y, width, height);
+ //CALL_GL_API(glScissor, x, y, width, height);
+}
+
+void glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+// LOGD("agl2: glViewport x=%d y=%d width=%d height=%d", x, y, width, height);
+ ctx->iface->Viewport(ctx->iface, x, y, width, height);
+}
diff --git a/opengl/libagl2/src/texture.cpp b/opengl/libagl2/src/texture.cpp
new file mode 100644
index 0000000..4de1f16
--- /dev/null
+++ b/opengl/libagl2/src/texture.cpp
@@ -0,0 +1,534 @@
+#include "gles2context.h"
+
+//#undef LOGD
+//#define LOGD(...)
+
+#define API_ENTRY
+#define CALL_GL_API(NAME,...) LOGD("?"#NAME); assert(0);
+#define CALL_GL_API_RETURN(NAME,...) LOGD("?"#NAME); assert(0); return 0;
+
+static inline GGLTexture * AllocTexture()
+{
+ GGLTexture * tex = (GGLTexture *)calloc(1, sizeof(GGLTexture));
+ tex->minFilter = GGLTexture::GGL_LINEAR; // should be NEAREST_ MIPMAP_LINEAR
+ tex->magFilter = GGLTexture::GGL_LINEAR;
+ return tex;
+}
+
+void GLES2Context::InitializeTextures()
+{
+ tex.textures = std::map<GLuint, GGLTexture *>(); // the entire struct has been zeroed in constructor
+ tex.tex2D = AllocTexture();
+ tex.textures[GL_TEXTURE_2D] = tex.tex2D;
+ tex.texCube = AllocTexture();
+ tex.textures[GL_TEXTURE_CUBE_MAP] = tex.texCube;
+ for (unsigned i = 0; i < GGL_MAXCOMBINEDTEXTUREIMAGEUNITS; i++) {
+ tex.tmus[i] = NULL;
+ tex.sampler2tmu[i] = NULL;
+ }
+
+ tex.active = 0;
+
+ tex.free = max(GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP) + 1;
+
+ tex.tex2D->format = GGL_PIXEL_FORMAT_RGBA_8888;
+ tex.tex2D->type = GL_TEXTURE_2D;
+ tex.tex2D->levelCount = 1;
+ tex.tex2D->wrapS = tex.tex2D->wrapT = GGLTexture::GGL_REPEAT;
+ tex.tex2D->minFilter = tex.tex2D->magFilter = GGLTexture::GGL_NEAREST;
+ tex.tex2D->width = tex.tex2D->height = 1;
+ tex.tex2D->levels = malloc(4);
+ *(unsigned *)tex.tex2D->levels = 0xff000000;
+
+
+ tex.texCube->format = GGL_PIXEL_FORMAT_RGBA_8888;
+ tex.texCube->type = GL_TEXTURE_CUBE_MAP;
+ tex.texCube->levelCount = 1;
+ tex.texCube->wrapS = tex.texCube->wrapT = GGLTexture::GGL_REPEAT;
+ tex.texCube->minFilter = tex.texCube->magFilter = GGLTexture::GGL_NEAREST;
+ tex.texCube->width = tex.texCube->height = 1;
+ tex.texCube->levels = malloc(4 * 6);
+ static unsigned texels [6] = {0xff0000ff, 0xff00ff00, 0xffff0000,
+ 0xff00ffff, 0xffffff00, 0xffff00ff
+ };
+ memcpy(tex.texCube->levels, texels, sizeof texels);
+
+ //texture.levelCount = GenerateMipmaps(texture.levels, texture.width, texture.height);
+
+ // static unsigned texels [6] = {0xff0000ff, 0xff00ff00, 0xffff0000,
+ // 0xff00ffff, 0xffffff00, 0xffff00ff};
+ // memcpy(texture.levels[0], texels, sizeof texels);
+ // texture.format = GGL_PIXEL_FORMAT_RGBA_8888;
+ // texture.width = texture.height = 1;
+ //texture.height /= 6;
+ //texture.type = GL_TEXTURE_CUBE_MAP;
+
+ tex.unpack = 4;
+}
+
+void GLES2Context::TextureState::UpdateSampler(GGLInterface * iface, unsigned tmu)
+{
+ for (unsigned i = 0; i < GGL_MAXCOMBINEDTEXTUREIMAGEUNITS; i++)
+ if (tmu == sampler2tmu[i])
+ iface->SetSampler(iface, i, tmus[tmu]);
+}
+
+void GLES2Context::UninitializeTextures()
+{
+ for (std::map<GLuint, GGLTexture *>::iterator it = tex.textures.begin(); it != tex.textures.end(); it++) {
+ if (!it->second)
+ continue;
+ free(it->second->levels);
+ free(it->second);
+ }
+}
+
+static inline void GetFormatAndBytesPerPixel(const GLenum format, unsigned * bytesPerPixel,
+ GGLPixelFormat * texFormat)
+{
+ switch (format) {
+ case GL_ALPHA:
+ *texFormat = GGL_PIXEL_FORMAT_A_8;
+ *bytesPerPixel = 1;
+ break;
+ case GL_LUMINANCE:
+ *texFormat = GGL_PIXEL_FORMAT_L_8;
+ *bytesPerPixel = 1;
+ break;
+ case GL_LUMINANCE_ALPHA:
+ *texFormat = GGL_PIXEL_FORMAT_LA_88;
+ *bytesPerPixel = 2;
+ break;
+ case GL_RGB:
+ *texFormat = GGL_PIXEL_FORMAT_RGB_888;
+ *bytesPerPixel = 3;
+ break;
+ case GL_RGBA:
+ *texFormat = GGL_PIXEL_FORMAT_RGBA_8888;
+ *bytesPerPixel = 4;
+ break;
+
+ // internal formats to avoid conversion
+ case GL_UNSIGNED_SHORT_5_6_5:
+ *texFormat = GGL_PIXEL_FORMAT_RGB_565;
+ *bytesPerPixel = 2;
+ break;
+
+ default:
+ assert(0);
+ return;
+ }
+}
+
+static inline void CopyTexture(char * dst, const char * src, const unsigned bytesPerPixel,
+ const unsigned sx, const unsigned sy, const unsigned sw,
+ const unsigned dx, const unsigned dy, const unsigned dw,
+ const unsigned w, const unsigned h)
+{
+ const unsigned bpp = bytesPerPixel;
+ if (dw == sw && dw == w && sx == 0 && dx == 0)
+ memcpy(dst + dy * dw * bpp, src + sy * sw * bpp, w * h * bpp);
+ else
+ for (unsigned y = 0; y < h; y++)
+ memcpy(dst + ((dy + y) * dw + dx) * bpp, src + ((sy + y) * sw + sx) * bpp, w * bpp);
+}
+
+void glActiveTexture(GLenum texture)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ unsigned index = texture - GL_TEXTURE0;
+ assert(NELEM(ctx->tex.tmus) > index);
+// LOGD("agl2: glActiveTexture %u", index);
+ ctx->tex.active = index;
+}
+
+void glBindTexture(GLenum target, GLuint texture)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+// LOGD("agl2: glBindTexture target=0x%.4X texture=%u active=%u", target, texture, ctx->tex.active);
+ std::map<GLuint, GGLTexture *>::iterator it = ctx->tex.textures.find(texture);
+ GGLTexture * tex = NULL;
+ if (it != ctx->tex.textures.end()) {
+ tex = it->second;
+ if (!tex) {
+ tex = AllocTexture();
+ tex->type = target;
+ it->second = tex;
+// LOGD("agl2: glBindTexture allocTexture");
+ }
+// else
+// LOGD("agl2: glBindTexture bind existing texture");
+ assert(target == tex->type);
+ } else if (0 == texture) {
+ if (GL_TEXTURE_2D == target)
+ {
+ tex = ctx->tex.tex2D;
+// LOGD("agl2: glBindTexture bind default tex2D");
+ }
+ else if (GL_TEXTURE_CUBE_MAP == target)
+ {
+ tex = ctx->tex.texCube;
+// LOGD("agl2: glBindTexture bind default texCube");
+ }
+ else
+ assert(0);
+ } else {
+ if (texture <= ctx->tex.free)
+ ctx->tex.free = texture + 1;
+ tex = AllocTexture();
+ tex->type = target;
+ ctx->tex.textures[texture] = tex;
+// LOGD("agl2: glBindTexture new texture=%u", texture);
+ }
+ ctx->tex.tmus[ctx->tex.active] = tex;
+// LOGD("agl2: glBindTexture format=0x%.2X w=%u h=%u levels=%p", tex->format,
+// tex->width, tex->height, tex->levels);
+ ctx->tex.UpdateSampler(ctx->iface, ctx->tex.active);
+}
+
+void API_ENTRY(glCompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data)
+{
+ CALL_GL_API(glCompressedTexImage2D, target, level, internalformat, width, height, border, imageSize, data);
+}
+
+void API_ENTRY(glCompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data)
+{
+ CALL_GL_API(glCompressedTexSubImage2D, target, level, xoffset, yoffset, width, height, format, imageSize, data);
+}
+
+void glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+// LOGD("agl2: glCopyTexImage2D target=0x%.4X internalformat=0x%.4X", target, internalformat);
+// LOGD("x=%d y=%d width=%d height=%d border=%d level=%d ", x, y, width, height, border, level);
+ assert(0 == border);
+ assert(0 == level);
+ unsigned bytesPerPixel = 0;
+ GGLPixelFormat texFormat = GGL_PIXEL_FORMAT_UNKNOWN;
+ GetFormatAndBytesPerPixel(internalformat, &bytesPerPixel, &texFormat);
+
+ assert(texFormat == ctx->rasterizer.frameSurface.format);
+// LOGD("texFormat=0x%.2X bytesPerPixel=%d \n", texFormat, bytesPerPixel);
+ unsigned offset = 0, size = width * height * bytesPerPixel, totalSize = size;
+
+ assert(ctx->tex.tmus[ctx->tex.active]);
+ assert(y + height <= ctx->rasterizer.frameSurface.height);
+ assert(x + width <= ctx->rasterizer.frameSurface.width);
+ GGLTexture & tex = *ctx->tex.tmus[ctx->tex.active];
+ tex.width = width;
+ tex.height = height;
+ tex.levelCount = 1;
+ tex.format = texFormat;
+ switch (target) {
+ case GL_TEXTURE_2D:
+ tex.levels = realloc(tex.levels, totalSize);
+ CopyTexture((char *)tex.levels, (const char *)ctx->rasterizer.frameSurface.data, bytesPerPixel,
+ x, y, ctx->rasterizer.frameSurface.width, 0, 0, width, width, height);
+ break;
+ default:
+ assert(0);
+ return;
+ }
+ ctx->tex.UpdateSampler(ctx->iface, ctx->tex.active);
+}
+
+void glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ // x, y are src offset
+ // xoffset and yoffset are dst offset
+ GLES2_GET_CONST_CONTEXT(ctx);
+// LOGD("agl2: glCopyTexSubImage2D target=0x%.4X level=%d", target, level);
+// LOGD("xoffset=%d yoffset=%d x=%d y=%d width=%d height=%d", xoffset, yoffset, x, y, width, height);
+ assert(0 == level);
+
+ unsigned bytesPerPixel = 4;
+ unsigned offset = 0, size = width * height * bytesPerPixel, totalSize = size;
+
+ assert(ctx->tex.tmus[ctx->tex.active]);
+ GGLTexture & tex = *ctx->tex.tmus[ctx->tex.active];
+
+ assert(tex.format == ctx->rasterizer.frameSurface.format);
+ assert(GGL_PIXEL_FORMAT_RGBA_8888 == tex.format);
+
+ const unsigned srcWidth = ctx->rasterizer.frameSurface.width;
+ const unsigned srcHeight = ctx->rasterizer.frameSurface.height;
+
+ assert(x >= 0 && y >= 0);
+ assert(xoffset >= 0 && yoffset >= 0);
+ assert(x + width <= srcWidth);
+ assert(y + height <= srcHeight);
+ assert(xoffset + width <= tex.width);
+ assert(yoffset + height <= tex.height);
+
+ switch (target) {
+ case GL_TEXTURE_2D:
+ CopyTexture((char *)tex.levels, (const char *)ctx->rasterizer.frameSurface.data, bytesPerPixel,
+ x, y, srcWidth, xoffset, yoffset, tex.width, width, height);
+ break;
+ default:
+ assert(0);
+ return;
+ }
+ ctx->tex.UpdateSampler(ctx->iface, ctx->tex.active);
+}
+
+void glDeleteTextures(GLsizei n, const GLuint* textures)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ for (unsigned i = 0; i < n; i++) {
+ std::map<GLuint, GGLTexture *>::iterator it = ctx->tex.textures.find(textures[i]);
+ if (it == ctx->tex.textures.end())
+ continue;
+ ctx->tex.free = min(ctx->tex.free, textures[i]);
+ for (unsigned i = 0; i < GGL_MAXCOMBINEDTEXTUREIMAGEUNITS; i++)
+ if (ctx->tex.tmus[i] == it->second) {
+ if (GL_TEXTURE_2D == it->second->type)
+ ctx->tex.tmus[i] = ctx->tex.tex2D;
+ else if (GL_TEXTURE_CUBE_MAP == it->second->type)
+ ctx->tex.tmus[i] = ctx->tex.texCube;
+ else
+ assert(0);
+ ctx->tex.UpdateSampler(ctx->iface, i);
+ }
+ if (it->second) {
+ free(it->second->levels);
+ free(it->second);
+ }
+ ctx->tex.textures.erase(it);
+ }
+}
+
+void glGenTextures(GLsizei n, GLuint* textures)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ for (unsigned i = 0; i < n; i++) {
+ textures[i] = 0;
+ for (ctx->tex.free; ctx->tex.free < 0xffffffffu; ctx->tex.free++)
+ if (ctx->tex.textures.find(ctx->tex.free) == ctx->tex.textures.end()) {
+ ctx->tex.textures[ctx->tex.free] = NULL;
+ textures[i] = ctx->tex.free;
+ ctx->tex.free++;
+ break;
+ }
+ assert(textures[i]);
+ }
+}
+
+void API_ENTRY(glGetTexParameterfv)(GLenum target, GLenum pname, GLfloat* params)
+{
+ CALL_GL_API(glGetTexParameterfv, target, pname, params);
+}
+void API_ENTRY(glGetTexParameteriv)(GLenum target, GLenum pname, GLint* params)
+{
+ CALL_GL_API(glGetTexParameteriv, target, pname, params);
+}
+
+GLboolean glIsTexture(GLuint texture)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ if (ctx->tex.textures.find(texture) == ctx->tex.textures.end())
+ return GL_FALSE;
+ else
+ return GL_TRUE;
+}
+
+void glPixelStorei(GLenum pname, GLint param)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ assert(GL_UNPACK_ALIGNMENT == pname);
+ assert(1 == param || 2 == param || 4 == param || 8 == param);
+// LOGD("\n*\n* agl2: glPixelStorei not implemented pname=0x%.4X param=%d \n*", pname, param);
+ ctx->tex.unpack = param;
+// CALL_GL_API(glPixelStorei, pname, param);
+}
+void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width,
+ GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+// LOGD("agl2: glTexImage2D internalformat=0x%.4X format=0x%.4X type=0x%.4X \n", internalformat, format, type);
+// LOGD("width=%d height=%d border=%d level=%d pixels=%p \n", width, height, border, level, pixels);
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ break;
+ case GL_UNSIGNED_SHORT_5_6_5:
+ internalformat = format = GL_UNSIGNED_SHORT_5_6_5;
+ assert(4 == ctx->tex.unpack);
+ break;
+ default:
+ assert(0);
+ }
+ assert(internalformat == format);
+ assert(0 == border);
+ if (0 != level) {
+ LOGD("agl2: glTexImage2D level=%d", level);
+ return;
+ }
+ unsigned bytesPerPixel = 0;
+ GGLPixelFormat texFormat = GGL_PIXEL_FORMAT_UNKNOWN;
+ GetFormatAndBytesPerPixel(format, &bytesPerPixel, &texFormat);
+
+ assert(texFormat && bytesPerPixel);
+// LOGD("texFormat=0x%.2X bytesPerPixel=%d active=%u", texFormat, bytesPerPixel, ctx->tex.active);
+ unsigned offset = 0, size = width * height * bytesPerPixel, totalSize = size;
+
+ assert(ctx->tex.tmus[ctx->tex.active]);
+
+ GGLTexture & tex = *ctx->tex.tmus[ctx->tex.active];
+ tex.width = width;
+ tex.height = height;
+ tex.levelCount = 1;
+ tex.format = texFormat;
+
+ switch (target) {
+ case GL_TEXTURE_2D:
+ assert(GL_TEXTURE_2D == ctx->tex.tmus[ctx->tex.active]->type);
+ offset = 0;
+ break;
+ break;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ assert(GL_TEXTURE_CUBE_MAP == ctx->tex.tmus[ctx->tex.active]->type);
+ assert(width == height);
+ offset = (target - GL_TEXTURE_CUBE_MAP_POSITIVE_X) * size;
+ totalSize = 6 * size;
+ break;
+ default:
+ assert(0);
+ return;
+ }
+
+ tex.levels = realloc(tex.levels, totalSize);
+ if (pixels)
+ CopyTexture((char *)tex.levels, (const char *)pixels, bytesPerPixel, 0, 0, width, 0, 0, width, width, height);
+ ctx->tex.UpdateSampler(ctx->iface, ctx->tex.active);
+}
+
+void glTexParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+// LOGD("agl2: glTexParameterf target=0x%.4X pname=0x%.4X param=%f", target, pname, param);
+ glTexParameteri(target, pname, param);
+}
+void API_ENTRY(glTexParameterfv)(GLenum target, GLenum pname, const GLfloat* params)
+{
+ CALL_GL_API(glTexParameterfv, target, pname, params);
+}
+void glTexParameteri(GLenum target, GLenum pname, GLint param)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+// LOGD("alg2: glTexParameteri target=0x%.0X pname=0x%.4X param=0x%.4X",
+// target, pname, param);
+ assert(ctx->tex.tmus[ctx->tex.active]);
+ assert(target == ctx->tex.tmus[ctx->tex.active]->type);
+ GGLTexture & tex = *ctx->tex.tmus[ctx->tex.active];
+ switch (pname) {
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ GGLTexture::GGLTextureWrap wrap;
+ switch (param) {
+ case GL_REPEAT:
+ wrap = GGLTexture::GGL_REPEAT;
+ break;
+ case GL_CLAMP_TO_EDGE:
+ wrap = GGLTexture::GGL_CLAMP_TO_EDGE;
+ break;
+ case GL_MIRRORED_REPEAT:
+ wrap = GGLTexture::GGL_MIRRORED_REPEAT;
+ break;
+ default:
+ assert(0);
+ return;
+ }
+ if (GL_TEXTURE_WRAP_S == pname)
+ tex.wrapS = wrap;
+ else
+ tex.wrapT = wrap;
+ break;
+ case GL_TEXTURE_MIN_FILTER:
+ switch (param) {
+ case GL_NEAREST:
+ tex.minFilter = GGLTexture::GGL_NEAREST;
+ break;
+ case GL_LINEAR:
+ tex.minFilter = GGLTexture::GGL_LINEAR;
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+// tex.minFilter = GGLTexture::GGL_NEAREST_MIPMAP_NEAREST;
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+// tex.minFilter = GGLTexture::GGL_NEAREST_MIPMAP_LINEAR;
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+// tex.minFilter = GGLTexture::GGL_LINEAR_MIPMAP_NEAREST;
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+// tex.minFilter = GGLTexture::GGL_LINEAR_MIPMAP_LINEAR;
+ break;
+ default:
+ assert(0);
+ return;
+ }
+ break;
+ case GL_TEXTURE_MAG_FILTER:
+ switch (param) {
+ case GL_NEAREST:
+ tex.minFilter = GGLTexture::GGL_NEAREST;
+ break;
+ case GL_LINEAR:
+ tex.minFilter = GGLTexture::GGL_LINEAR;
+ break;
+ default:
+ assert(0);
+ return;
+ }
+ break;
+ default:
+ assert(0);
+ return;
+ }
+ // implementation restriction
+ if (tex.magFilter != tex.minFilter)
+ tex.magFilter = tex.minFilter = GGLTexture::GGL_LINEAR;
+ ctx->tex.UpdateSampler(ctx->iface, ctx->tex.active);
+}
+void API_ENTRY(glTexParameteriv)(GLenum target, GLenum pname, const GLint* params)
+{
+ CALL_GL_API(glTexParameteriv, target, pname, params);
+}
+void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+// LOGD("agl2: glTexSubImage2D target=0x%.4X level=%d xoffset=%d yoffset=%d width=%d height=%d format=0x%.4X type=0x%.4X pixels=%p",
+// target, level, xoffset, yoffset, width, height, format, type, pixels);
+ assert(0 == level);
+ assert(target == ctx->tex.tmus[ctx->tex.active]->type);
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ break;
+ case GL_UNSIGNED_SHORT_5_6_5:
+ format = GL_UNSIGNED_SHORT_5_6_5;
+ assert(4 == ctx->tex.unpack);
+ break;
+ default:
+ assert(0);
+ }
+ GGLTexture & tex = *ctx->tex.tmus[ctx->tex.active];
+ GGLPixelFormat texFormat = GGL_PIXEL_FORMAT_UNKNOWN;
+ unsigned bytesPerPixel = 0;
+ GetFormatAndBytesPerPixel(format, &bytesPerPixel, &texFormat);
+ assert(texFormat == tex.format);
+ assert(GL_UNSIGNED_BYTE == type);
+ switch (target) {
+ case GL_TEXTURE_2D:
+ CopyTexture((char *)tex.levels, (const char *)pixels, bytesPerPixel, 0, 0, width, xoffset,
+ yoffset, tex.width, width, height);
+ break;
+ default:
+ assert(0);
+ }
+ ctx->tex.UpdateSampler(ctx->iface, ctx->tex.active);
+}
diff --git a/opengl/libagl2/src/vertex.cpp b/opengl/libagl2/src/vertex.cpp
new file mode 100644
index 0000000..021b82b
--- /dev/null
+++ b/opengl/libagl2/src/vertex.cpp
@@ -0,0 +1,373 @@
+#include "gles2context.h"
+
+//#undef LOGD
+//#define LOGD(...)
+
+void GLES2Context::InitializeVertices()
+{
+ vert.vbos = std::map<GLuint, VBO *>(); // the entire struct has been zeroed in constructor
+ vert.free = 1;
+ vert.vbo = NULL;
+ vert.indices = NULL;
+ for (unsigned i = 0; i < GGL_MAXVERTEXATTRIBS; i++)
+ vert.defaultAttribs[i] = Vector4(0,0,0,1);
+}
+
+void GLES2Context::UninitializeVertices()
+{
+ for (std::map<GLuint, VBO *>::iterator it = vert.vbos.begin(); it != vert.vbos.end(); it++) {
+ if (!it->second)
+ continue;
+ free(it->second->data);
+ free(it->second);
+ }
+}
+
+static inline void FetchElement(const GLES2Context * ctx, const unsigned index,
+ const unsigned maxAttrib, VertexInput * elem)
+{
+ for (unsigned i = 0; i < maxAttrib; i++) {
+ {
+ unsigned size = 0;
+ if (ctx->vert.attribs[i].enabled) {
+ const char * ptr = (const char *)ctx->vert.attribs[i].ptr;
+ ptr += ctx->vert.attribs[i].stride * index;
+ memcpy(elem->attributes + i, ptr, ctx->vert.attribs[i].size * sizeof(float));
+ size = ctx->vert.attribs[i].size;
+// LOGD("agl2: FetchElement %d attribs size=%d %.2f,%.2f,%.2f,%.2f", i, size, elem->attributes[i].x,
+// elem->attributes[i].y, elem->attributes[i].z, elem->attributes[i].w);
+ } else {
+// LOGD("agl2: FetchElement %d default %.2f,%.2f,%.2f,%.2f", i, ctx->vert.defaultAttribs[i].x,
+// ctx->vert.defaultAttribs[i].y, ctx->vert.defaultAttribs[i].z, ctx->vert.defaultAttribs[i].w);
+ }
+
+ switch (size) {
+ case 0: // fall through
+ elem->attributes[i].x = ctx->vert.defaultAttribs[i].x;
+ case 1: // fall through
+ elem->attributes[i].y = ctx->vert.defaultAttribs[i].y;
+ case 2: // fall through
+ elem->attributes[i].z = ctx->vert.defaultAttribs[i].z;
+ case 3: // fall through
+ elem->attributes[i].w = ctx->vert.defaultAttribs[i].w;
+ case 4:
+ break;
+ default:
+ assert(0);
+ break;
+ }
+// LOGD("agl2: FetchElement %d size=%d %.2f,%.2f,%.2f,%.2f", i, size, elem->attributes[i].x,
+// elem->attributes[i].y, elem->attributes[i].z, elem->attributes[i].w);
+ }
+ }
+}
+
+template<typename IndexT> static void DrawElementsTriangles(const GLES2Context * ctx,
+ const unsigned count, const IndexT * indices, const unsigned maxAttrib)
+{
+ VertexInput v[3];
+ if (ctx->vert.indices)
+ indices = (IndexT *)((char *)ctx->vert.indices->data + (long)indices);
+ for (unsigned i = 0; i < count; i += 3) {
+ for (unsigned j = 0; j < 3; j++)
+ FetchElement(ctx, indices[i + j], maxAttrib, v + j);
+ ctx->iface->DrawTriangle(ctx->iface, v, v + 1, v + 2);
+ }
+}
+
+static void DrawArraysTriangles(const GLES2Context * ctx, const unsigned first,
+ const unsigned count, const unsigned maxAttrib)
+{
+// LOGD("agl: DrawArraysTriangles=%p", DrawArraysTriangles);
+ VertexInput v[3];
+ for (unsigned i = 2; i < count; i+=3) {
+ // TODO: fix order
+ FetchElement(ctx, first + i - 2, maxAttrib, v + 0);
+ FetchElement(ctx, first + i - 1, maxAttrib, v + 1);
+ FetchElement(ctx, first + i - 0, maxAttrib, v + 2);
+ ctx->iface->DrawTriangle(ctx->iface, v + 0, v + 1, v + 2);
+ }
+// LOGD("agl: DrawArraysTriangles end");
+}
+
+template<typename IndexT> static void DrawElementsTriangleStrip(const GLES2Context * ctx,
+ const unsigned count, const IndexT * indices, const unsigned maxAttrib)
+{
+ VertexInput v[3];
+ if (ctx->vert.indices)
+ indices = (IndexT *)((char *)ctx->vert.indices->data + (long)indices);
+
+// LOGD("agl2: DrawElementsTriangleStrip");
+// for (unsigned i = 0; i < count; i++)
+// LOGD("indices[%d] = %d", i, indices[i]);
+
+ FetchElement(ctx, indices[0], maxAttrib, v + 0);
+ FetchElement(ctx, indices[1], maxAttrib, v + 1);
+ for (unsigned i = 2; i < count; i ++) {
+ FetchElement(ctx, indices[i], maxAttrib, v + i % 3);
+ ctx->iface->DrawTriangle(ctx->iface, v + (i - 2) % 3, v + (i - 1) % 3 , v + (i + 0) % 3);
+ }
+
+// for (unsigned i = 2; i < count; i++) {
+// FetchElement(ctx, indices[i - 2], maxAttrib, v + 0);
+// FetchElement(ctx, indices[i - 1], maxAttrib, v + 1);
+// FetchElement(ctx, indices[i - 0], maxAttrib, v + 2);
+// ctx->iface->DrawTriangle(ctx->iface, v + 0, v + 1, v + 2);
+// }
+}
+
+static void DrawArraysTriangleStrip(const GLES2Context * ctx, const unsigned first,
+ const unsigned count, const unsigned maxAttrib)
+{
+ VertexInput v[3];
+ FetchElement(ctx, first, maxAttrib, v + 0);
+ FetchElement(ctx, first + 1, maxAttrib, v + 1);
+ for (unsigned i = 2; i < count; i++) {
+ // TODO: fix order
+ FetchElement(ctx, first + i, maxAttrib, v + i % 3);
+ ctx->iface->DrawTriangle(ctx->iface, v + (i - 2) % 3, v + (i - 1) % 3 , v + (i + 0) % 3);
+ }
+}
+
+void glBindBuffer(GLenum target, GLuint buffer)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ VBO * vbo = NULL;
+ if (0 != buffer) {
+ std::map<GLuint, VBO *>::iterator it = ctx->vert.vbos.find(buffer);
+ if (it != ctx->vert.vbos.end()) {
+ vbo = it->second;
+ if (!vbo)
+ vbo = (VBO *)calloc(1, sizeof(VBO));
+ it->second = vbo;
+ } else
+ assert(0);
+ }
+ if (GL_ARRAY_BUFFER == target)
+ ctx->vert.vbo = vbo;
+ else if (GL_ELEMENT_ARRAY_BUFFER == target)
+ ctx->vert.indices = vbo;
+ else
+ assert(0);
+ assert(vbo || buffer == 0);
+// LOGD("\n*\n glBindBuffer 0x%.4X=%d ", target, buffer);
+}
+
+void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ if (GL_ARRAY_BUFFER == target) {
+ assert(ctx->vert.vbo);
+ ctx->vert.vbo->data = realloc(ctx->vert.vbo->data, size);
+ ctx->vert.vbo->size = size;
+ ctx->vert.vbo->usage = usage;
+ if (data)
+ memcpy(ctx->vert.vbo->data, data, size);
+ } else if (GL_ELEMENT_ARRAY_BUFFER == target) {
+ assert(ctx->vert.indices);
+ ctx->vert.indices->data = realloc(ctx->vert.indices->data, size);
+ ctx->vert.indices->size = size;
+ ctx->vert.indices->usage = usage;
+ if (data)
+ memcpy(ctx->vert.indices->data, data, size);
+ } else
+ assert(0);
+// LOGD("\n*\n glBufferData target=0x%.4X size=%u data=%p usage=0x%.4X \n",
+// target, size, data, usage);
+}
+
+void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ if (GL_ARRAY_BUFFER == target)
+ {
+ assert(ctx->vert.vbo);
+ assert(0 <= offset);
+ assert(0 <= size);
+ assert(offset + size <= ctx->vert.vbo->size);
+ memcpy((char *)ctx->vert.vbo->data + offset, data, size);
+ }
+ else
+ assert(0);
+}
+
+void glDeleteBuffers(GLsizei n, const GLuint* buffers)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ for (unsigned i = 0; i < n; i++) {
+ std::map<GLuint, VBO*>::iterator it = ctx->vert.vbos.find(buffers[i]);
+ if (it == ctx->vert.vbos.end())
+ continue;
+ ctx->vert.free = min(ctx->vert.free, buffers[i]);
+ if (it->second == ctx->vert.vbo)
+ ctx->vert.vbo = NULL;
+ else if (it->second == ctx->vert.indices)
+ ctx->vert.indices = NULL;
+ if (it->second) {
+ free(it->second->data);
+ free(it->second);
+ }
+ }
+}
+
+void glDisableVertexAttribArray(GLuint index)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ assert(GGL_MAXVERTEXATTRIBS > index);
+ ctx->vert.attribs[index].enabled = false;
+}
+
+void glDrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+// LOGD("agl2: glDrawArrays=%p", glDrawArrays);
+ assert(ctx->rasterizer.CurrentProgram);
+ assert(0 <= first);
+ int maxAttrib = -1;
+ ctx->iface->ShaderProgramGetiv(ctx->rasterizer.CurrentProgram, GL_ACTIVE_ATTRIBUTES, &maxAttrib);
+ assert(0 <= maxAttrib && GGL_MAXVERTEXATTRIBS >= maxAttrib);
+ switch (mode) {
+ case GL_TRIANGLE_STRIP:
+ DrawArraysTriangleStrip(ctx, first, count, maxAttrib);
+ break;
+ case GL_TRIANGLES:
+ DrawArraysTriangles(ctx, first, count, maxAttrib);
+ break;
+ default:
+ LOGE("agl2: glDrawArrays unsupported mode: 0x%.4X \n", mode);
+ assert(0);
+ break;
+ }
+// LOGD("agl2: glDrawArrays end");
+}
+
+void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+// LOGD("agl2: glDrawElements=%p mode=0x%.4X count=%d type=0x%.4X indices=%p",
+// glDrawElements, mode, count, type, indices);
+ if (!ctx->rasterizer.CurrentProgram)
+ return;
+
+ int maxAttrib = -1;
+ ctx->iface->ShaderProgramGetiv(ctx->rasterizer.CurrentProgram, GL_ACTIVE_ATTRIBUTES, &maxAttrib);
+ assert(0 <= maxAttrib && GGL_MAXVERTEXATTRIBS >= maxAttrib);
+// LOGD("agl2: glDrawElements mode=0x%.4X type=0x%.4X count=%d program=%p indices=%p \n",
+// mode, type, count, ctx->rasterizer.CurrentProgram, indices);
+ switch (mode) {
+ case GL_TRIANGLES:
+ if (GL_UNSIGNED_SHORT == type)
+ DrawElementsTriangles<unsigned short>(ctx, count, (unsigned short *)indices, maxAttrib);
+ else
+ assert(0);
+ break;
+ case GL_TRIANGLE_STRIP:
+ if (GL_UNSIGNED_SHORT == type)
+ DrawElementsTriangleStrip<unsigned short>(ctx, count, (unsigned short *)indices, maxAttrib);
+ else
+ assert(0);
+ break;
+ default:
+ assert(0);
+ }
+// LOGD("agl2: glDrawElements end");
+}
+
+void glEnableVertexAttribArray(GLuint index)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ ctx->vert.attribs[index].enabled = true;
+// LOGD("agl2: glEnableVertexAttribArray %d \n", index);
+}
+
+void glGenBuffers(GLsizei n, GLuint* buffers)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ for (unsigned i = 0; i < n; i++) {
+ buffers[i] = 0;
+ for (ctx->vert.free; ctx->vert.free < 0xffffffffu; ctx->vert.free++) {
+ if (ctx->vert.vbos.find(ctx->vert.free) == ctx->vert.vbos.end()) {
+ ctx->vert.vbos[ctx->vert.free] = NULL;
+ buffers[i] = ctx->vert.free;
+// LOGD("glGenBuffers %d \n", buffers[i]);
+ ctx->vert.free++;
+ break;
+ }
+ }
+ assert(buffers[i]);
+ }
+}
+
+void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized,
+ GLsizei stride, const GLvoid* ptr)
+{
+ GLES2_GET_CONST_CONTEXT(ctx);
+ assert(GL_FLOAT == type);
+ assert(0 < size && 4 >= size);
+ ctx->vert.attribs[index].size = size;
+ ctx->vert.attribs[index].type = type;
+ ctx->vert.attribs[index].normalized = normalized;
+ if (0 == stride)
+ ctx->vert.attribs[index].stride = size * sizeof(float);
+ else if (stride > 0)
+ ctx->vert.attribs[index].stride = stride;
+ else
+ assert(0);
+// LOGD("\n*\n*\n* agl2: glVertexAttribPointer program=%u index=%d size=%d stride=%d ptr=%p \n*\n*",
+// unsigned(ctx->rasterizer.CurrentProgram) ^ 0x04dc18f9, index, size, stride, ptr);
+ if (ctx->vert.vbo)
+ ctx->vert.attribs[index].ptr = (char *)ctx->vert.vbo->data + (long)ptr;
+ else
+ ctx->vert.attribs[index].ptr = ptr;
+// const float * attrib = (const float *)ctx->vert.attribs[index].ptr;
+// for (unsigned i = 0; i < 3; i++)
+// if (3 == size)
+// LOGD("%.2f %.2f %.2f", attrib[i * 3 + 0], attrib[i * 3 + 1], attrib[i * 3 + 2]);
+// else if (2 == size)
+// LOGD("%.2f %.2f", attrib[i * 3 + 0], attrib[i * 3 + 1]);
+
+}
+
+void glVertexAttrib1f(GLuint indx, GLfloat x)
+{
+ glVertexAttrib4f(indx, x,0,0,1);
+}
+
+void glVertexAttrib1fv(GLuint indx, const GLfloat* values)
+{
+ glVertexAttrib4f(indx, values[0],0,0,1);
+}
+
+void glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
+{
+ glVertexAttrib4f(indx, x,y,0,1);
+}
+
+void glVertexAttrib2fv(GLuint indx, const GLfloat* values)
+{
+ glVertexAttrib4f(indx, values[0],values[1],0,1);
+}
+
+void glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
+{
+ glVertexAttrib4f(indx, x,y,z,1);
+}
+
+void glVertexAttrib3fv(GLuint indx, const GLfloat* values)
+{
+ glVertexAttrib4f(indx, values[0],values[1],values[2],1);
+}
+
+void glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ assert(GGL_MAXVERTEXATTRIBS > indx);
+ GLES2_GET_CONST_CONTEXT(ctx);
+// LOGD("\n*\n*\n agl2: glVertexAttrib4f %d %.2f,%.2f,%.2f,%.2f \n*\n*", indx, x, y, z, w);
+ ctx->vert.defaultAttribs[indx] = Vector4(x,y,z,w);
+ assert(0);
+}
+
+void glVertexAttrib4fv(GLuint indx, const GLfloat* values)
+{
+ glVertexAttrib4f(indx, values[0], values[1], values[2], values[3]);
+}
diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk
index c8041fc..123306b6 100644
--- a/opengl/libs/Android.mk
+++ b/opengl/libs/Android.mk
@@ -13,11 +13,11 @@
EGL/hooks.cpp \
EGL/Loader.cpp \
#
-
-LOCAL_SHARED_LIBRARIES += libcutils libutils
+LOCAL_STATIC_LIBRARIES += libGLESv2_dbg libprotobuf-cpp-2.3.0-lite
+LOCAL_SHARED_LIBRARIES += libcutils libutils libstlport
LOCAL_LDLIBS := -lpthread -ldl
LOCAL_MODULE:= libEGL
-
+LOCAL_LDFLAGS += -Wl,--exclude-libs=ALL
# needed on sim build because of weird logging issues
ifeq ($(TARGET_SIMULATOR),true)
else
@@ -164,3 +164,6 @@
LOCAL_MODULE:= libETC1
include $(BUILD_SHARED_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
+
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 747c829..2502f15 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -30,6 +30,7 @@
#include "egl_impl.h"
#include "Loader.h"
+#include "glesv2dbg.h"
// ----------------------------------------------------------------------------
namespace android {
@@ -114,6 +115,7 @@
Loader::~Loader()
{
+ StopDebugServer();
}
const char* Loader::getTag(int dpy, int impl)
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 3d5a4d1..861d7ac 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -45,6 +45,7 @@
#include "hooks.h"
#include "egl_impl.h"
#include "Loader.h"
+#include "glesv2dbg.h"
#define setError(_e, _r) setErrorEtc(__FUNCTION__, __LINE__, _e, _r)
@@ -223,9 +224,15 @@
egl_context_t(EGLDisplay dpy, EGLContext context, EGLConfig config,
int impl, egl_connection_t const* cnx, int version)
: dpy(dpy), context(context), config(config), read(0), draw(0), impl(impl),
- cnx(cnx), version(version)
+ cnx(cnx), version(version), dbg(NULL)
{
}
+ ~egl_context_t()
+ {
+ if (dbg)
+ DestroyDbgContext(dbg);
+ dbg = NULL;
+ }
EGLDisplay dpy;
EGLContext context;
EGLConfig config;
@@ -234,6 +241,7 @@
int impl;
egl_connection_t const* cnx;
int version;
+ DbgContext * dbg;
};
struct egl_image_t : public egl_object_t
@@ -296,9 +304,9 @@
// ----------------------------------------------------------------------------
-static int gEGLTraceLevel;
+static int gEGLTraceLevel, gEGLDebugLevel;
static int gEGLApplicationTraceLevel;
-extern EGLAPI gl_hooks_t gHooksTrace;
+extern EGLAPI gl_hooks_t gHooksTrace, gHooksDebug;
static inline void setGlTraceThreadSpecific(gl_hooks_t const *value) {
pthread_setspecific(gGLTraceKey, value);
@@ -314,12 +322,35 @@
int propertyLevel = atoi(value);
int applicationLevel = gEGLApplicationTraceLevel;
gEGLTraceLevel = propertyLevel > applicationLevel ? propertyLevel : applicationLevel;
+
+ property_get("debug.egl.debug_proc", value, "");
+ long pid = getpid();
+ char procPath[128] = {};
+ sprintf(procPath, "/proc/%ld/cmdline", pid);
+ FILE * file = fopen(procPath, "r");
+ if (file)
+ {
+ char cmdline[256] = {};
+ if (fgets(cmdline, sizeof(cmdline) - 1, file))
+ {
+ if (!strcmp(value, cmdline))
+ gEGLDebugLevel = 1;
+ }
+ fclose(file);
+ }
+
+ if (gEGLDebugLevel > 0)
+ StartDebugServer();
}
static void setGLHooksThreadSpecific(gl_hooks_t const *value) {
if (gEGLTraceLevel > 0) {
setGlTraceThreadSpecific(value);
setGlThreadSpecific(&gHooksTrace);
+ } else if (gEGLDebugLevel > 0 && value != &gHooksNoContext) {
+ setGlTraceThreadSpecific(value);
+ setGlThreadSpecific(&gHooksDebug);
+ LOGD("\n* setGLHooksThreadSpecific gHooksDebug");
} else {
setGlThreadSpecific(value);
}
@@ -561,6 +592,11 @@
return egl_to_native_cast<egl_context_t>(context);
}
+DbgContext * getDbgContextThreadSpecific()
+{
+ return get_context(getContext())->dbg;
+}
+
static inline
egl_image_t* get_image(EGLImageKHR image) {
return egl_to_native_cast<egl_image_t>(image);
@@ -1368,6 +1404,8 @@
loseCurrent(cur_c);
if (ctx != EGL_NO_CONTEXT) {
+ if (!c->dbg && gEGLDebugLevel > 0)
+ c->dbg = CreateDbgContext(c->version, c->cnx->hooks[c->version]);
setGLHooksThreadSpecific(c->cnx->hooks[c->version]);
setContext(ctx);
_c.acquire();
@@ -1597,7 +1635,7 @@
cnx->hooks[GLESv1_INDEX]->ext.extensions[slot] =
cnx->hooks[GLESv2_INDEX]->ext.extensions[slot] =
#if EGL_TRACE
- gHooksTrace.ext.extensions[slot] =
+ gHooksDebug.ext.extensions[slot] = gHooksTrace.ext.extensions[slot] =
#endif
cnx->egl.eglGetProcAddress(procname);
}
@@ -1625,6 +1663,10 @@
EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
{
+ EGLBoolean Debug_eglSwapBuffers(EGLDisplay dpy, EGLSurface draw);
+ if (gEGLDebugLevel > 0)
+ Debug_eglSwapBuffers(dpy, draw);
+
clearError();
SurfaceRef _s(draw);
diff --git a/opengl/libs/EGL/trace.cpp b/opengl/libs/EGL/trace.cpp
index d3e96ba..f3e101b 100644
--- a/opengl/libs/EGL/trace.cpp
+++ b/opengl/libs/EGL/trace.cpp
@@ -325,7 +325,7 @@
#define TRACE_GL(_type, _api, _args, _argList, ...) \
static _type Tracing_ ## _api _args { \
- TraceGL(#_api, __VA_ARGS__); \
+ TraceGL(#_api, __VA_ARGS__); \
gl_hooks_t::gl_t const * const _c = &getGLTraceThreadSpecific()->gl; \
return _c->_api _argList; \
}
@@ -333,11 +333,11 @@
extern "C" {
#include "../trace.in"
}
+
#undef TRACE_GL_VOID
#undef TRACE_GL
#define GL_ENTRY(_r, _api, ...) Tracing_ ## _api,
-
EGLAPI gl_hooks_t gHooksTrace = {
{
#include "entries.in"
@@ -348,6 +348,48 @@
};
#undef GL_ENTRY
+
+#undef TRACE_GL_VOID
+#undef TRACE_GL
+
+// define the ES 1.0 Debug_gl* functions as Tracing_gl functions
+#define TRACE_GL_VOID(_api, _args, _argList, ...) \
+static void Debug_ ## _api _args { \
+ TraceGL(#_api, __VA_ARGS__); \
+ gl_hooks_t::gl_t const * const _c = &getGLTraceThreadSpecific()->gl; \
+ _c->_api _argList; \
+}
+
+#define TRACE_GL(_type, _api, _args, _argList, ...) \
+static _type Debug_ ## _api _args { \
+ TraceGL(#_api, __VA_ARGS__); \
+ gl_hooks_t::gl_t const * const _c = &getGLTraceThreadSpecific()->gl; \
+ return _c->_api _argList; \
+}
+
+extern "C" {
+#include "../debug.in"
+}
+
+#undef TRACE_GL_VOID
+#undef TRACE_GL
+
+// declare all Debug_gl* functions
+#define GL_ENTRY(_r, _api, ...) _r Debug_##_api ( __VA_ARGS__ );
+#include "glesv2dbg_functions.h"
+#undef GL_ENTRY
+
+#define GL_ENTRY(_r, _api, ...) Debug_ ## _api,
+EGLAPI gl_hooks_t gHooksDebug = {
+ {
+ #include "entries.in"
+ },
+ {
+ {0}
+ }
+};
+#undef GL_ENTRY
+
// ----------------------------------------------------------------------------
}; // namespace android
// ----------------------------------------------------------------------------
diff --git a/opengl/libs/GLES2_dbg/Android.mk b/opengl/libs/GLES2_dbg/Android.mk
new file mode 100644
index 0000000..e593c327
--- /dev/null
+++ b/opengl/libs/GLES2_dbg/Android.mk
@@ -0,0 +1,45 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ src/api.cpp \
+ src/dbgcontext.cpp \
+ src/debugger_message.pb.cpp \
+ src/egl.cpp \
+ src/server.cpp \
+ src/texture.cpp \
+ src/vertex.cpp
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/../ \
+ external/stlport/stlport \
+ external/protobuf/src \
+ bionic
+
+#LOCAL_CFLAGS += -O0 -g -DDEBUG -UNDEBUG
+LOCAL_CFLAGS := -DGOOGLE_PROTOBUF_NO_RTTI
+
+ifeq ($(TARGET_ARCH),arm)
+ LOCAL_CFLAGS += -fstrict-aliasing
+endif
+
+ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true)
+ LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER
+endif
+
+ifneq ($(TARGET_SIMULATOR),true)
+ # we need to access the private Bionic header <bionic_tls.h>
+ # on ARM platforms, we need to mirror the ARCH_ARM_HAVE_TLS_REGISTER
+ # behavior from the bionic Android.mk file
+ ifeq ($(TARGET_ARCH)-$(ARCH_ARM_HAVE_TLS_REGISTER),arm-true)
+ LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER
+ endif
+ LOCAL_C_INCLUDES += bionic/libc/private
+endif
+
+LOCAL_MODULE:= libGLESv2_dbg
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/opengl/libs/GLES2_dbg/generate_api_cpp.py b/opengl/libs/GLES2_dbg/generate_api_cpp.py
new file mode 100755
index 0000000..5b024ad
--- /dev/null
+++ b/opengl/libs/GLES2_dbg/generate_api_cpp.py
@@ -0,0 +1,207 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+#
+# Copyright 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.
+#
+
+import os
+import sys
+
+def RemoveAnnotation(line):
+ if line.find(":") >= 0:
+ annotation = line[line.find(":"): line.find(" ", line.find(":"))]
+ return line.replace(annotation, "*")
+ else:
+ return line
+
+def generate_api(lines):
+ externs = []
+ i = 0
+ # these have been hand written
+ skipFunctions = ["glTexImage2D", "glTexSubImage2D", "glReadPixels",
+"glDrawArrays", "glDrawElements"]
+
+ # these have an EXTEND_Debug_* macro for getting data
+ extendFunctions = ["glCopyTexImage2D", "glCopyTexSubImage2D", "glShaderSource"]
+
+ # these also needs to be forwarded to DbgContext
+ contextFunctions = ["glUseProgram", "glEnableVertexAttribArray", "glDisableVertexAttribArray",
+"glVertexAttribPointer", "glBindBuffer", "glBufferData", "glBufferSubData", "glDeleteBuffers",]
+
+ for line in lines:
+ if line.find("API_ENTRY(") >= 0: # a function prototype
+ returnType = line[0: line.find(" API_ENTRY(")]
+ functionName = line[line.find("(") + 1: line.find(")")] #extract GL function name
+ parameterList = line[line.find(")(") + 2: line.find(") {")]
+
+ #if line.find("*") >= 0:
+ # extern = "%s Debug_%s(%s);" % (returnType, functionName, parameterList)
+ # externs.append(extern)
+ # continue
+
+ if functionName in skipFunctions:
+ sys.stderr.write("!\n! skipping function '%s'\n!\n" % (functionName))
+ continue
+
+ parameters = parameterList.split(',')
+ paramIndex = 0
+ if line.find("*") >= 0 and (line.find("*") < line.find(":") or line.find("*") > line.rfind(":")): # unannotated pointer
+ if not functionName in extendFunctions:
+ # add function to list of functions that should be hand written, but generate code anyways
+ extern = "%s Debug_%s(%s);" % (returnType, functionName, RemoveAnnotation(parameterList))
+ sys.stderr.write("%s should be hand written\n" % (extern))
+ print "// FIXME: this function has pointers, it should be hand written"
+ externs.append(extern)
+
+ print "%s Debug_%s(%s)\n{" % (returnType, functionName, RemoveAnnotation(parameterList))
+ print """ glesv2debugger::Message msg;
+ const bool expectResponse = false;"""
+
+ if parameterList == "void":
+ parameters = []
+ arguments = ""
+ paramNames = []
+ inout = ""
+ getData = ""
+
+ callerMembers = ""
+ setCallerMembers = ""
+ setMsgParameters = ""
+
+ for parameter in parameters:
+ const = parameter.find("const")
+ parameter = parameter.replace("const", "")
+ parameter = parameter.strip()
+ paramType = parameter.split(' ')[0]
+ paramName = parameter.split(' ')[1]
+ annotation = ""
+ arguments += paramName
+ if parameter.find(":") >= 0: # has annotation
+ assert inout == "" # only one parameter should be annotated
+ sys.stderr.write("%s is annotated: %s \n" % (functionName, paramType))
+ inout = paramType.split(":")[2]
+ annotation = paramType.split(":")[1]
+ paramType = paramType.split(":")[0]
+ count = 1
+ countArg = ""
+ if annotation.find("*") >= 0: # [1,n] * param
+ count = int(annotation.split("*")[0])
+ countArg = annotation.split("*")[1]
+ assert countArg in paramNames
+ elif annotation in paramNames:
+ count = 1
+ countArg = annotation
+ elif annotation == "GLstring":
+ annotation = "strlen(%s)" % (paramName)
+ else:
+ count = int(annotation)
+
+ setMsgParameters += " msg.set_arg%d(ToInt(%s));\n" % (paramIndex, paramName)
+ if paramType.find("void") >= 0:
+ getData += " msg.mutable_data()->assign(reinterpret_cast<const char *>(%s), %s * sizeof(char));" % (paramName, annotation)
+ else:
+ getData += " msg.mutable_data()->assign(reinterpret_cast<const char *>(%s), %s * sizeof(%s));" % (paramName, annotation, paramType)
+ paramType += "*"
+ else:
+ if paramType == "GLfloat" or paramType == "GLclampf" or paramType.find("*") >= 0:
+ setMsgParameters += " msg.set_arg%d(ToInt(%s));\n" % (paramIndex, paramName)
+ else:
+ setMsgParameters += " msg.set_arg%d(%s);\n" % (paramIndex, paramName)
+ if paramIndex < len(parameters) - 1:
+ arguments += ', '
+ if const >= 0:
+ paramType = "const " + paramType
+ paramNames.append(paramName)
+ paramIndex += 1
+ callerMembers += " %s %s;\n" % (paramType, paramName)
+ setCallerMembers += " caller.%s = %s;\n" % (paramName, paramName)
+
+ print " struct : public FunctionCall {"
+ print callerMembers
+ print " const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {"
+ if inout in ["out", "inout"]: # get timing excluding output data copy
+ print " nsecs_t c0 = systemTime(timeMode);"
+ if returnType == "void":
+ print " _c->%s(%s);" % (functionName, arguments)
+ else:
+ print " const int * ret = reinterpret_cast<const int *>(_c->%s(%s));" % (functionName, arguments)
+ print " msg.set_ret(ToInt(ret));"
+ if inout in ["out", "inout"]:
+ print " msg.set_time((systemTime(timeMode) - c0) * 1e-6f);"
+ print " " + getData
+ if functionName in contextFunctions:
+ print " getDbgContextThreadSpecific()->%s(%s);" % (functionName, arguments)
+ if returnType == "void":
+ print " return 0;"
+ else:
+ print " return ret;"
+ print """ }
+ } caller;"""
+ print setCallerMembers
+ print setMsgParameters
+
+ if line.find("*") >= 0 or line.find(":") >= 0:
+ print " // FIXME: check for pointer usage"
+ if inout in ["in", "inout"]:
+ print getData
+ if functionName in extendFunctions:
+ print " EXTEND_Debug_%s;" % (functionName)
+ print " int * ret = MessageLoop(caller, msg, expectResponse,"
+ print " glesv2debugger::Message_Function_%s);" % (functionName)
+ if returnType != "void":
+ if returnType == "GLboolean":
+ print " return static_cast<GLboolean>(reinterpret_cast<int>(ret));"
+ else:
+ print " return reinterpret_cast<%s>(ret);" % (returnType)
+ print "}\n"
+
+
+ print "// FIXME: the following functions should be written by hand"
+ for extern in externs:
+ print extern
+
+if __name__ == "__main__":
+ print """\
+/*
+ ** Copyright 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.
+ */
+
+// auto generated by generate_api_cpp.py
+
+#include "src/header.h"
+#include "src/api.h"
+
+template<typename T> static int ToInt(const T & t) { STATIC_ASSERT(sizeof(T) == sizeof(int), bitcast); return (int &)t; }
+template<typename T> static T FromInt(const int & t) { STATIC_ASSERT(sizeof(T) == sizeof(int), bitcast); return (T &)t; }
+"""
+ lines = open("gl2_api_annotated.in").readlines()
+ generate_api(lines)
+ #lines = open("gl2ext_api.in").readlines()
+ #generate_api(lines)
+
+
diff --git a/opengl/libs/GLES2_dbg/generate_debug_in.py b/opengl/libs/GLES2_dbg/generate_debug_in.py
new file mode 100755
index 0000000..1280c6f
--- /dev/null
+++ b/opengl/libs/GLES2_dbg/generate_debug_in.py
@@ -0,0 +1,80 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+#
+# Copyright 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.
+#
+
+import os
+import sys
+
+def append_functions(functions, lines):
+ i = 0
+ for line in lines:
+ if line.find("API_ENTRY(") >= 0: # a function prototype
+ returnType = line[0: line.find(" API_ENTRY(")]
+ functionName = line[line.find("(") + 1: line.find(")")] #extract GL function name
+ parameterList = line[line.find(")(") + 2: line.find(") {")]
+
+ functions.append(functionName)
+ #print functionName
+ continue
+
+ parameters = parameterList.split(',')
+ paramIndex = 0
+ if line.find("*") >= 0:
+ print "// FIXME: this function has pointers, it should be hand written"
+ externs.append("%s Tracing_%s(%s);" % (returnType, functionName, parameterList))
+ print "%s Tracing_%s(%s)\n{" % (returnType, functionName, parameterList)
+
+ if parameterList == "void":
+ parameters = []
+
+ arguments = ""
+
+ for parameter in parameters:
+ parameter = parameter.replace("const", "")
+ parameter = parameter.strip()
+ paramType = parameter.split(' ')[0]
+ paramName = parameter.split(' ')[1]
+
+ paramIndex += 1
+
+ return functions
+
+
+
+if __name__ == "__main__":
+ definedFunctions = []
+ lines = open("gl2_api_annotated.in").readlines()
+ definedFunctions = append_functions(definedFunctions, lines)
+
+ output = open("../debug.in", "w")
+ lines = open("../trace.in").readlines()
+ output.write("// the following functions are not defined in GLESv2_dbg\n")
+ for line in lines:
+ functionName = ""
+ if line.find("TRACE_GL(") >= 0: # a function prototype
+ functionName = line.split(',')[1].strip()
+ elif line.find("TRACE_GL_VOID(") >= 0: # a function prototype
+ functionName = line[line.find("(") + 1: line.find(",")] #extract GL function name
+ else:
+ continue
+ if functionName in definedFunctions:
+ #print functionName
+ continue
+ else:
+ output.write(line)
+
diff --git a/opengl/libs/GLES2_dbg/generate_debugger_message_proto.py b/opengl/libs/GLES2_dbg/generate_debugger_message_proto.py
new file mode 100755
index 0000000..b14885b
--- /dev/null
+++ b/opengl/libs/GLES2_dbg/generate_debugger_message_proto.py
@@ -0,0 +1,139 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+#
+# Copyright 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.
+#
+
+import os
+
+def generate_egl_entries(output, lines, i):
+ for line in lines:
+ if line.find("EGL_ENTRY(") >= 0:
+ line = line.split(",")[1].strip() #extract EGL function name
+ output.write(" %s = %d;\n" % (line, i))
+ i += 1
+ return i
+
+
+def generate_gl_entries(output,lines,i):
+ for line in lines:
+ if line.find("API_ENTRY(") >= 0:
+ line = line[line.find("(") + 1: line.find(")")] #extract GL function name
+ output.write(" %s = %d;\n" % (line, i))
+ i += 1
+ return i
+
+
+if __name__ == "__main__":
+ output = open("debugger_message.proto",'w')
+ output.write("""\
+/*
+ * 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.
+ */
+
+// do not edit; auto generated by generate_debugger_message_proto.py
+
+package com.android.glesv2debugger;
+
+option optimize_for = LITE_RUNTIME;
+
+message Message
+{
+ required int32 context_id = 1; // GL context id
+ enum Function
+ {
+""")
+
+ i = 0;
+
+ lines = open("gl2_api_annotated.in").readlines()
+ i = generate_gl_entries(output, lines, i)
+ output.write(" // end of GL functions\n")
+
+ #lines = open("gl2ext_api.in").readlines()
+ #i = generate_gl_entries(output, lines, i)
+ #output.write(" // end of GL EXT functions\n")
+
+ lines = open("../EGL/egl_entries.in").readlines()
+ i = generate_egl_entries(output, lines, i)
+ output.write(" // end of GL EXT functions\n")
+
+ output.write(" ACK = %d;\n" % (i))
+ i += 1
+
+ output.write(" NEG = %d;\n" % (i))
+ i += 1
+
+ output.write(" CONTINUE = %d;\n" % (i))
+ i += 1
+
+ output.write(" SKIP = %d;\n" % (i))
+ i += 1
+
+ output.write(" SETPROP = %d;\n" % (i))
+ i += 1
+
+ output.write(" CAPTURE = %d;\n" % (i))
+ i += 1
+
+ output.write(""" }
+ required Function function = 2 [default = NEG]; // type/function of message
+ enum Type
+ {
+ BeforeCall = 0;
+ AfterCall = 1;
+ Response = 2; // currently used for misc messages
+ }
+ required Type type = 3;
+ required bool expect_response = 4;
+ optional int32 ret = 5; // return value from previous GL call
+ optional int32 arg0 = 6; // args to GL call
+ optional int32 arg1 = 7;
+ optional int32 arg2 = 8;
+ optional int32 arg3 = 9;
+ optional int32 arg4 = 16;
+ optional int32 arg5 = 17;
+ optional int32 arg6 = 18;
+ optional int32 arg7 = 19;
+ optional int32 arg8 = 20;
+ optional bytes data = 10; // variable length data used for GL call
+ optional float time = 11; // duration of previous GL call (ms)
+ enum Prop
+ {
+ Capture = 0; // arg0 = true | false
+ TimeMode = 1; // arg0 = SYSTEM_TIME_* in utils/Timers.h
+ };
+ optional Prop prop = 21; // used with SETPROP, value in arg0
+ optional float clock = 22; // wall clock in seconds
+}
+""")
+
+ output.close()
+
+ os.system("aprotoc --cpp_out=src --java_out=../../../../../development/tools/glesv2debugger/src debugger_message.proto")
+ os.system('mv -f "src/debugger_message.pb.cc" "src/debugger_message.pb.cpp"')
diff --git a/opengl/libs/GLES2_dbg/gl2_api_annotated.in b/opengl/libs/GLES2_dbg/gl2_api_annotated.in
new file mode 100644
index 0000000..227e2eb
--- /dev/null
+++ b/opengl/libs/GLES2_dbg/gl2_api_annotated.in
@@ -0,0 +1,426 @@
+void API_ENTRY(glActiveTexture)(GLenum texture) {
+ CALL_GL_API(glActiveTexture, texture);
+}
+void API_ENTRY(glAttachShader)(GLuint program, GLuint shader) {
+ CALL_GL_API(glAttachShader, program, shader);
+}
+void API_ENTRY(glBindAttribLocation)(GLuint program, GLuint index, const GLchar:GLstring:in name) {
+ CALL_GL_API(glBindAttribLocation, program, index, name);
+}
+void API_ENTRY(glBindBuffer)(GLenum target, GLuint buffer) {
+ CALL_GL_API(glBindBuffer, target, buffer);
+}
+void API_ENTRY(glBindFramebuffer)(GLenum target, GLuint framebuffer) {
+ CALL_GL_API(glBindFramebuffer, target, framebuffer);
+}
+void API_ENTRY(glBindRenderbuffer)(GLenum target, GLuint renderbuffer) {
+ CALL_GL_API(glBindRenderbuffer, target, renderbuffer);
+}
+void API_ENTRY(glBindTexture)(GLenum target, GLuint texture) {
+ CALL_GL_API(glBindTexture, target, texture);
+}
+void API_ENTRY(glBlendColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
+ CALL_GL_API(glBlendColor, red, green, blue, alpha);
+}
+void API_ENTRY(glBlendEquation)( GLenum mode ) {
+ CALL_GL_API(glBlendEquation, mode);
+}
+void API_ENTRY(glBlendEquationSeparate)(GLenum modeRGB, GLenum modeAlpha) {
+ CALL_GL_API(glBlendEquationSeparate, modeRGB, modeAlpha);
+}
+void API_ENTRY(glBlendFunc)(GLenum sfactor, GLenum dfactor) {
+ CALL_GL_API(glBlendFunc, sfactor, dfactor);
+}
+void API_ENTRY(glBlendFuncSeparate)(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) {
+ CALL_GL_API(glBlendFuncSeparate, srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+void API_ENTRY(glBufferData)(GLenum target, GLsizeiptr size, const GLvoid:size:in data, GLenum usage) {
+ CALL_GL_API(glBufferData, target, size, data, usage);
+}
+void API_ENTRY(glBufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid:size:in data) {
+ CALL_GL_API(glBufferSubData, target, offset, size, data);
+}
+GLenum API_ENTRY(glCheckFramebufferStatus)(GLenum target) {
+ CALL_GL_API_RETURN(glCheckFramebufferStatus, target);
+}
+void API_ENTRY(glClear)(GLbitfield mask) {
+ CALL_GL_API(glClear, mask);
+}
+void API_ENTRY(glClearColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
+ CALL_GL_API(glClearColor, red, green, blue, alpha);
+}
+void API_ENTRY(glClearDepthf)(GLclampf depth) {
+ CALL_GL_API(glClearDepthf, depth);
+}
+void API_ENTRY(glClearStencil)(GLint s) {
+ CALL_GL_API(glClearStencil, s);
+}
+void API_ENTRY(glColorMask)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {
+ CALL_GL_API(glColorMask, red, green, blue, alpha);
+}
+void API_ENTRY(glCompileShader)(GLuint shader) {
+ CALL_GL_API(glCompileShader, shader);
+}
+void API_ENTRY(glCompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data) {
+ CALL_GL_API(glCompressedTexImage2D, target, level, internalformat, width, height, border, imageSize, data);
+}
+void API_ENTRY(glCompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data) {
+ CALL_GL_API(glCompressedTexSubImage2D, target, level, xoffset, yoffset, width, height, format, imageSize, data);
+}
+void API_ENTRY(glCopyTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
+ CALL_GL_API(glCopyTexImage2D, target, level, internalformat, x, y, width, height, border);
+}
+void API_ENTRY(glCopyTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
+ CALL_GL_API(glCopyTexSubImage2D, target, level, xoffset, yoffset, x, y, width, height);
+}
+GLuint API_ENTRY(glCreateProgram)(void) {
+ CALL_GL_API_RETURN(glCreateProgram);
+}
+GLuint API_ENTRY(glCreateShader)(GLenum type) {
+ CALL_GL_API_RETURN(glCreateShader, type);
+}
+void API_ENTRY(glCullFace)(GLenum mode) {
+ CALL_GL_API(glCullFace, mode);
+}
+void API_ENTRY(glDeleteBuffers)(GLsizei n, const GLuint:n:in buffers) {
+ CALL_GL_API(glDeleteBuffers, n, buffers);
+}
+void API_ENTRY(glDeleteFramebuffers)(GLsizei n, const GLuint:n:in framebuffers) {
+ CALL_GL_API(glDeleteFramebuffers, n, framebuffers);
+}
+void API_ENTRY(glDeleteProgram)(GLuint program) {
+ CALL_GL_API(glDeleteProgram, program);
+}
+void API_ENTRY(glDeleteRenderbuffers)(GLsizei n, const GLuint:n:in renderbuffers) {
+ CALL_GL_API(glDeleteRenderbuffers, n, renderbuffers);
+}
+void API_ENTRY(glDeleteShader)(GLuint shader) {
+ CALL_GL_API(glDeleteShader, shader);
+}
+void API_ENTRY(glDeleteTextures)(GLsizei n, const GLuint:n:in textures) {
+ CALL_GL_API(glDeleteTextures, n, textures);
+}
+void API_ENTRY(glDepthFunc)(GLenum func) {
+ CALL_GL_API(glDepthFunc, func);
+}
+void API_ENTRY(glDepthMask)(GLboolean flag) {
+ CALL_GL_API(glDepthMask, flag);
+}
+void API_ENTRY(glDepthRangef)(GLclampf zNear, GLclampf zFar) {
+ CALL_GL_API(glDepthRangef, zNear, zFar);
+}
+void API_ENTRY(glDetachShader)(GLuint program, GLuint shader) {
+ CALL_GL_API(glDetachShader, program, shader);
+}
+void API_ENTRY(glDisable)(GLenum cap) {
+ CALL_GL_API(glDisable, cap);
+}
+void API_ENTRY(glDisableVertexAttribArray)(GLuint index) {
+ CALL_GL_API(glDisableVertexAttribArray, index);
+}
+void API_ENTRY(glDrawArrays)(GLenum mode, GLint first, GLsizei count) {
+ CALL_GL_API(glDrawArrays, mode, first, count);
+}
+void API_ENTRY(glDrawElements)(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) {
+ CALL_GL_API(glDrawElements, mode, count, type, indices);
+}
+void API_ENTRY(glEnable)(GLenum cap) {
+ CALL_GL_API(glEnable, cap);
+}
+void API_ENTRY(glEnableVertexAttribArray)(GLuint index) {
+ CALL_GL_API(glEnableVertexAttribArray, index);
+}
+void API_ENTRY(glFinish)(void) {
+ CALL_GL_API(glFinish);
+}
+void API_ENTRY(glFlush)(void) {
+ CALL_GL_API(glFlush);
+}
+void API_ENTRY(glFramebufferRenderbuffer)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) {
+ CALL_GL_API(glFramebufferRenderbuffer, target, attachment, renderbuffertarget, renderbuffer);
+}
+void API_ENTRY(glFramebufferTexture2D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {
+ CALL_GL_API(glFramebufferTexture2D, target, attachment, textarget, texture, level);
+}
+void API_ENTRY(glFrontFace)(GLenum mode) {
+ CALL_GL_API(glFrontFace, mode);
+}
+void API_ENTRY(glGenBuffers)(GLsizei n, GLuint:n:out buffers) {
+ CALL_GL_API(glGenBuffers, n, buffers);
+}
+void API_ENTRY(glGenerateMipmap)(GLenum target) {
+ CALL_GL_API(glGenerateMipmap, target);
+}
+void API_ENTRY(glGenFramebuffers)(GLsizei n, GLuint:n:out framebuffers) {
+ CALL_GL_API(glGenFramebuffers, n, framebuffers);
+}
+void API_ENTRY(glGenRenderbuffers)(GLsizei n, GLuint:n:out renderbuffers) {
+ CALL_GL_API(glGenRenderbuffers, n, renderbuffers);
+}
+void API_ENTRY(glGenTextures)(GLsizei n, GLuint:n:out textures) {
+ CALL_GL_API(glGenTextures, n, textures);
+}
+void API_ENTRY(glGetActiveAttrib)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar:GLstring:in name) {
+ CALL_GL_API(glGetActiveAttrib, program, index, bufsize, length, size, type, name);
+}
+void API_ENTRY(glGetActiveUniform)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar:GLstring:in name) {
+ CALL_GL_API(glGetActiveUniform, program, index, bufsize, length, size, type, name);
+}
+void API_ENTRY(glGetAttachedShaders)(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) {
+ CALL_GL_API(glGetAttachedShaders, program, maxcount, count, shaders);
+}
+int API_ENTRY(glGetAttribLocation)(GLuint program, const GLchar:GLstring:in name) {
+ CALL_GL_API_RETURN(glGetAttribLocation, program, name);
+}
+void API_ENTRY(glGetBooleanv)(GLenum pname, GLboolean* params) {
+ CALL_GL_API(glGetBooleanv, pname, params);
+}
+void API_ENTRY(glGetBufferParameteriv)(GLenum target, GLenum pname, GLint* params) {
+ CALL_GL_API(glGetBufferParameteriv, target, pname, params);
+}
+GLenum API_ENTRY(glGetError)(void) {
+ CALL_GL_API_RETURN(glGetError);
+}
+void API_ENTRY(glGetFloatv)(GLenum pname, GLfloat* params) {
+ CALL_GL_API(glGetFloatv, pname, params);
+}
+void API_ENTRY(glGetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, GLenum pname, GLint* params) {
+ CALL_GL_API(glGetFramebufferAttachmentParameteriv, target, attachment, pname, params);
+}
+void API_ENTRY(glGetIntegerv)(GLenum pname, GLint* params) {
+ CALL_GL_API(glGetIntegerv, pname, params);
+}
+void API_ENTRY(glGetProgramiv)(GLuint program, GLenum pname, GLint:1:out params) {
+ CALL_GL_API(glGetProgramiv, program, pname, params);
+}
+void API_ENTRY(glGetProgramInfoLog)(GLuint program, GLsizei bufsize, GLsizei* length, GLchar:GLstring:out infolog) {
+ CALL_GL_API(glGetProgramInfoLog, program, bufsize, length, infolog);
+}
+void API_ENTRY(glGetRenderbufferParameteriv)(GLenum target, GLenum pname, GLint* params) {
+ CALL_GL_API(glGetRenderbufferParameteriv, target, pname, params);
+}
+void API_ENTRY(glGetShaderiv)(GLuint shader, GLenum pname, GLint:1:out params) {
+ CALL_GL_API(glGetShaderiv, shader, pname, params);
+}
+void API_ENTRY(glGetShaderInfoLog)(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar:GLstring:out infolog) {
+ CALL_GL_API(glGetShaderInfoLog, shader, bufsize, length, infolog);
+}
+void API_ENTRY(glGetShaderPrecisionFormat)(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
+ CALL_GL_API(glGetShaderPrecisionFormat, shadertype, precisiontype, range, precision);
+}
+void API_ENTRY(glGetShaderSource)(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar:GLstring:out source) {
+ CALL_GL_API(glGetShaderSource, shader, bufsize, length, source);
+}
+const GLubyte* API_ENTRY(glGetString)(GLenum name) {
+ CALL_GL_API_RETURN(glGetString, name);
+}
+void API_ENTRY(glGetTexParameterfv)(GLenum target, GLenum pname, GLfloat* params) {
+ CALL_GL_API(glGetTexParameterfv, target, pname, params);
+}
+void API_ENTRY(glGetTexParameteriv)(GLenum target, GLenum pname, GLint* params) {
+ CALL_GL_API(glGetTexParameteriv, target, pname, params);
+}
+void API_ENTRY(glGetUniformfv)(GLuint program, GLint location, GLfloat* params) {
+ CALL_GL_API(glGetUniformfv, program, location, params);
+}
+void API_ENTRY(glGetUniformiv)(GLuint program, GLint location, GLint* params) {
+ CALL_GL_API(glGetUniformiv, program, location, params);
+}
+int API_ENTRY(glGetUniformLocation)(GLuint program, const GLchar:GLstring:in name) {
+ CALL_GL_API_RETURN(glGetUniformLocation, program, name);
+}
+void API_ENTRY(glGetVertexAttribfv)(GLuint index, GLenum pname, GLfloat* params) {
+ CALL_GL_API(glGetVertexAttribfv, index, pname, params);
+}
+void API_ENTRY(glGetVertexAttribiv)(GLuint index, GLenum pname, GLint* params) {
+ CALL_GL_API(glGetVertexAttribiv, index, pname, params);
+}
+void API_ENTRY(glGetVertexAttribPointerv)(GLuint index, GLenum pname, GLvoid** pointer) {
+ CALL_GL_API(glGetVertexAttribPointerv, index, pname, pointer);
+}
+void API_ENTRY(glHint)(GLenum target, GLenum mode) {
+ CALL_GL_API(glHint, target, mode);
+}
+GLboolean API_ENTRY(glIsBuffer)(GLuint buffer) {
+ CALL_GL_API_RETURN(glIsBuffer, buffer);
+}
+GLboolean API_ENTRY(glIsEnabled)(GLenum cap) {
+ CALL_GL_API_RETURN(glIsEnabled, cap);
+}
+GLboolean API_ENTRY(glIsFramebuffer)(GLuint framebuffer) {
+ CALL_GL_API_RETURN(glIsFramebuffer, framebuffer);
+}
+GLboolean API_ENTRY(glIsProgram)(GLuint program) {
+ CALL_GL_API_RETURN(glIsProgram, program);
+}
+GLboolean API_ENTRY(glIsRenderbuffer)(GLuint renderbuffer) {
+ CALL_GL_API_RETURN(glIsRenderbuffer, renderbuffer);
+}
+GLboolean API_ENTRY(glIsShader)(GLuint shader) {
+ CALL_GL_API_RETURN(glIsShader, shader);
+}
+GLboolean API_ENTRY(glIsTexture)(GLuint texture) {
+ CALL_GL_API_RETURN(glIsTexture, texture);
+}
+void API_ENTRY(glLineWidth)(GLfloat width) {
+ CALL_GL_API(glLineWidth, width);
+}
+void API_ENTRY(glLinkProgram)(GLuint program) {
+ CALL_GL_API(glLinkProgram, program);
+}
+void API_ENTRY(glPixelStorei)(GLenum pname, GLint param) {
+ CALL_GL_API(glPixelStorei, pname, param);
+}
+void API_ENTRY(glPolygonOffset)(GLfloat factor, GLfloat units) {
+ CALL_GL_API(glPolygonOffset, factor, units);
+}
+void API_ENTRY(glReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) {
+ CALL_GL_API(glReadPixels, x, y, width, height, format, type, pixels);
+}
+void API_ENTRY(glReleaseShaderCompiler)(void) {
+ CALL_GL_API(glReleaseShaderCompiler);
+}
+void API_ENTRY(glRenderbufferStorage)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
+ CALL_GL_API(glRenderbufferStorage, target, internalformat, width, height);
+}
+void API_ENTRY(glSampleCoverage)(GLclampf value, GLboolean invert) {
+ CALL_GL_API(glSampleCoverage, value, invert);
+}
+void API_ENTRY(glScissor)(GLint x, GLint y, GLsizei width, GLsizei height) {
+ CALL_GL_API(glScissor, x, y, width, height);
+}
+void API_ENTRY(glShaderBinary)(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length) {
+ CALL_GL_API(glShaderBinary, n, shaders, binaryformat, binary, length);
+}
+void API_ENTRY(glShaderSource)(GLuint shader, GLsizei count, const GLchar** string, const GLint* length) {
+ CALL_GL_API(glShaderSource, shader, count, string, length);
+}
+void API_ENTRY(glStencilFunc)(GLenum func, GLint ref, GLuint mask) {
+ CALL_GL_API(glStencilFunc, func, ref, mask);
+}
+void API_ENTRY(glStencilFuncSeparate)(GLenum face, GLenum func, GLint ref, GLuint mask) {
+ CALL_GL_API(glStencilFuncSeparate, face, func, ref, mask);
+}
+void API_ENTRY(glStencilMask)(GLuint mask) {
+ CALL_GL_API(glStencilMask, mask);
+}
+void API_ENTRY(glStencilMaskSeparate)(GLenum face, GLuint mask) {
+ CALL_GL_API(glStencilMaskSeparate, face, mask);
+}
+void API_ENTRY(glStencilOp)(GLenum fail, GLenum zfail, GLenum zpass) {
+ CALL_GL_API(glStencilOp, fail, zfail, zpass);
+}
+void API_ENTRY(glStencilOpSeparate)(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) {
+ CALL_GL_API(glStencilOpSeparate, face, fail, zfail, zpass);
+}
+void API_ENTRY(glTexImage2D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels) {
+ CALL_GL_API(glTexImage2D, target, level, internalformat, width, height, border, format, type, pixels);
+}
+void API_ENTRY(glTexParameterf)(GLenum target, GLenum pname, GLfloat param) {
+ CALL_GL_API(glTexParameterf, target, pname, param);
+}
+void API_ENTRY(glTexParameterfv)(GLenum target, GLenum pname, const GLfloat* params) {
+ CALL_GL_API(glTexParameterfv, target, pname, params);
+}
+void API_ENTRY(glTexParameteri)(GLenum target, GLenum pname, GLint param) {
+ CALL_GL_API(glTexParameteri, target, pname, param);
+}
+void API_ENTRY(glTexParameteriv)(GLenum target, GLenum pname, const GLint* params) {
+ CALL_GL_API(glTexParameteriv, target, pname, params);
+}
+void API_ENTRY(glTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels) {
+ CALL_GL_API(glTexSubImage2D, target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+void API_ENTRY(glUniform1f)(GLint location, GLfloat x) {
+ CALL_GL_API(glUniform1f, location, x);
+}
+void API_ENTRY(glUniform1fv)(GLint location, GLsizei count, const GLfloat:1*count:in v) {
+ CALL_GL_API(glUniform1fv, location, count, v);
+}
+void API_ENTRY(glUniform1i)(GLint location, GLint x) {
+ CALL_GL_API(glUniform1i, location, x);
+}
+void API_ENTRY(glUniform1iv)(GLint location, GLsizei count, const GLint:1*count:in v) {
+ CALL_GL_API(glUniform1iv, location, count, v);
+}
+void API_ENTRY(glUniform2f)(GLint location, GLfloat x, GLfloat y) {
+ CALL_GL_API(glUniform2f, location, x, y);
+}
+void API_ENTRY(glUniform2fv)(GLint location, GLsizei count, const GLfloat:2*count:in v) {
+ CALL_GL_API(glUniform2fv, location, count, v);
+}
+void API_ENTRY(glUniform2i)(GLint location, GLint x, GLint y) {
+ CALL_GL_API(glUniform2i, location, x, y);
+}
+void API_ENTRY(glUniform2iv)(GLint location, GLsizei count, const GLint:2*count:in v) {
+ CALL_GL_API(glUniform2iv, location, count, v);
+}
+void API_ENTRY(glUniform3f)(GLint location, GLfloat x, GLfloat y, GLfloat z) {
+ CALL_GL_API(glUniform3f, location, x, y, z);
+}
+void API_ENTRY(glUniform3fv)(GLint location, GLsizei count, const GLfloat:3*count:in v) {
+ CALL_GL_API(glUniform3fv, location, count, v);
+}
+void API_ENTRY(glUniform3i)(GLint location, GLint x, GLint y, GLint z) {
+ CALL_GL_API(glUniform3i, location, x, y, z);
+}
+void API_ENTRY(glUniform3iv)(GLint location, GLsizei count, const GLint:3*count:in v) {
+ CALL_GL_API(glUniform3iv, location, count, v);
+}
+void API_ENTRY(glUniform4f)(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
+ CALL_GL_API(glUniform4f, location, x, y, z, w);
+}
+void API_ENTRY(glUniform4fv)(GLint location, GLsizei count, const GLfloat:4*count:in v) {
+ CALL_GL_API(glUniform4fv, location, count, v);
+}
+void API_ENTRY(glUniform4i)(GLint location, GLint x, GLint y, GLint z, GLint w) {
+ CALL_GL_API(glUniform4i, location, x, y, z, w);
+}
+void API_ENTRY(glUniform4iv)(GLint location, GLsizei count, const GLint:4*count:in v) {
+ CALL_GL_API(glUniform4iv, location, count, v);
+}
+void API_ENTRY(glUniformMatrix2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat:4*count:in value) {
+ CALL_GL_API(glUniformMatrix2fv, location, count, transpose, value);
+}
+void API_ENTRY(glUniformMatrix3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat:9*count:in value) {
+ CALL_GL_API(glUniformMatrix3fv, location, count, transpose, value);
+}
+void API_ENTRY(glUniformMatrix4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat:16*count:in value) {
+ CALL_GL_API(glUniformMatrix4fv, location, count, transpose, value);
+}
+void API_ENTRY(glUseProgram)(GLuint program) {
+ CALL_GL_API(glUseProgram, program);
+}
+void API_ENTRY(glValidateProgram)(GLuint program) {
+ CALL_GL_API(glValidateProgram, program);
+}
+void API_ENTRY(glVertexAttrib1f)(GLuint indx, GLfloat x) {
+ CALL_GL_API(glVertexAttrib1f, indx, x);
+}
+void API_ENTRY(glVertexAttrib1fv)(GLuint indx, const GLfloat:1:in values) {
+ CALL_GL_API(glVertexAttrib1fv, indx, values);
+}
+void API_ENTRY(glVertexAttrib2f)(GLuint indx, GLfloat x, GLfloat y) {
+ CALL_GL_API(glVertexAttrib2f, indx, x, y);
+}
+void API_ENTRY(glVertexAttrib2fv)(GLuint indx, const GLfloat:2:in values) {
+ CALL_GL_API(glVertexAttrib2fv, indx, values);
+}
+void API_ENTRY(glVertexAttrib3f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z) {
+ CALL_GL_API(glVertexAttrib3f, indx, x, y, z);
+}
+void API_ENTRY(glVertexAttrib3fv)(GLuint indx, const GLfloat:3:in values) {
+ CALL_GL_API(glVertexAttrib3fv, indx, values);
+}
+void API_ENTRY(glVertexAttrib4f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
+ CALL_GL_API(glVertexAttrib4f, indx, x, y, z, w);
+}
+void API_ENTRY(glVertexAttrib4fv)(GLuint indx, const GLfloat:4:in values) {
+ CALL_GL_API(glVertexAttrib4fv, indx, values);
+}
+void API_ENTRY(glVertexAttribPointer)(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr) {
+ CALL_GL_API(glVertexAttribPointer, indx, size, type, normalized, stride, ptr);
+}
+void API_ENTRY(glViewport)(GLint x, GLint y, GLsizei width, GLsizei height) {
+ CALL_GL_API(glViewport, x, y, width, height);
+}
diff --git a/opengl/libs/GLES2_dbg/src/api.cpp b/opengl/libs/GLES2_dbg/src/api.cpp
new file mode 100644
index 0000000..7094ca7
--- /dev/null
+++ b/opengl/libs/GLES2_dbg/src/api.cpp
@@ -0,0 +1,3653 @@
+/*
+ ** Copyright 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.
+ */
+
+// auto generated by generate_api_cpp.py
+
+#include "src/header.h"
+#include "src/api.h"
+
+template<typename T> static int ToInt(const T & t) { STATIC_ASSERT(sizeof(T) == sizeof(int), bitcast); return (int &)t; }
+template<typename T> static T FromInt(const int & t) { STATIC_ASSERT(sizeof(T) == sizeof(int), bitcast); return (T &)t; }
+
+void Debug_glActiveTexture(GLenum texture)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum texture;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glActiveTexture(texture);
+ return 0;
+ }
+ } caller;
+ caller.texture = texture;
+
+ msg.set_arg0(texture);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glActiveTexture);
+}
+
+void Debug_glAttachShader(GLuint program, GLuint shader)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint program;
+ GLuint shader;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glAttachShader(program, shader);
+ return 0;
+ }
+ } caller;
+ caller.program = program;
+ caller.shader = shader;
+
+ msg.set_arg0(program);
+ msg.set_arg1(shader);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glAttachShader);
+}
+
+void Debug_glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint program;
+ GLuint index;
+ const GLchar* name;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glBindAttribLocation(program, index, name);
+ return 0;
+ }
+ } caller;
+ caller.program = program;
+ caller.index = index;
+ caller.name = name;
+
+ msg.set_arg0(program);
+ msg.set_arg1(index);
+ msg.set_arg2(ToInt(name));
+
+ // FIXME: check for pointer usage
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(name), strlen(name) * sizeof(GLchar));
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glBindAttribLocation);
+}
+
+void Debug_glBindBuffer(GLenum target, GLuint buffer)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum target;
+ GLuint buffer;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glBindBuffer(target, buffer);
+ getDbgContextThreadSpecific()->glBindBuffer(target, buffer);
+ return 0;
+ }
+ } caller;
+ caller.target = target;
+ caller.buffer = buffer;
+
+ msg.set_arg0(target);
+ msg.set_arg1(buffer);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glBindBuffer);
+}
+
+void Debug_glBindFramebuffer(GLenum target, GLuint framebuffer)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum target;
+ GLuint framebuffer;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glBindFramebuffer(target, framebuffer);
+ return 0;
+ }
+ } caller;
+ caller.target = target;
+ caller.framebuffer = framebuffer;
+
+ msg.set_arg0(target);
+ msg.set_arg1(framebuffer);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glBindFramebuffer);
+}
+
+void Debug_glBindRenderbuffer(GLenum target, GLuint renderbuffer)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum target;
+ GLuint renderbuffer;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glBindRenderbuffer(target, renderbuffer);
+ return 0;
+ }
+ } caller;
+ caller.target = target;
+ caller.renderbuffer = renderbuffer;
+
+ msg.set_arg0(target);
+ msg.set_arg1(renderbuffer);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glBindRenderbuffer);
+}
+
+void Debug_glBindTexture(GLenum target, GLuint texture)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum target;
+ GLuint texture;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glBindTexture(target, texture);
+ return 0;
+ }
+ } caller;
+ caller.target = target;
+ caller.texture = texture;
+
+ msg.set_arg0(target);
+ msg.set_arg1(texture);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glBindTexture);
+}
+
+void Debug_glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLclampf red;
+ GLclampf green;
+ GLclampf blue;
+ GLclampf alpha;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glBlendColor(red, green, blue, alpha);
+ return 0;
+ }
+ } caller;
+ caller.red = red;
+ caller.green = green;
+ caller.blue = blue;
+ caller.alpha = alpha;
+
+ msg.set_arg0(ToInt(red));
+ msg.set_arg1(ToInt(green));
+ msg.set_arg2(ToInt(blue));
+ msg.set_arg3(ToInt(alpha));
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glBlendColor);
+}
+
+void Debug_glBlendEquation( GLenum mode )
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum mode;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glBlendEquation(mode);
+ return 0;
+ }
+ } caller;
+ caller.mode = mode;
+
+ msg.set_arg0(mode);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glBlendEquation);
+}
+
+void Debug_glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum modeRGB;
+ GLenum modeAlpha;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glBlendEquationSeparate(modeRGB, modeAlpha);
+ return 0;
+ }
+ } caller;
+ caller.modeRGB = modeRGB;
+ caller.modeAlpha = modeAlpha;
+
+ msg.set_arg0(modeRGB);
+ msg.set_arg1(modeAlpha);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glBlendEquationSeparate);
+}
+
+void Debug_glBlendFunc(GLenum sfactor, GLenum dfactor)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum sfactor;
+ GLenum dfactor;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glBlendFunc(sfactor, dfactor);
+ return 0;
+ }
+ } caller;
+ caller.sfactor = sfactor;
+ caller.dfactor = dfactor;
+
+ msg.set_arg0(sfactor);
+ msg.set_arg1(dfactor);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glBlendFunc);
+}
+
+void Debug_glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum srcRGB;
+ GLenum dstRGB;
+ GLenum srcAlpha;
+ GLenum dstAlpha;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
+ return 0;
+ }
+ } caller;
+ caller.srcRGB = srcRGB;
+ caller.dstRGB = dstRGB;
+ caller.srcAlpha = srcAlpha;
+ caller.dstAlpha = dstAlpha;
+
+ msg.set_arg0(srcRGB);
+ msg.set_arg1(dstRGB);
+ msg.set_arg2(srcAlpha);
+ msg.set_arg3(dstAlpha);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glBlendFuncSeparate);
+}
+
+void Debug_glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum target;
+ GLsizeiptr size;
+ const GLvoid* data;
+ GLenum usage;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glBufferData(target, size, data, usage);
+ getDbgContextThreadSpecific()->glBufferData(target, size, data, usage);
+ return 0;
+ }
+ } caller;
+ caller.target = target;
+ caller.size = size;
+ caller.data = data;
+ caller.usage = usage;
+
+ msg.set_arg0(target);
+ msg.set_arg1(size);
+ msg.set_arg2(ToInt(data));
+ msg.set_arg3(usage);
+
+ // FIXME: check for pointer usage
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(data), size * sizeof(char));
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glBufferData);
+}
+
+void Debug_glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum target;
+ GLintptr offset;
+ GLsizeiptr size;
+ const GLvoid* data;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glBufferSubData(target, offset, size, data);
+ getDbgContextThreadSpecific()->glBufferSubData(target, offset, size, data);
+ return 0;
+ }
+ } caller;
+ caller.target = target;
+ caller.offset = offset;
+ caller.size = size;
+ caller.data = data;
+
+ msg.set_arg0(target);
+ msg.set_arg1(offset);
+ msg.set_arg2(size);
+ msg.set_arg3(ToInt(data));
+
+ // FIXME: check for pointer usage
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(data), size * sizeof(char));
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glBufferSubData);
+}
+
+GLenum Debug_glCheckFramebufferStatus(GLenum target)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum target;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ const int * ret = reinterpret_cast<const int *>(_c->glCheckFramebufferStatus(target));
+ msg.set_ret(ToInt(ret));
+ return ret;
+ }
+ } caller;
+ caller.target = target;
+
+ msg.set_arg0(target);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glCheckFramebufferStatus);
+ return reinterpret_cast<GLenum>(ret);
+}
+
+void Debug_glClear(GLbitfield mask)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLbitfield mask;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glClear(mask);
+ return 0;
+ }
+ } caller;
+ caller.mask = mask;
+
+ msg.set_arg0(mask);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glClear);
+}
+
+void Debug_glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLclampf red;
+ GLclampf green;
+ GLclampf blue;
+ GLclampf alpha;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glClearColor(red, green, blue, alpha);
+ return 0;
+ }
+ } caller;
+ caller.red = red;
+ caller.green = green;
+ caller.blue = blue;
+ caller.alpha = alpha;
+
+ msg.set_arg0(ToInt(red));
+ msg.set_arg1(ToInt(green));
+ msg.set_arg2(ToInt(blue));
+ msg.set_arg3(ToInt(alpha));
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glClearColor);
+}
+
+void Debug_glClearDepthf(GLclampf depth)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLclampf depth;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glClearDepthf(depth);
+ return 0;
+ }
+ } caller;
+ caller.depth = depth;
+
+ msg.set_arg0(ToInt(depth));
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glClearDepthf);
+}
+
+void Debug_glClearStencil(GLint s)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLint s;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glClearStencil(s);
+ return 0;
+ }
+ } caller;
+ caller.s = s;
+
+ msg.set_arg0(s);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glClearStencil);
+}
+
+void Debug_glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLboolean red;
+ GLboolean green;
+ GLboolean blue;
+ GLboolean alpha;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glColorMask(red, green, blue, alpha);
+ return 0;
+ }
+ } caller;
+ caller.red = red;
+ caller.green = green;
+ caller.blue = blue;
+ caller.alpha = alpha;
+
+ msg.set_arg0(red);
+ msg.set_arg1(green);
+ msg.set_arg2(blue);
+ msg.set_arg3(alpha);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glColorMask);
+}
+
+void Debug_glCompileShader(GLuint shader)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint shader;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glCompileShader(shader);
+ return 0;
+ }
+ } caller;
+ caller.shader = shader;
+
+ msg.set_arg0(shader);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glCompileShader);
+}
+
+// FIXME: this function has pointers, it should be hand written
+void Debug_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum target;
+ GLint level;
+ GLenum internalformat;
+ GLsizei width;
+ GLsizei height;
+ GLint border;
+ GLsizei imageSize;
+ const GLvoid* data;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
+ return 0;
+ }
+ } caller;
+ caller.target = target;
+ caller.level = level;
+ caller.internalformat = internalformat;
+ caller.width = width;
+ caller.height = height;
+ caller.border = border;
+ caller.imageSize = imageSize;
+ caller.data = data;
+
+ msg.set_arg0(target);
+ msg.set_arg1(level);
+ msg.set_arg2(internalformat);
+ msg.set_arg3(width);
+ msg.set_arg4(height);
+ msg.set_arg5(border);
+ msg.set_arg6(imageSize);
+ msg.set_arg7(ToInt(data));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glCompressedTexImage2D);
+}
+
+// FIXME: this function has pointers, it should be hand written
+void Debug_glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum target;
+ GLint level;
+ GLint xoffset;
+ GLint yoffset;
+ GLsizei width;
+ GLsizei height;
+ GLenum format;
+ GLsizei imageSize;
+ const GLvoid* data;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
+ return 0;
+ }
+ } caller;
+ caller.target = target;
+ caller.level = level;
+ caller.xoffset = xoffset;
+ caller.yoffset = yoffset;
+ caller.width = width;
+ caller.height = height;
+ caller.format = format;
+ caller.imageSize = imageSize;
+ caller.data = data;
+
+ msg.set_arg0(target);
+ msg.set_arg1(level);
+ msg.set_arg2(xoffset);
+ msg.set_arg3(yoffset);
+ msg.set_arg4(width);
+ msg.set_arg5(height);
+ msg.set_arg6(format);
+ msg.set_arg7(imageSize);
+ msg.set_arg8(ToInt(data));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glCompressedTexSubImage2D);
+}
+
+void Debug_glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum target;
+ GLint level;
+ GLenum internalformat;
+ GLint x;
+ GLint y;
+ GLsizei width;
+ GLsizei height;
+ GLint border;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
+ return 0;
+ }
+ } caller;
+ caller.target = target;
+ caller.level = level;
+ caller.internalformat = internalformat;
+ caller.x = x;
+ caller.y = y;
+ caller.width = width;
+ caller.height = height;
+ caller.border = border;
+
+ msg.set_arg0(target);
+ msg.set_arg1(level);
+ msg.set_arg2(internalformat);
+ msg.set_arg3(x);
+ msg.set_arg4(y);
+ msg.set_arg5(width);
+ msg.set_arg6(height);
+ msg.set_arg7(border);
+
+ EXTEND_Debug_glCopyTexImage2D;
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glCopyTexImage2D);
+}
+
+void Debug_glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum target;
+ GLint level;
+ GLint xoffset;
+ GLint yoffset;
+ GLint x;
+ GLint y;
+ GLsizei width;
+ GLsizei height;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
+ return 0;
+ }
+ } caller;
+ caller.target = target;
+ caller.level = level;
+ caller.xoffset = xoffset;
+ caller.yoffset = yoffset;
+ caller.x = x;
+ caller.y = y;
+ caller.width = width;
+ caller.height = height;
+
+ msg.set_arg0(target);
+ msg.set_arg1(level);
+ msg.set_arg2(xoffset);
+ msg.set_arg3(yoffset);
+ msg.set_arg4(x);
+ msg.set_arg5(y);
+ msg.set_arg6(width);
+ msg.set_arg7(height);
+
+ EXTEND_Debug_glCopyTexSubImage2D;
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glCopyTexSubImage2D);
+}
+
+GLuint Debug_glCreateProgram(void)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ const int * ret = reinterpret_cast<const int *>(_c->glCreateProgram());
+ msg.set_ret(ToInt(ret));
+ return ret;
+ }
+ } caller;
+
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glCreateProgram);
+ return reinterpret_cast<GLuint>(ret);
+}
+
+GLuint Debug_glCreateShader(GLenum type)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum type;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ const int * ret = reinterpret_cast<const int *>(_c->glCreateShader(type));
+ msg.set_ret(ToInt(ret));
+ return ret;
+ }
+ } caller;
+ caller.type = type;
+
+ msg.set_arg0(type);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glCreateShader);
+ return reinterpret_cast<GLuint>(ret);
+}
+
+void Debug_glCullFace(GLenum mode)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum mode;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glCullFace(mode);
+ return 0;
+ }
+ } caller;
+ caller.mode = mode;
+
+ msg.set_arg0(mode);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glCullFace);
+}
+
+void Debug_glDeleteBuffers(GLsizei n, const GLuint* buffers)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLsizei n;
+ const GLuint* buffers;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glDeleteBuffers(n, buffers);
+ getDbgContextThreadSpecific()->glDeleteBuffers(n, buffers);
+ return 0;
+ }
+ } caller;
+ caller.n = n;
+ caller.buffers = buffers;
+
+ msg.set_arg0(n);
+ msg.set_arg1(ToInt(buffers));
+
+ // FIXME: check for pointer usage
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(buffers), n * sizeof(GLuint));
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glDeleteBuffers);
+}
+
+void Debug_glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLsizei n;
+ const GLuint* framebuffers;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glDeleteFramebuffers(n, framebuffers);
+ return 0;
+ }
+ } caller;
+ caller.n = n;
+ caller.framebuffers = framebuffers;
+
+ msg.set_arg0(n);
+ msg.set_arg1(ToInt(framebuffers));
+
+ // FIXME: check for pointer usage
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(framebuffers), n * sizeof(GLuint));
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glDeleteFramebuffers);
+}
+
+void Debug_glDeleteProgram(GLuint program)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint program;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glDeleteProgram(program);
+ return 0;
+ }
+ } caller;
+ caller.program = program;
+
+ msg.set_arg0(program);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glDeleteProgram);
+}
+
+void Debug_glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLsizei n;
+ const GLuint* renderbuffers;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glDeleteRenderbuffers(n, renderbuffers);
+ return 0;
+ }
+ } caller;
+ caller.n = n;
+ caller.renderbuffers = renderbuffers;
+
+ msg.set_arg0(n);
+ msg.set_arg1(ToInt(renderbuffers));
+
+ // FIXME: check for pointer usage
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(renderbuffers), n * sizeof(GLuint));
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glDeleteRenderbuffers);
+}
+
+void Debug_glDeleteShader(GLuint shader)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint shader;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glDeleteShader(shader);
+ return 0;
+ }
+ } caller;
+ caller.shader = shader;
+
+ msg.set_arg0(shader);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glDeleteShader);
+}
+
+void Debug_glDeleteTextures(GLsizei n, const GLuint* textures)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLsizei n;
+ const GLuint* textures;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glDeleteTextures(n, textures);
+ return 0;
+ }
+ } caller;
+ caller.n = n;
+ caller.textures = textures;
+
+ msg.set_arg0(n);
+ msg.set_arg1(ToInt(textures));
+
+ // FIXME: check for pointer usage
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(textures), n * sizeof(GLuint));
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glDeleteTextures);
+}
+
+void Debug_glDepthFunc(GLenum func)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum func;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glDepthFunc(func);
+ return 0;
+ }
+ } caller;
+ caller.func = func;
+
+ msg.set_arg0(func);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glDepthFunc);
+}
+
+void Debug_glDepthMask(GLboolean flag)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLboolean flag;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glDepthMask(flag);
+ return 0;
+ }
+ } caller;
+ caller.flag = flag;
+
+ msg.set_arg0(flag);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glDepthMask);
+}
+
+void Debug_glDepthRangef(GLclampf zNear, GLclampf zFar)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLclampf zNear;
+ GLclampf zFar;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glDepthRangef(zNear, zFar);
+ return 0;
+ }
+ } caller;
+ caller.zNear = zNear;
+ caller.zFar = zFar;
+
+ msg.set_arg0(ToInt(zNear));
+ msg.set_arg1(ToInt(zFar));
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glDepthRangef);
+}
+
+void Debug_glDetachShader(GLuint program, GLuint shader)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint program;
+ GLuint shader;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glDetachShader(program, shader);
+ return 0;
+ }
+ } caller;
+ caller.program = program;
+ caller.shader = shader;
+
+ msg.set_arg0(program);
+ msg.set_arg1(shader);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glDetachShader);
+}
+
+void Debug_glDisable(GLenum cap)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum cap;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glDisable(cap);
+ return 0;
+ }
+ } caller;
+ caller.cap = cap;
+
+ msg.set_arg0(cap);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glDisable);
+}
+
+void Debug_glDisableVertexAttribArray(GLuint index)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint index;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glDisableVertexAttribArray(index);
+ getDbgContextThreadSpecific()->glDisableVertexAttribArray(index);
+ return 0;
+ }
+ } caller;
+ caller.index = index;
+
+ msg.set_arg0(index);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glDisableVertexAttribArray);
+}
+
+void Debug_glEnable(GLenum cap)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum cap;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glEnable(cap);
+ return 0;
+ }
+ } caller;
+ caller.cap = cap;
+
+ msg.set_arg0(cap);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glEnable);
+}
+
+void Debug_glEnableVertexAttribArray(GLuint index)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint index;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glEnableVertexAttribArray(index);
+ getDbgContextThreadSpecific()->glEnableVertexAttribArray(index);
+ return 0;
+ }
+ } caller;
+ caller.index = index;
+
+ msg.set_arg0(index);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glEnableVertexAttribArray);
+}
+
+void Debug_glFinish(void)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glFinish();
+ return 0;
+ }
+ } caller;
+
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glFinish);
+}
+
+void Debug_glFlush(void)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glFlush();
+ return 0;
+ }
+ } caller;
+
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glFlush);
+}
+
+void Debug_glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum target;
+ GLenum attachment;
+ GLenum renderbuffertarget;
+ GLuint renderbuffer;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
+ return 0;
+ }
+ } caller;
+ caller.target = target;
+ caller.attachment = attachment;
+ caller.renderbuffertarget = renderbuffertarget;
+ caller.renderbuffer = renderbuffer;
+
+ msg.set_arg0(target);
+ msg.set_arg1(attachment);
+ msg.set_arg2(renderbuffertarget);
+ msg.set_arg3(renderbuffer);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glFramebufferRenderbuffer);
+}
+
+void Debug_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum target;
+ GLenum attachment;
+ GLenum textarget;
+ GLuint texture;
+ GLint level;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glFramebufferTexture2D(target, attachment, textarget, texture, level);
+ return 0;
+ }
+ } caller;
+ caller.target = target;
+ caller.attachment = attachment;
+ caller.textarget = textarget;
+ caller.texture = texture;
+ caller.level = level;
+
+ msg.set_arg0(target);
+ msg.set_arg1(attachment);
+ msg.set_arg2(textarget);
+ msg.set_arg3(texture);
+ msg.set_arg4(level);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glFramebufferTexture2D);
+}
+
+void Debug_glFrontFace(GLenum mode)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum mode;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glFrontFace(mode);
+ return 0;
+ }
+ } caller;
+ caller.mode = mode;
+
+ msg.set_arg0(mode);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glFrontFace);
+}
+
+void Debug_glGenBuffers(GLsizei n, GLuint* buffers)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLsizei n;
+ GLuint* buffers;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ nsecs_t c0 = systemTime(timeMode);
+ _c->glGenBuffers(n, buffers);
+ msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(buffers), n * sizeof(GLuint));
+ return 0;
+ }
+ } caller;
+ caller.n = n;
+ caller.buffers = buffers;
+
+ msg.set_arg0(n);
+ msg.set_arg1(ToInt(buffers));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGenBuffers);
+}
+
+void Debug_glGenerateMipmap(GLenum target)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum target;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glGenerateMipmap(target);
+ return 0;
+ }
+ } caller;
+ caller.target = target;
+
+ msg.set_arg0(target);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGenerateMipmap);
+}
+
+void Debug_glGenFramebuffers(GLsizei n, GLuint* framebuffers)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLsizei n;
+ GLuint* framebuffers;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ nsecs_t c0 = systemTime(timeMode);
+ _c->glGenFramebuffers(n, framebuffers);
+ msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(framebuffers), n * sizeof(GLuint));
+ return 0;
+ }
+ } caller;
+ caller.n = n;
+ caller.framebuffers = framebuffers;
+
+ msg.set_arg0(n);
+ msg.set_arg1(ToInt(framebuffers));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGenFramebuffers);
+}
+
+void Debug_glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLsizei n;
+ GLuint* renderbuffers;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ nsecs_t c0 = systemTime(timeMode);
+ _c->glGenRenderbuffers(n, renderbuffers);
+ msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(renderbuffers), n * sizeof(GLuint));
+ return 0;
+ }
+ } caller;
+ caller.n = n;
+ caller.renderbuffers = renderbuffers;
+
+ msg.set_arg0(n);
+ msg.set_arg1(ToInt(renderbuffers));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGenRenderbuffers);
+}
+
+void Debug_glGenTextures(GLsizei n, GLuint* textures)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLsizei n;
+ GLuint* textures;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ nsecs_t c0 = systemTime(timeMode);
+ _c->glGenTextures(n, textures);
+ msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(textures), n * sizeof(GLuint));
+ return 0;
+ }
+ } caller;
+ caller.n = n;
+ caller.textures = textures;
+
+ msg.set_arg0(n);
+ msg.set_arg1(ToInt(textures));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGenTextures);
+}
+
+// FIXME: this function has pointers, it should be hand written
+void Debug_glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint program;
+ GLuint index;
+ GLsizei bufsize;
+ GLsizei* length;
+ GLint* size;
+ GLenum* type;
+ GLchar* name;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glGetActiveAttrib(program, index, bufsize, length, size, type, name);
+ return 0;
+ }
+ } caller;
+ caller.program = program;
+ caller.index = index;
+ caller.bufsize = bufsize;
+ caller.length = length;
+ caller.size = size;
+ caller.type = type;
+ caller.name = name;
+
+ msg.set_arg0(program);
+ msg.set_arg1(index);
+ msg.set_arg2(bufsize);
+ msg.set_arg3(ToInt(length));
+ msg.set_arg4(ToInt(size));
+ msg.set_arg5(ToInt(type));
+ msg.set_arg6(ToInt(name));
+
+ // FIXME: check for pointer usage
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(name), strlen(name) * sizeof(GLchar));
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGetActiveAttrib);
+}
+
+// FIXME: this function has pointers, it should be hand written
+void Debug_glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint program;
+ GLuint index;
+ GLsizei bufsize;
+ GLsizei* length;
+ GLint* size;
+ GLenum* type;
+ GLchar* name;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glGetActiveUniform(program, index, bufsize, length, size, type, name);
+ return 0;
+ }
+ } caller;
+ caller.program = program;
+ caller.index = index;
+ caller.bufsize = bufsize;
+ caller.length = length;
+ caller.size = size;
+ caller.type = type;
+ caller.name = name;
+
+ msg.set_arg0(program);
+ msg.set_arg1(index);
+ msg.set_arg2(bufsize);
+ msg.set_arg3(ToInt(length));
+ msg.set_arg4(ToInt(size));
+ msg.set_arg5(ToInt(type));
+ msg.set_arg6(ToInt(name));
+
+ // FIXME: check for pointer usage
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(name), strlen(name) * sizeof(GLchar));
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGetActiveUniform);
+}
+
+// FIXME: this function has pointers, it should be hand written
+void Debug_glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint program;
+ GLsizei maxcount;
+ GLsizei* count;
+ GLuint* shaders;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glGetAttachedShaders(program, maxcount, count, shaders);
+ return 0;
+ }
+ } caller;
+ caller.program = program;
+ caller.maxcount = maxcount;
+ caller.count = count;
+ caller.shaders = shaders;
+
+ msg.set_arg0(program);
+ msg.set_arg1(maxcount);
+ msg.set_arg2(ToInt(count));
+ msg.set_arg3(ToInt(shaders));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGetAttachedShaders);
+}
+
+int Debug_glGetAttribLocation(GLuint program, const GLchar* name)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint program;
+ const GLchar* name;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ const int * ret = reinterpret_cast<const int *>(_c->glGetAttribLocation(program, name));
+ msg.set_ret(ToInt(ret));
+ return ret;
+ }
+ } caller;
+ caller.program = program;
+ caller.name = name;
+
+ msg.set_arg0(program);
+ msg.set_arg1(ToInt(name));
+
+ // FIXME: check for pointer usage
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(name), strlen(name) * sizeof(GLchar));
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGetAttribLocation);
+ return reinterpret_cast<int>(ret);
+}
+
+// FIXME: this function has pointers, it should be hand written
+void Debug_glGetBooleanv(GLenum pname, GLboolean* params)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum pname;
+ GLboolean* params;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glGetBooleanv(pname, params);
+ return 0;
+ }
+ } caller;
+ caller.pname = pname;
+ caller.params = params;
+
+ msg.set_arg0(pname);
+ msg.set_arg1(ToInt(params));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGetBooleanv);
+}
+
+// FIXME: this function has pointers, it should be hand written
+void Debug_glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum target;
+ GLenum pname;
+ GLint* params;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glGetBufferParameteriv(target, pname, params);
+ return 0;
+ }
+ } caller;
+ caller.target = target;
+ caller.pname = pname;
+ caller.params = params;
+
+ msg.set_arg0(target);
+ msg.set_arg1(pname);
+ msg.set_arg2(ToInt(params));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGetBufferParameteriv);
+}
+
+GLenum Debug_glGetError(void)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ const int * ret = reinterpret_cast<const int *>(_c->glGetError());
+ msg.set_ret(ToInt(ret));
+ return ret;
+ }
+ } caller;
+
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGetError);
+ return reinterpret_cast<GLenum>(ret);
+}
+
+// FIXME: this function has pointers, it should be hand written
+void Debug_glGetFloatv(GLenum pname, GLfloat* params)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum pname;
+ GLfloat* params;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glGetFloatv(pname, params);
+ return 0;
+ }
+ } caller;
+ caller.pname = pname;
+ caller.params = params;
+
+ msg.set_arg0(pname);
+ msg.set_arg1(ToInt(params));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGetFloatv);
+}
+
+// FIXME: this function has pointers, it should be hand written
+void Debug_glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum target;
+ GLenum attachment;
+ GLenum pname;
+ GLint* params;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glGetFramebufferAttachmentParameteriv(target, attachment, pname, params);
+ return 0;
+ }
+ } caller;
+ caller.target = target;
+ caller.attachment = attachment;
+ caller.pname = pname;
+ caller.params = params;
+
+ msg.set_arg0(target);
+ msg.set_arg1(attachment);
+ msg.set_arg2(pname);
+ msg.set_arg3(ToInt(params));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGetFramebufferAttachmentParameteriv);
+}
+
+// FIXME: this function has pointers, it should be hand written
+void Debug_glGetIntegerv(GLenum pname, GLint* params)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum pname;
+ GLint* params;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glGetIntegerv(pname, params);
+ return 0;
+ }
+ } caller;
+ caller.pname = pname;
+ caller.params = params;
+
+ msg.set_arg0(pname);
+ msg.set_arg1(ToInt(params));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGetIntegerv);
+}
+
+void Debug_glGetProgramiv(GLuint program, GLenum pname, GLint* params)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint program;
+ GLenum pname;
+ GLint* params;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ nsecs_t c0 = systemTime(timeMode);
+ _c->glGetProgramiv(program, pname, params);
+ msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(params), 1 * sizeof(GLint));
+ return 0;
+ }
+ } caller;
+ caller.program = program;
+ caller.pname = pname;
+ caller.params = params;
+
+ msg.set_arg0(program);
+ msg.set_arg1(pname);
+ msg.set_arg2(ToInt(params));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGetProgramiv);
+}
+
+// FIXME: this function has pointers, it should be hand written
+void Debug_glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint program;
+ GLsizei bufsize;
+ GLsizei* length;
+ GLchar* infolog;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ nsecs_t c0 = systemTime(timeMode);
+ _c->glGetProgramInfoLog(program, bufsize, length, infolog);
+ msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(infolog), strlen(infolog) * sizeof(GLchar));
+ return 0;
+ }
+ } caller;
+ caller.program = program;
+ caller.bufsize = bufsize;
+ caller.length = length;
+ caller.infolog = infolog;
+
+ msg.set_arg0(program);
+ msg.set_arg1(bufsize);
+ msg.set_arg2(ToInt(length));
+ msg.set_arg3(ToInt(infolog));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGetProgramInfoLog);
+}
+
+// FIXME: this function has pointers, it should be hand written
+void Debug_glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum target;
+ GLenum pname;
+ GLint* params;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glGetRenderbufferParameteriv(target, pname, params);
+ return 0;
+ }
+ } caller;
+ caller.target = target;
+ caller.pname = pname;
+ caller.params = params;
+
+ msg.set_arg0(target);
+ msg.set_arg1(pname);
+ msg.set_arg2(ToInt(params));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGetRenderbufferParameteriv);
+}
+
+void Debug_glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint shader;
+ GLenum pname;
+ GLint* params;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ nsecs_t c0 = systemTime(timeMode);
+ _c->glGetShaderiv(shader, pname, params);
+ msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(params), 1 * sizeof(GLint));
+ return 0;
+ }
+ } caller;
+ caller.shader = shader;
+ caller.pname = pname;
+ caller.params = params;
+
+ msg.set_arg0(shader);
+ msg.set_arg1(pname);
+ msg.set_arg2(ToInt(params));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGetShaderiv);
+}
+
+// FIXME: this function has pointers, it should be hand written
+void Debug_glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint shader;
+ GLsizei bufsize;
+ GLsizei* length;
+ GLchar* infolog;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ nsecs_t c0 = systemTime(timeMode);
+ _c->glGetShaderInfoLog(shader, bufsize, length, infolog);
+ msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(infolog), strlen(infolog) * sizeof(GLchar));
+ return 0;
+ }
+ } caller;
+ caller.shader = shader;
+ caller.bufsize = bufsize;
+ caller.length = length;
+ caller.infolog = infolog;
+
+ msg.set_arg0(shader);
+ msg.set_arg1(bufsize);
+ msg.set_arg2(ToInt(length));
+ msg.set_arg3(ToInt(infolog));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGetShaderInfoLog);
+}
+
+// FIXME: this function has pointers, it should be hand written
+void Debug_glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum shadertype;
+ GLenum precisiontype;
+ GLint* range;
+ GLint* precision;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
+ return 0;
+ }
+ } caller;
+ caller.shadertype = shadertype;
+ caller.precisiontype = precisiontype;
+ caller.range = range;
+ caller.precision = precision;
+
+ msg.set_arg0(shadertype);
+ msg.set_arg1(precisiontype);
+ msg.set_arg2(ToInt(range));
+ msg.set_arg3(ToInt(precision));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGetShaderPrecisionFormat);
+}
+
+// FIXME: this function has pointers, it should be hand written
+void Debug_glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint shader;
+ GLsizei bufsize;
+ GLsizei* length;
+ GLchar* source;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ nsecs_t c0 = systemTime(timeMode);
+ _c->glGetShaderSource(shader, bufsize, length, source);
+ msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(source), strlen(source) * sizeof(GLchar));
+ return 0;
+ }
+ } caller;
+ caller.shader = shader;
+ caller.bufsize = bufsize;
+ caller.length = length;
+ caller.source = source;
+
+ msg.set_arg0(shader);
+ msg.set_arg1(bufsize);
+ msg.set_arg2(ToInt(length));
+ msg.set_arg3(ToInt(source));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGetShaderSource);
+}
+
+// FIXME: this function has pointers, it should be hand written
+const GLubyte* Debug_glGetString(GLenum name)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum name;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ const int * ret = reinterpret_cast<const int *>(_c->glGetString(name));
+ msg.set_ret(ToInt(ret));
+ return ret;
+ }
+ } caller;
+ caller.name = name;
+
+ msg.set_arg0(name);
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGetString);
+ return reinterpret_cast<const GLubyte*>(ret);
+}
+
+// FIXME: this function has pointers, it should be hand written
+void Debug_glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum target;
+ GLenum pname;
+ GLfloat* params;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glGetTexParameterfv(target, pname, params);
+ return 0;
+ }
+ } caller;
+ caller.target = target;
+ caller.pname = pname;
+ caller.params = params;
+
+ msg.set_arg0(target);
+ msg.set_arg1(pname);
+ msg.set_arg2(ToInt(params));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGetTexParameterfv);
+}
+
+// FIXME: this function has pointers, it should be hand written
+void Debug_glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum target;
+ GLenum pname;
+ GLint* params;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glGetTexParameteriv(target, pname, params);
+ return 0;
+ }
+ } caller;
+ caller.target = target;
+ caller.pname = pname;
+ caller.params = params;
+
+ msg.set_arg0(target);
+ msg.set_arg1(pname);
+ msg.set_arg2(ToInt(params));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGetTexParameteriv);
+}
+
+// FIXME: this function has pointers, it should be hand written
+void Debug_glGetUniformfv(GLuint program, GLint location, GLfloat* params)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint program;
+ GLint location;
+ GLfloat* params;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glGetUniformfv(program, location, params);
+ return 0;
+ }
+ } caller;
+ caller.program = program;
+ caller.location = location;
+ caller.params = params;
+
+ msg.set_arg0(program);
+ msg.set_arg1(location);
+ msg.set_arg2(ToInt(params));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGetUniformfv);
+}
+
+// FIXME: this function has pointers, it should be hand written
+void Debug_glGetUniformiv(GLuint program, GLint location, GLint* params)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint program;
+ GLint location;
+ GLint* params;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glGetUniformiv(program, location, params);
+ return 0;
+ }
+ } caller;
+ caller.program = program;
+ caller.location = location;
+ caller.params = params;
+
+ msg.set_arg0(program);
+ msg.set_arg1(location);
+ msg.set_arg2(ToInt(params));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGetUniformiv);
+}
+
+int Debug_glGetUniformLocation(GLuint program, const GLchar* name)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint program;
+ const GLchar* name;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ const int * ret = reinterpret_cast<const int *>(_c->glGetUniformLocation(program, name));
+ msg.set_ret(ToInt(ret));
+ return ret;
+ }
+ } caller;
+ caller.program = program;
+ caller.name = name;
+
+ msg.set_arg0(program);
+ msg.set_arg1(ToInt(name));
+
+ // FIXME: check for pointer usage
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(name), strlen(name) * sizeof(GLchar));
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGetUniformLocation);
+ return reinterpret_cast<int>(ret);
+}
+
+// FIXME: this function has pointers, it should be hand written
+void Debug_glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint index;
+ GLenum pname;
+ GLfloat* params;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glGetVertexAttribfv(index, pname, params);
+ return 0;
+ }
+ } caller;
+ caller.index = index;
+ caller.pname = pname;
+ caller.params = params;
+
+ msg.set_arg0(index);
+ msg.set_arg1(pname);
+ msg.set_arg2(ToInt(params));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGetVertexAttribfv);
+}
+
+// FIXME: this function has pointers, it should be hand written
+void Debug_glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint index;
+ GLenum pname;
+ GLint* params;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glGetVertexAttribiv(index, pname, params);
+ return 0;
+ }
+ } caller;
+ caller.index = index;
+ caller.pname = pname;
+ caller.params = params;
+
+ msg.set_arg0(index);
+ msg.set_arg1(pname);
+ msg.set_arg2(ToInt(params));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGetVertexAttribiv);
+}
+
+// FIXME: this function has pointers, it should be hand written
+void Debug_glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint index;
+ GLenum pname;
+ GLvoid** pointer;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glGetVertexAttribPointerv(index, pname, pointer);
+ return 0;
+ }
+ } caller;
+ caller.index = index;
+ caller.pname = pname;
+ caller.pointer = pointer;
+
+ msg.set_arg0(index);
+ msg.set_arg1(pname);
+ msg.set_arg2(ToInt(pointer));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glGetVertexAttribPointerv);
+}
+
+void Debug_glHint(GLenum target, GLenum mode)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum target;
+ GLenum mode;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glHint(target, mode);
+ return 0;
+ }
+ } caller;
+ caller.target = target;
+ caller.mode = mode;
+
+ msg.set_arg0(target);
+ msg.set_arg1(mode);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glHint);
+}
+
+GLboolean Debug_glIsBuffer(GLuint buffer)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint buffer;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ const int * ret = reinterpret_cast<const int *>(_c->glIsBuffer(buffer));
+ msg.set_ret(ToInt(ret));
+ return ret;
+ }
+ } caller;
+ caller.buffer = buffer;
+
+ msg.set_arg0(buffer);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glIsBuffer);
+ return static_cast<GLboolean>(reinterpret_cast<int>(ret));
+}
+
+GLboolean Debug_glIsEnabled(GLenum cap)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum cap;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ const int * ret = reinterpret_cast<const int *>(_c->glIsEnabled(cap));
+ msg.set_ret(ToInt(ret));
+ return ret;
+ }
+ } caller;
+ caller.cap = cap;
+
+ msg.set_arg0(cap);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glIsEnabled);
+ return static_cast<GLboolean>(reinterpret_cast<int>(ret));
+}
+
+GLboolean Debug_glIsFramebuffer(GLuint framebuffer)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint framebuffer;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ const int * ret = reinterpret_cast<const int *>(_c->glIsFramebuffer(framebuffer));
+ msg.set_ret(ToInt(ret));
+ return ret;
+ }
+ } caller;
+ caller.framebuffer = framebuffer;
+
+ msg.set_arg0(framebuffer);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glIsFramebuffer);
+ return static_cast<GLboolean>(reinterpret_cast<int>(ret));
+}
+
+GLboolean Debug_glIsProgram(GLuint program)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint program;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ const int * ret = reinterpret_cast<const int *>(_c->glIsProgram(program));
+ msg.set_ret(ToInt(ret));
+ return ret;
+ }
+ } caller;
+ caller.program = program;
+
+ msg.set_arg0(program);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glIsProgram);
+ return static_cast<GLboolean>(reinterpret_cast<int>(ret));
+}
+
+GLboolean Debug_glIsRenderbuffer(GLuint renderbuffer)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint renderbuffer;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ const int * ret = reinterpret_cast<const int *>(_c->glIsRenderbuffer(renderbuffer));
+ msg.set_ret(ToInt(ret));
+ return ret;
+ }
+ } caller;
+ caller.renderbuffer = renderbuffer;
+
+ msg.set_arg0(renderbuffer);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glIsRenderbuffer);
+ return static_cast<GLboolean>(reinterpret_cast<int>(ret));
+}
+
+GLboolean Debug_glIsShader(GLuint shader)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint shader;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ const int * ret = reinterpret_cast<const int *>(_c->glIsShader(shader));
+ msg.set_ret(ToInt(ret));
+ return ret;
+ }
+ } caller;
+ caller.shader = shader;
+
+ msg.set_arg0(shader);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glIsShader);
+ return static_cast<GLboolean>(reinterpret_cast<int>(ret));
+}
+
+GLboolean Debug_glIsTexture(GLuint texture)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint texture;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ const int * ret = reinterpret_cast<const int *>(_c->glIsTexture(texture));
+ msg.set_ret(ToInt(ret));
+ return ret;
+ }
+ } caller;
+ caller.texture = texture;
+
+ msg.set_arg0(texture);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glIsTexture);
+ return static_cast<GLboolean>(reinterpret_cast<int>(ret));
+}
+
+void Debug_glLineWidth(GLfloat width)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLfloat width;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glLineWidth(width);
+ return 0;
+ }
+ } caller;
+ caller.width = width;
+
+ msg.set_arg0(ToInt(width));
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glLineWidth);
+}
+
+void Debug_glLinkProgram(GLuint program)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint program;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glLinkProgram(program);
+ return 0;
+ }
+ } caller;
+ caller.program = program;
+
+ msg.set_arg0(program);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glLinkProgram);
+}
+
+void Debug_glPixelStorei(GLenum pname, GLint param)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum pname;
+ GLint param;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glPixelStorei(pname, param);
+ return 0;
+ }
+ } caller;
+ caller.pname = pname;
+ caller.param = param;
+
+ msg.set_arg0(pname);
+ msg.set_arg1(param);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glPixelStorei);
+}
+
+void Debug_glPolygonOffset(GLfloat factor, GLfloat units)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLfloat factor;
+ GLfloat units;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glPolygonOffset(factor, units);
+ return 0;
+ }
+ } caller;
+ caller.factor = factor;
+ caller.units = units;
+
+ msg.set_arg0(ToInt(factor));
+ msg.set_arg1(ToInt(units));
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glPolygonOffset);
+}
+
+void Debug_glReleaseShaderCompiler(void)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glReleaseShaderCompiler();
+ return 0;
+ }
+ } caller;
+
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glReleaseShaderCompiler);
+}
+
+void Debug_glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum target;
+ GLenum internalformat;
+ GLsizei width;
+ GLsizei height;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glRenderbufferStorage(target, internalformat, width, height);
+ return 0;
+ }
+ } caller;
+ caller.target = target;
+ caller.internalformat = internalformat;
+ caller.width = width;
+ caller.height = height;
+
+ msg.set_arg0(target);
+ msg.set_arg1(internalformat);
+ msg.set_arg2(width);
+ msg.set_arg3(height);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glRenderbufferStorage);
+}
+
+void Debug_glSampleCoverage(GLclampf value, GLboolean invert)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLclampf value;
+ GLboolean invert;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glSampleCoverage(value, invert);
+ return 0;
+ }
+ } caller;
+ caller.value = value;
+ caller.invert = invert;
+
+ msg.set_arg0(ToInt(value));
+ msg.set_arg1(invert);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glSampleCoverage);
+}
+
+void Debug_glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLint x;
+ GLint y;
+ GLsizei width;
+ GLsizei height;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glScissor(x, y, width, height);
+ return 0;
+ }
+ } caller;
+ caller.x = x;
+ caller.y = y;
+ caller.width = width;
+ caller.height = height;
+
+ msg.set_arg0(x);
+ msg.set_arg1(y);
+ msg.set_arg2(width);
+ msg.set_arg3(height);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glScissor);
+}
+
+// FIXME: this function has pointers, it should be hand written
+void Debug_glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLsizei n;
+ const GLuint* shaders;
+ GLenum binaryformat;
+ const GLvoid* binary;
+ GLsizei length;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glShaderBinary(n, shaders, binaryformat, binary, length);
+ return 0;
+ }
+ } caller;
+ caller.n = n;
+ caller.shaders = shaders;
+ caller.binaryformat = binaryformat;
+ caller.binary = binary;
+ caller.length = length;
+
+ msg.set_arg0(n);
+ msg.set_arg1(ToInt(shaders));
+ msg.set_arg2(binaryformat);
+ msg.set_arg3(ToInt(binary));
+ msg.set_arg4(length);
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glShaderBinary);
+}
+
+void Debug_glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint shader;
+ GLsizei count;
+ const GLchar** string;
+ const GLint* length;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glShaderSource(shader, count, string, length);
+ return 0;
+ }
+ } caller;
+ caller.shader = shader;
+ caller.count = count;
+ caller.string = string;
+ caller.length = length;
+
+ msg.set_arg0(shader);
+ msg.set_arg1(count);
+ msg.set_arg2(ToInt(string));
+ msg.set_arg3(ToInt(length));
+
+ // FIXME: check for pointer usage
+ EXTEND_Debug_glShaderSource;
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glShaderSource);
+}
+
+void Debug_glStencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum func;
+ GLint ref;
+ GLuint mask;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glStencilFunc(func, ref, mask);
+ return 0;
+ }
+ } caller;
+ caller.func = func;
+ caller.ref = ref;
+ caller.mask = mask;
+
+ msg.set_arg0(func);
+ msg.set_arg1(ref);
+ msg.set_arg2(mask);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glStencilFunc);
+}
+
+void Debug_glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum face;
+ GLenum func;
+ GLint ref;
+ GLuint mask;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glStencilFuncSeparate(face, func, ref, mask);
+ return 0;
+ }
+ } caller;
+ caller.face = face;
+ caller.func = func;
+ caller.ref = ref;
+ caller.mask = mask;
+
+ msg.set_arg0(face);
+ msg.set_arg1(func);
+ msg.set_arg2(ref);
+ msg.set_arg3(mask);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glStencilFuncSeparate);
+}
+
+void Debug_glStencilMask(GLuint mask)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint mask;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glStencilMask(mask);
+ return 0;
+ }
+ } caller;
+ caller.mask = mask;
+
+ msg.set_arg0(mask);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glStencilMask);
+}
+
+void Debug_glStencilMaskSeparate(GLenum face, GLuint mask)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum face;
+ GLuint mask;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glStencilMaskSeparate(face, mask);
+ return 0;
+ }
+ } caller;
+ caller.face = face;
+ caller.mask = mask;
+
+ msg.set_arg0(face);
+ msg.set_arg1(mask);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glStencilMaskSeparate);
+}
+
+void Debug_glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum fail;
+ GLenum zfail;
+ GLenum zpass;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glStencilOp(fail, zfail, zpass);
+ return 0;
+ }
+ } caller;
+ caller.fail = fail;
+ caller.zfail = zfail;
+ caller.zpass = zpass;
+
+ msg.set_arg0(fail);
+ msg.set_arg1(zfail);
+ msg.set_arg2(zpass);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glStencilOp);
+}
+
+void Debug_glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum face;
+ GLenum fail;
+ GLenum zfail;
+ GLenum zpass;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glStencilOpSeparate(face, fail, zfail, zpass);
+ return 0;
+ }
+ } caller;
+ caller.face = face;
+ caller.fail = fail;
+ caller.zfail = zfail;
+ caller.zpass = zpass;
+
+ msg.set_arg0(face);
+ msg.set_arg1(fail);
+ msg.set_arg2(zfail);
+ msg.set_arg3(zpass);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glStencilOpSeparate);
+}
+
+void Debug_glTexParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum target;
+ GLenum pname;
+ GLfloat param;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glTexParameterf(target, pname, param);
+ return 0;
+ }
+ } caller;
+ caller.target = target;
+ caller.pname = pname;
+ caller.param = param;
+
+ msg.set_arg0(target);
+ msg.set_arg1(pname);
+ msg.set_arg2(ToInt(param));
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glTexParameterf);
+}
+
+// FIXME: this function has pointers, it should be hand written
+void Debug_glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum target;
+ GLenum pname;
+ const GLfloat* params;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glTexParameterfv(target, pname, params);
+ return 0;
+ }
+ } caller;
+ caller.target = target;
+ caller.pname = pname;
+ caller.params = params;
+
+ msg.set_arg0(target);
+ msg.set_arg1(pname);
+ msg.set_arg2(ToInt(params));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glTexParameterfv);
+}
+
+void Debug_glTexParameteri(GLenum target, GLenum pname, GLint param)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum target;
+ GLenum pname;
+ GLint param;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glTexParameteri(target, pname, param);
+ return 0;
+ }
+ } caller;
+ caller.target = target;
+ caller.pname = pname;
+ caller.param = param;
+
+ msg.set_arg0(target);
+ msg.set_arg1(pname);
+ msg.set_arg2(param);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glTexParameteri);
+}
+
+// FIXME: this function has pointers, it should be hand written
+void Debug_glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum target;
+ GLenum pname;
+ const GLint* params;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glTexParameteriv(target, pname, params);
+ return 0;
+ }
+ } caller;
+ caller.target = target;
+ caller.pname = pname;
+ caller.params = params;
+
+ msg.set_arg0(target);
+ msg.set_arg1(pname);
+ msg.set_arg2(ToInt(params));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glTexParameteriv);
+}
+
+void Debug_glUniform1f(GLint location, GLfloat x)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLint location;
+ GLfloat x;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glUniform1f(location, x);
+ return 0;
+ }
+ } caller;
+ caller.location = location;
+ caller.x = x;
+
+ msg.set_arg0(location);
+ msg.set_arg1(ToInt(x));
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glUniform1f);
+}
+
+void Debug_glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLint location;
+ GLsizei count;
+ const GLfloat* v;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glUniform1fv(location, count, v);
+ return 0;
+ }
+ } caller;
+ caller.location = location;
+ caller.count = count;
+ caller.v = v;
+
+ msg.set_arg0(location);
+ msg.set_arg1(count);
+ msg.set_arg2(ToInt(v));
+
+ // FIXME: check for pointer usage
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 1*count * sizeof(GLfloat));
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glUniform1fv);
+}
+
+void Debug_glUniform1i(GLint location, GLint x)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLint location;
+ GLint x;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glUniform1i(location, x);
+ return 0;
+ }
+ } caller;
+ caller.location = location;
+ caller.x = x;
+
+ msg.set_arg0(location);
+ msg.set_arg1(x);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glUniform1i);
+}
+
+void Debug_glUniform1iv(GLint location, GLsizei count, const GLint* v)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLint location;
+ GLsizei count;
+ const GLint* v;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glUniform1iv(location, count, v);
+ return 0;
+ }
+ } caller;
+ caller.location = location;
+ caller.count = count;
+ caller.v = v;
+
+ msg.set_arg0(location);
+ msg.set_arg1(count);
+ msg.set_arg2(ToInt(v));
+
+ // FIXME: check for pointer usage
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 1*count * sizeof(GLint));
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glUniform1iv);
+}
+
+void Debug_glUniform2f(GLint location, GLfloat x, GLfloat y)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLint location;
+ GLfloat x;
+ GLfloat y;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glUniform2f(location, x, y);
+ return 0;
+ }
+ } caller;
+ caller.location = location;
+ caller.x = x;
+ caller.y = y;
+
+ msg.set_arg0(location);
+ msg.set_arg1(ToInt(x));
+ msg.set_arg2(ToInt(y));
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glUniform2f);
+}
+
+void Debug_glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLint location;
+ GLsizei count;
+ const GLfloat* v;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glUniform2fv(location, count, v);
+ return 0;
+ }
+ } caller;
+ caller.location = location;
+ caller.count = count;
+ caller.v = v;
+
+ msg.set_arg0(location);
+ msg.set_arg1(count);
+ msg.set_arg2(ToInt(v));
+
+ // FIXME: check for pointer usage
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 2*count * sizeof(GLfloat));
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glUniform2fv);
+}
+
+void Debug_glUniform2i(GLint location, GLint x, GLint y)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLint location;
+ GLint x;
+ GLint y;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glUniform2i(location, x, y);
+ return 0;
+ }
+ } caller;
+ caller.location = location;
+ caller.x = x;
+ caller.y = y;
+
+ msg.set_arg0(location);
+ msg.set_arg1(x);
+ msg.set_arg2(y);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glUniform2i);
+}
+
+void Debug_glUniform2iv(GLint location, GLsizei count, const GLint* v)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLint location;
+ GLsizei count;
+ const GLint* v;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glUniform2iv(location, count, v);
+ return 0;
+ }
+ } caller;
+ caller.location = location;
+ caller.count = count;
+ caller.v = v;
+
+ msg.set_arg0(location);
+ msg.set_arg1(count);
+ msg.set_arg2(ToInt(v));
+
+ // FIXME: check for pointer usage
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 2*count * sizeof(GLint));
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glUniform2iv);
+}
+
+void Debug_glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLint location;
+ GLfloat x;
+ GLfloat y;
+ GLfloat z;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glUniform3f(location, x, y, z);
+ return 0;
+ }
+ } caller;
+ caller.location = location;
+ caller.x = x;
+ caller.y = y;
+ caller.z = z;
+
+ msg.set_arg0(location);
+ msg.set_arg1(ToInt(x));
+ msg.set_arg2(ToInt(y));
+ msg.set_arg3(ToInt(z));
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glUniform3f);
+}
+
+void Debug_glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLint location;
+ GLsizei count;
+ const GLfloat* v;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glUniform3fv(location, count, v);
+ return 0;
+ }
+ } caller;
+ caller.location = location;
+ caller.count = count;
+ caller.v = v;
+
+ msg.set_arg0(location);
+ msg.set_arg1(count);
+ msg.set_arg2(ToInt(v));
+
+ // FIXME: check for pointer usage
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 3*count * sizeof(GLfloat));
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glUniform3fv);
+}
+
+void Debug_glUniform3i(GLint location, GLint x, GLint y, GLint z)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLint location;
+ GLint x;
+ GLint y;
+ GLint z;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glUniform3i(location, x, y, z);
+ return 0;
+ }
+ } caller;
+ caller.location = location;
+ caller.x = x;
+ caller.y = y;
+ caller.z = z;
+
+ msg.set_arg0(location);
+ msg.set_arg1(x);
+ msg.set_arg2(y);
+ msg.set_arg3(z);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glUniform3i);
+}
+
+void Debug_glUniform3iv(GLint location, GLsizei count, const GLint* v)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLint location;
+ GLsizei count;
+ const GLint* v;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glUniform3iv(location, count, v);
+ return 0;
+ }
+ } caller;
+ caller.location = location;
+ caller.count = count;
+ caller.v = v;
+
+ msg.set_arg0(location);
+ msg.set_arg1(count);
+ msg.set_arg2(ToInt(v));
+
+ // FIXME: check for pointer usage
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 3*count * sizeof(GLint));
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glUniform3iv);
+}
+
+void Debug_glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLint location;
+ GLfloat x;
+ GLfloat y;
+ GLfloat z;
+ GLfloat w;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glUniform4f(location, x, y, z, w);
+ return 0;
+ }
+ } caller;
+ caller.location = location;
+ caller.x = x;
+ caller.y = y;
+ caller.z = z;
+ caller.w = w;
+
+ msg.set_arg0(location);
+ msg.set_arg1(ToInt(x));
+ msg.set_arg2(ToInt(y));
+ msg.set_arg3(ToInt(z));
+ msg.set_arg4(ToInt(w));
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glUniform4f);
+}
+
+void Debug_glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLint location;
+ GLsizei count;
+ const GLfloat* v;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glUniform4fv(location, count, v);
+ return 0;
+ }
+ } caller;
+ caller.location = location;
+ caller.count = count;
+ caller.v = v;
+
+ msg.set_arg0(location);
+ msg.set_arg1(count);
+ msg.set_arg2(ToInt(v));
+
+ // FIXME: check for pointer usage
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 4*count * sizeof(GLfloat));
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glUniform4fv);
+}
+
+void Debug_glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLint location;
+ GLint x;
+ GLint y;
+ GLint z;
+ GLint w;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glUniform4i(location, x, y, z, w);
+ return 0;
+ }
+ } caller;
+ caller.location = location;
+ caller.x = x;
+ caller.y = y;
+ caller.z = z;
+ caller.w = w;
+
+ msg.set_arg0(location);
+ msg.set_arg1(x);
+ msg.set_arg2(y);
+ msg.set_arg3(z);
+ msg.set_arg4(w);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glUniform4i);
+}
+
+void Debug_glUniform4iv(GLint location, GLsizei count, const GLint* v)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLint location;
+ GLsizei count;
+ const GLint* v;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glUniform4iv(location, count, v);
+ return 0;
+ }
+ } caller;
+ caller.location = location;
+ caller.count = count;
+ caller.v = v;
+
+ msg.set_arg0(location);
+ msg.set_arg1(count);
+ msg.set_arg2(ToInt(v));
+
+ // FIXME: check for pointer usage
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 4*count * sizeof(GLint));
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glUniform4iv);
+}
+
+void Debug_glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLint location;
+ GLsizei count;
+ GLboolean transpose;
+ const GLfloat* value;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glUniformMatrix2fv(location, count, transpose, value);
+ return 0;
+ }
+ } caller;
+ caller.location = location;
+ caller.count = count;
+ caller.transpose = transpose;
+ caller.value = value;
+
+ msg.set_arg0(location);
+ msg.set_arg1(count);
+ msg.set_arg2(transpose);
+ msg.set_arg3(ToInt(value));
+
+ // FIXME: check for pointer usage
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(value), 4*count * sizeof(GLfloat));
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glUniformMatrix2fv);
+}
+
+void Debug_glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLint location;
+ GLsizei count;
+ GLboolean transpose;
+ const GLfloat* value;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glUniformMatrix3fv(location, count, transpose, value);
+ return 0;
+ }
+ } caller;
+ caller.location = location;
+ caller.count = count;
+ caller.transpose = transpose;
+ caller.value = value;
+
+ msg.set_arg0(location);
+ msg.set_arg1(count);
+ msg.set_arg2(transpose);
+ msg.set_arg3(ToInt(value));
+
+ // FIXME: check for pointer usage
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(value), 9*count * sizeof(GLfloat));
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glUniformMatrix3fv);
+}
+
+void Debug_glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLint location;
+ GLsizei count;
+ GLboolean transpose;
+ const GLfloat* value;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glUniformMatrix4fv(location, count, transpose, value);
+ return 0;
+ }
+ } caller;
+ caller.location = location;
+ caller.count = count;
+ caller.transpose = transpose;
+ caller.value = value;
+
+ msg.set_arg0(location);
+ msg.set_arg1(count);
+ msg.set_arg2(transpose);
+ msg.set_arg3(ToInt(value));
+
+ // FIXME: check for pointer usage
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(value), 16*count * sizeof(GLfloat));
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glUniformMatrix4fv);
+}
+
+void Debug_glUseProgram(GLuint program)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint program;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glUseProgram(program);
+ getDbgContextThreadSpecific()->glUseProgram(program);
+ return 0;
+ }
+ } caller;
+ caller.program = program;
+
+ msg.set_arg0(program);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glUseProgram);
+}
+
+void Debug_glValidateProgram(GLuint program)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint program;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glValidateProgram(program);
+ return 0;
+ }
+ } caller;
+ caller.program = program;
+
+ msg.set_arg0(program);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glValidateProgram);
+}
+
+void Debug_glVertexAttrib1f(GLuint indx, GLfloat x)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint indx;
+ GLfloat x;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glVertexAttrib1f(indx, x);
+ return 0;
+ }
+ } caller;
+ caller.indx = indx;
+ caller.x = x;
+
+ msg.set_arg0(indx);
+ msg.set_arg1(ToInt(x));
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glVertexAttrib1f);
+}
+
+void Debug_glVertexAttrib1fv(GLuint indx, const GLfloat* values)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint indx;
+ const GLfloat* values;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glVertexAttrib1fv(indx, values);
+ return 0;
+ }
+ } caller;
+ caller.indx = indx;
+ caller.values = values;
+
+ msg.set_arg0(indx);
+ msg.set_arg1(ToInt(values));
+
+ // FIXME: check for pointer usage
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(values), 1 * sizeof(GLfloat));
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glVertexAttrib1fv);
+}
+
+void Debug_glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint indx;
+ GLfloat x;
+ GLfloat y;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glVertexAttrib2f(indx, x, y);
+ return 0;
+ }
+ } caller;
+ caller.indx = indx;
+ caller.x = x;
+ caller.y = y;
+
+ msg.set_arg0(indx);
+ msg.set_arg1(ToInt(x));
+ msg.set_arg2(ToInt(y));
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glVertexAttrib2f);
+}
+
+void Debug_glVertexAttrib2fv(GLuint indx, const GLfloat* values)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint indx;
+ const GLfloat* values;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glVertexAttrib2fv(indx, values);
+ return 0;
+ }
+ } caller;
+ caller.indx = indx;
+ caller.values = values;
+
+ msg.set_arg0(indx);
+ msg.set_arg1(ToInt(values));
+
+ // FIXME: check for pointer usage
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(values), 2 * sizeof(GLfloat));
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glVertexAttrib2fv);
+}
+
+void Debug_glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint indx;
+ GLfloat x;
+ GLfloat y;
+ GLfloat z;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glVertexAttrib3f(indx, x, y, z);
+ return 0;
+ }
+ } caller;
+ caller.indx = indx;
+ caller.x = x;
+ caller.y = y;
+ caller.z = z;
+
+ msg.set_arg0(indx);
+ msg.set_arg1(ToInt(x));
+ msg.set_arg2(ToInt(y));
+ msg.set_arg3(ToInt(z));
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glVertexAttrib3f);
+}
+
+void Debug_glVertexAttrib3fv(GLuint indx, const GLfloat* values)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint indx;
+ const GLfloat* values;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glVertexAttrib3fv(indx, values);
+ return 0;
+ }
+ } caller;
+ caller.indx = indx;
+ caller.values = values;
+
+ msg.set_arg0(indx);
+ msg.set_arg1(ToInt(values));
+
+ // FIXME: check for pointer usage
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(values), 3 * sizeof(GLfloat));
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glVertexAttrib3fv);
+}
+
+void Debug_glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint indx;
+ GLfloat x;
+ GLfloat y;
+ GLfloat z;
+ GLfloat w;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glVertexAttrib4f(indx, x, y, z, w);
+ return 0;
+ }
+ } caller;
+ caller.indx = indx;
+ caller.x = x;
+ caller.y = y;
+ caller.z = z;
+ caller.w = w;
+
+ msg.set_arg0(indx);
+ msg.set_arg1(ToInt(x));
+ msg.set_arg2(ToInt(y));
+ msg.set_arg3(ToInt(z));
+ msg.set_arg4(ToInt(w));
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glVertexAttrib4f);
+}
+
+void Debug_glVertexAttrib4fv(GLuint indx, const GLfloat* values)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint indx;
+ const GLfloat* values;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glVertexAttrib4fv(indx, values);
+ return 0;
+ }
+ } caller;
+ caller.indx = indx;
+ caller.values = values;
+
+ msg.set_arg0(indx);
+ msg.set_arg1(ToInt(values));
+
+ // FIXME: check for pointer usage
+ msg.mutable_data()->assign(reinterpret_cast<const char *>(values), 4 * sizeof(GLfloat));
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glVertexAttrib4fv);
+}
+
+// FIXME: this function has pointers, it should be hand written
+void Debug_glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLuint indx;
+ GLint size;
+ GLenum type;
+ GLboolean normalized;
+ GLsizei stride;
+ const GLvoid* ptr;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
+ getDbgContextThreadSpecific()->glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
+ return 0;
+ }
+ } caller;
+ caller.indx = indx;
+ caller.size = size;
+ caller.type = type;
+ caller.normalized = normalized;
+ caller.stride = stride;
+ caller.ptr = ptr;
+
+ msg.set_arg0(indx);
+ msg.set_arg1(size);
+ msg.set_arg2(type);
+ msg.set_arg3(normalized);
+ msg.set_arg4(stride);
+ msg.set_arg5(ToInt(ptr));
+
+ // FIXME: check for pointer usage
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glVertexAttribPointer);
+}
+
+void Debug_glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLint x;
+ GLint y;
+ GLsizei width;
+ GLsizei height;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ _c->glViewport(x, y, width, height);
+ return 0;
+ }
+ } caller;
+ caller.x = x;
+ caller.y = y;
+ caller.width = width;
+ caller.height = height;
+
+ msg.set_arg0(x);
+ msg.set_arg1(y);
+ msg.set_arg2(width);
+ msg.set_arg3(height);
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glViewport);
+}
+
+// FIXME: the following functions should be written by hand
+void Debug_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data);
+void Debug_glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data);
+void Debug_glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+void Debug_glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+void Debug_glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
+void Debug_glGetBooleanv(GLenum pname, GLboolean* params);
+void Debug_glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params);
+void Debug_glGetFloatv(GLenum pname, GLfloat* params);
+void Debug_glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params);
+void Debug_glGetIntegerv(GLenum pname, GLint* params);
+void Debug_glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog);
+void Debug_glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params);
+void Debug_glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog);
+void Debug_glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
+void Debug_glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source);
+const GLubyte* Debug_glGetString(GLenum name);
+void Debug_glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
+void Debug_glGetTexParameteriv(GLenum target, GLenum pname, GLint* params);
+void Debug_glGetUniformfv(GLuint program, GLint location, GLfloat* params);
+void Debug_glGetUniformiv(GLuint program, GLint location, GLint* params);
+void Debug_glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params);
+void Debug_glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params);
+void Debug_glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer);
+void Debug_glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length);
+void Debug_glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
+void Debug_glTexParameteriv(GLenum target, GLenum pname, const GLint* params);
+void Debug_glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr);
diff --git a/opengl/libs/GLES2_dbg/src/api.h b/opengl/libs/GLES2_dbg/src/api.h
new file mode 100644
index 0000000..be94dfc
--- /dev/null
+++ b/opengl/libs/GLES2_dbg/src/api.h
@@ -0,0 +1,31 @@
+/*
+ ** Copyright 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.
+ */
+
+#define EXTEND_Debug_glCopyTexImage2D \
+ void * pixels = malloc(width * height * 4); \
+ getGLTraceThreadSpecific()->gl.glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); \
+ msg.set_data(pixels, width * height * 4); \
+ free(pixels);
+
+#define EXTEND_Debug_glCopyTexSubImage2D EXTEND_Debug_glCopyTexImage2D
+
+#define EXTEND_Debug_glShaderSource \
+ std::string * const data = msg.mutable_data(); \
+ for (unsigned i = 0; i < count; i++) \
+ if (!length || length[i] < 0) \
+ data->append(string[i]); \
+ else \
+ data->append(string[i], length[i]);
\ No newline at end of file
diff --git a/opengl/libs/GLES2_dbg/src/caller.h b/opengl/libs/GLES2_dbg/src/caller.h
new file mode 100644
index 0000000..01bc4ea
--- /dev/null
+++ b/opengl/libs/GLES2_dbg/src/caller.h
@@ -0,0 +1,19 @@
+/*
+ ** Copyright 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.
+ */
+
+#include "src/header.h"
+
+
diff --git a/opengl/libs/GLES2_dbg/src/dbgcontext.cpp b/opengl/libs/GLES2_dbg/src/dbgcontext.cpp
new file mode 100644
index 0000000..68514df
--- /dev/null
+++ b/opengl/libs/GLES2_dbg/src/dbgcontext.cpp
@@ -0,0 +1,243 @@
+/*
+ ** Copyright 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.
+ */
+
+#include "header.h"
+
+namespace android
+{
+
+DbgContext::DbgContext(const unsigned version, const gl_hooks_t * const hooks,
+ const unsigned MAX_VERTEX_ATTRIBS)
+ : version(version), hooks(hooks)
+ , MAX_VERTEX_ATTRIBS(MAX_VERTEX_ATTRIBS)
+ , vertexAttribs(new VertexAttrib[MAX_VERTEX_ATTRIBS])
+ , hasNonVBOAttribs(false), indexBuffers(NULL), indexBuffer(NULL)
+{
+ for (unsigned i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+ vertexAttribs[i] = VertexAttrib();
+}
+
+DbgContext::~DbgContext()
+{
+ delete vertexAttribs;
+}
+
+DbgContext * CreateDbgContext(const unsigned version, const gl_hooks_t * const hooks)
+{
+ assert(version < 2);
+ assert(GL_NO_ERROR == hooks->gl.glGetError());
+ GLint MAX_VERTEX_ATTRIBS = 0;
+ hooks->gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &MAX_VERTEX_ATTRIBS);
+ return new DbgContext(version, hooks, MAX_VERTEX_ATTRIBS);
+}
+
+void DestroyDbgContext(DbgContext * const dbg)
+{
+ delete dbg;
+}
+
+void DbgContext::Fetch(const unsigned index, std::string * const data) const
+{
+ // VBO data is already on client, just send user pointer data
+ for (unsigned i = 0; i < maxAttrib; i++) {
+ if (!vertexAttribs[i].enabled)
+ continue;
+ if (vertexAttribs[i].buffer > 0)
+ continue;
+ const char * ptr = (const char *)vertexAttribs[i].ptr;
+ ptr += index * vertexAttribs[i].stride;
+ data->append(ptr, vertexAttribs[i].elemSize);
+ }
+}
+
+void DbgContext::glUseProgram(GLuint program)
+{
+ assert(GL_NO_ERROR == hooks->gl.glGetError());
+
+ this->program = program;
+
+ GLint activeAttributes = 0;
+ hooks->gl.glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &activeAttributes);
+ maxAttrib = 0;
+ GLint maxNameLen = -1;
+ hooks->gl.glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxNameLen);
+ char * name = new char [maxNameLen + 1];
+ name[maxNameLen] = 0;
+ // find total number of attribute slots used
+ for (unsigned i = 0; i < activeAttributes; i++) {
+ GLint size = -1;
+ GLenum type = -1;
+ hooks->gl.glGetActiveAttrib(program, i, maxNameLen + 1, NULL, &size, &type, name);
+ GLint slot = hooks->gl.glGetAttribLocation(program, name);
+ assert(slot >= 0);
+ switch (type) {
+ case GL_FLOAT:
+ case GL_FLOAT_VEC2:
+ case GL_FLOAT_VEC3:
+ case GL_FLOAT_VEC4:
+ slot += size;
+ break;
+ case GL_FLOAT_MAT2:
+ slot += size * 2;
+ break;
+ case GL_FLOAT_MAT3:
+ slot += size * 3;
+ break;
+ case GL_FLOAT_MAT4:
+ slot += size * 4;
+ break;
+ default:
+ assert(0);
+ }
+ if (slot > maxAttrib)
+ maxAttrib = slot;
+ }
+ delete name;
+}
+
+static bool HasNonVBOAttribs(const DbgContext * const ctx)
+{
+ bool need = false;
+ for (unsigned i = 0; !need && i < ctx->maxAttrib; i++)
+ if (ctx->vertexAttribs[i].enabled && ctx->vertexAttribs[i].buffer == 0)
+ need = true;
+ return need;
+}
+
+void DbgContext::glVertexAttribPointer(GLuint indx, GLint size, GLenum type,
+ GLboolean normalized, GLsizei stride, const GLvoid* ptr)
+{
+ assert(GL_NO_ERROR == hooks->gl.glGetError());
+ assert(indx < MAX_VERTEX_ATTRIBS);
+ vertexAttribs[indx].size = size;
+ vertexAttribs[indx].type = type;
+ vertexAttribs[indx].normalized = normalized;
+ switch (type) {
+ case GL_FLOAT:
+ vertexAttribs[indx].elemSize = sizeof(GLfloat) * size;
+ break;
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ vertexAttribs[indx].elemSize = sizeof(GLint) * size;
+ break;
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ vertexAttribs[indx].elemSize = sizeof(GLshort) * size;
+ break;
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ vertexAttribs[indx].elemSize = sizeof(GLbyte) * size;
+ break;
+ default:
+ assert(0);
+ }
+ if (0 == stride)
+ stride = vertexAttribs[indx].elemSize;
+ vertexAttribs[indx].stride = stride;
+ vertexAttribs[indx].ptr = ptr;
+ hooks->gl.glGetVertexAttribiv(indx, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING,
+ (GLint *)&vertexAttribs[indx].buffer);
+ hasNonVBOAttribs = HasNonVBOAttribs(this);
+}
+
+void DbgContext::glEnableVertexAttribArray(GLuint index)
+{
+ assert(index < MAX_VERTEX_ATTRIBS);
+ vertexAttribs[index].enabled = true;
+ hasNonVBOAttribs = HasNonVBOAttribs(this);
+}
+
+void DbgContext::glDisableVertexAttribArray(GLuint index)
+{
+ assert(index < MAX_VERTEX_ATTRIBS);
+ vertexAttribs[index].enabled = false;
+ hasNonVBOAttribs = HasNonVBOAttribs(this);
+}
+
+void DbgContext::glBindBuffer(GLenum target, GLuint buffer)
+{
+ if (GL_ELEMENT_ARRAY_BUFFER != target)
+ return;
+ if (0 == buffer) {
+ indexBuffer = NULL;
+ return;
+ }
+ VBO * b = indexBuffers;
+ indexBuffer = NULL;
+ while (b) {
+ if (b->name == buffer) {
+ assert(GL_ELEMENT_ARRAY_BUFFER == b->target);
+ indexBuffer = b;
+ break;
+ }
+ b = b->next;
+ }
+ if (!indexBuffer)
+ indexBuffer = indexBuffers = new VBO(buffer, target, indexBuffers);
+}
+
+void DbgContext::glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
+{
+ if (GL_ELEMENT_ARRAY_BUFFER != target)
+ return;
+ assert(indexBuffer);
+ assert(size >= 0);
+ indexBuffer->size = size;
+ indexBuffer->data = realloc(indexBuffer->data, size);
+ memcpy(indexBuffer->data, data, size);
+}
+
+void DbgContext::glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
+{
+ if (GL_ELEMENT_ARRAY_BUFFER != target)
+ return;
+ assert(indexBuffer);
+ assert(size >= 0);
+ assert(offset >= 0);
+ assert(offset + size <= indexBuffer->size);
+ memcpy((char *)indexBuffer->data + offset, data, size);
+}
+
+void DbgContext::glDeleteBuffers(GLsizei n, const GLuint *buffers)
+{
+ for (unsigned i = 0; i < n; i++) {
+ for (unsigned j = 0; j < MAX_VERTEX_ATTRIBS; j++)
+ if (buffers[i] == vertexAttribs[j].buffer) {
+ vertexAttribs[j].buffer = 0;
+ vertexAttribs[j].enabled = false;
+ }
+ VBO * b = indexBuffers, * previous = NULL;
+ while (b) {
+ if (b->name == buffers[i]) {
+ assert(GL_ELEMENT_ARRAY_BUFFER == b->target);
+ if (indexBuffer == b)
+ indexBuffer = NULL;
+ if (previous)
+ previous->next = b->next;
+ else
+ indexBuffers = b->next;
+ free(b->data);
+ delete b;
+ break;
+ }
+ previous = b;
+ b = b->next;
+ }
+ }
+ hasNonVBOAttribs = HasNonVBOAttribs(this);
+}
+
+}; // namespace android
diff --git a/opengl/libs/GLES2_dbg/src/debugger_message.pb.cpp b/opengl/libs/GLES2_dbg/src/debugger_message.pb.cpp
new file mode 100644
index 0000000..4083c44
--- /dev/null
+++ b/opengl/libs/GLES2_dbg/src/debugger_message.pb.cpp
@@ -0,0 +1,1252 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+
+#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
+#include "debugger_message.pb.h"
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+// @@protoc_insertion_point(includes)
+
+namespace com {
+namespace android {
+namespace glesv2debugger {
+
+void protobuf_ShutdownFile_debugger_5fmessage_2eproto() {
+ delete Message::default_instance_;
+}
+
+void protobuf_AddDesc_debugger_5fmessage_2eproto() {
+ static bool already_here = false;
+ if (already_here) return;
+ already_here = true;
+ GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+ Message::default_instance_ = new Message();
+ Message::default_instance_->InitAsDefaultInstance();
+ ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_debugger_5fmessage_2eproto);
+}
+
+// Force AddDescriptors() to be called at static initialization time.
+struct StaticDescriptorInitializer_debugger_5fmessage_2eproto {
+ StaticDescriptorInitializer_debugger_5fmessage_2eproto() {
+ protobuf_AddDesc_debugger_5fmessage_2eproto();
+ }
+} static_descriptor_initializer_debugger_5fmessage_2eproto_;
+
+
+// ===================================================================
+
+bool Message_Function_IsValid(int value) {
+ switch(value) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ case 16:
+ case 17:
+ case 18:
+ case 19:
+ case 20:
+ case 21:
+ case 22:
+ case 23:
+ case 24:
+ case 25:
+ case 26:
+ case 27:
+ case 28:
+ case 29:
+ case 30:
+ case 31:
+ case 32:
+ case 33:
+ case 34:
+ case 35:
+ case 36:
+ case 37:
+ case 38:
+ case 39:
+ case 40:
+ case 41:
+ case 42:
+ case 43:
+ case 44:
+ case 45:
+ case 46:
+ case 47:
+ case 48:
+ case 49:
+ case 50:
+ case 51:
+ case 52:
+ case 53:
+ case 54:
+ case 55:
+ case 56:
+ case 57:
+ case 58:
+ case 59:
+ case 60:
+ case 61:
+ case 62:
+ case 63:
+ case 64:
+ case 65:
+ case 66:
+ case 67:
+ case 68:
+ case 69:
+ case 70:
+ case 71:
+ case 72:
+ case 73:
+ case 74:
+ case 75:
+ case 76:
+ case 77:
+ case 78:
+ case 79:
+ case 80:
+ case 81:
+ case 82:
+ case 83:
+ case 84:
+ case 85:
+ case 86:
+ case 87:
+ case 88:
+ case 89:
+ case 90:
+ case 91:
+ case 92:
+ case 93:
+ case 94:
+ case 95:
+ case 96:
+ case 97:
+ case 98:
+ case 99:
+ case 100:
+ case 101:
+ case 102:
+ case 103:
+ case 104:
+ case 105:
+ case 106:
+ case 107:
+ case 108:
+ case 109:
+ case 110:
+ case 111:
+ case 112:
+ case 113:
+ case 114:
+ case 115:
+ case 116:
+ case 117:
+ case 118:
+ case 119:
+ case 120:
+ case 121:
+ case 122:
+ case 123:
+ case 124:
+ case 125:
+ case 126:
+ case 127:
+ case 128:
+ case 129:
+ case 130:
+ case 131:
+ case 132:
+ case 133:
+ case 134:
+ case 135:
+ case 136:
+ case 137:
+ case 138:
+ case 139:
+ case 140:
+ case 141:
+ case 142:
+ case 143:
+ case 144:
+ case 145:
+ case 146:
+ case 147:
+ case 148:
+ case 149:
+ case 150:
+ case 151:
+ case 152:
+ case 153:
+ case 154:
+ case 155:
+ case 156:
+ case 157:
+ case 158:
+ case 159:
+ case 160:
+ case 161:
+ case 162:
+ case 163:
+ case 164:
+ case 165:
+ case 166:
+ case 167:
+ case 168:
+ case 169:
+ case 170:
+ case 171:
+ case 172:
+ case 173:
+ case 174:
+ case 175:
+ case 176:
+ case 177:
+ case 178:
+ case 179:
+ case 180:
+ case 181:
+ case 182:
+ case 183:
+ case 184:
+ case 185:
+ case 186:
+ case 187:
+ case 188:
+ case 189:
+ case 190:
+ case 191:
+ return true;
+ default:
+ return false;
+ }
+}
+
+#ifndef _MSC_VER
+const Message_Function Message::glActiveTexture;
+const Message_Function Message::glAttachShader;
+const Message_Function Message::glBindAttribLocation;
+const Message_Function Message::glBindBuffer;
+const Message_Function Message::glBindFramebuffer;
+const Message_Function Message::glBindRenderbuffer;
+const Message_Function Message::glBindTexture;
+const Message_Function Message::glBlendColor;
+const Message_Function Message::glBlendEquation;
+const Message_Function Message::glBlendEquationSeparate;
+const Message_Function Message::glBlendFunc;
+const Message_Function Message::glBlendFuncSeparate;
+const Message_Function Message::glBufferData;
+const Message_Function Message::glBufferSubData;
+const Message_Function Message::glCheckFramebufferStatus;
+const Message_Function Message::glClear;
+const Message_Function Message::glClearColor;
+const Message_Function Message::glClearDepthf;
+const Message_Function Message::glClearStencil;
+const Message_Function Message::glColorMask;
+const Message_Function Message::glCompileShader;
+const Message_Function Message::glCompressedTexImage2D;
+const Message_Function Message::glCompressedTexSubImage2D;
+const Message_Function Message::glCopyTexImage2D;
+const Message_Function Message::glCopyTexSubImage2D;
+const Message_Function Message::glCreateProgram;
+const Message_Function Message::glCreateShader;
+const Message_Function Message::glCullFace;
+const Message_Function Message::glDeleteBuffers;
+const Message_Function Message::glDeleteFramebuffers;
+const Message_Function Message::glDeleteProgram;
+const Message_Function Message::glDeleteRenderbuffers;
+const Message_Function Message::glDeleteShader;
+const Message_Function Message::glDeleteTextures;
+const Message_Function Message::glDepthFunc;
+const Message_Function Message::glDepthMask;
+const Message_Function Message::glDepthRangef;
+const Message_Function Message::glDetachShader;
+const Message_Function Message::glDisable;
+const Message_Function Message::glDisableVertexAttribArray;
+const Message_Function Message::glDrawArrays;
+const Message_Function Message::glDrawElements;
+const Message_Function Message::glEnable;
+const Message_Function Message::glEnableVertexAttribArray;
+const Message_Function Message::glFinish;
+const Message_Function Message::glFlush;
+const Message_Function Message::glFramebufferRenderbuffer;
+const Message_Function Message::glFramebufferTexture2D;
+const Message_Function Message::glFrontFace;
+const Message_Function Message::glGenBuffers;
+const Message_Function Message::glGenerateMipmap;
+const Message_Function Message::glGenFramebuffers;
+const Message_Function Message::glGenRenderbuffers;
+const Message_Function Message::glGenTextures;
+const Message_Function Message::glGetActiveAttrib;
+const Message_Function Message::glGetActiveUniform;
+const Message_Function Message::glGetAttachedShaders;
+const Message_Function Message::glGetAttribLocation;
+const Message_Function Message::glGetBooleanv;
+const Message_Function Message::glGetBufferParameteriv;
+const Message_Function Message::glGetError;
+const Message_Function Message::glGetFloatv;
+const Message_Function Message::glGetFramebufferAttachmentParameteriv;
+const Message_Function Message::glGetIntegerv;
+const Message_Function Message::glGetProgramiv;
+const Message_Function Message::glGetProgramInfoLog;
+const Message_Function Message::glGetRenderbufferParameteriv;
+const Message_Function Message::glGetShaderiv;
+const Message_Function Message::glGetShaderInfoLog;
+const Message_Function Message::glGetShaderPrecisionFormat;
+const Message_Function Message::glGetShaderSource;
+const Message_Function Message::glGetString;
+const Message_Function Message::glGetTexParameterfv;
+const Message_Function Message::glGetTexParameteriv;
+const Message_Function Message::glGetUniformfv;
+const Message_Function Message::glGetUniformiv;
+const Message_Function Message::glGetUniformLocation;
+const Message_Function Message::glGetVertexAttribfv;
+const Message_Function Message::glGetVertexAttribiv;
+const Message_Function Message::glGetVertexAttribPointerv;
+const Message_Function Message::glHint;
+const Message_Function Message::glIsBuffer;
+const Message_Function Message::glIsEnabled;
+const Message_Function Message::glIsFramebuffer;
+const Message_Function Message::glIsProgram;
+const Message_Function Message::glIsRenderbuffer;
+const Message_Function Message::glIsShader;
+const Message_Function Message::glIsTexture;
+const Message_Function Message::glLineWidth;
+const Message_Function Message::glLinkProgram;
+const Message_Function Message::glPixelStorei;
+const Message_Function Message::glPolygonOffset;
+const Message_Function Message::glReadPixels;
+const Message_Function Message::glReleaseShaderCompiler;
+const Message_Function Message::glRenderbufferStorage;
+const Message_Function Message::glSampleCoverage;
+const Message_Function Message::glScissor;
+const Message_Function Message::glShaderBinary;
+const Message_Function Message::glShaderSource;
+const Message_Function Message::glStencilFunc;
+const Message_Function Message::glStencilFuncSeparate;
+const Message_Function Message::glStencilMask;
+const Message_Function Message::glStencilMaskSeparate;
+const Message_Function Message::glStencilOp;
+const Message_Function Message::glStencilOpSeparate;
+const Message_Function Message::glTexImage2D;
+const Message_Function Message::glTexParameterf;
+const Message_Function Message::glTexParameterfv;
+const Message_Function Message::glTexParameteri;
+const Message_Function Message::glTexParameteriv;
+const Message_Function Message::glTexSubImage2D;
+const Message_Function Message::glUniform1f;
+const Message_Function Message::glUniform1fv;
+const Message_Function Message::glUniform1i;
+const Message_Function Message::glUniform1iv;
+const Message_Function Message::glUniform2f;
+const Message_Function Message::glUniform2fv;
+const Message_Function Message::glUniform2i;
+const Message_Function Message::glUniform2iv;
+const Message_Function Message::glUniform3f;
+const Message_Function Message::glUniform3fv;
+const Message_Function Message::glUniform3i;
+const Message_Function Message::glUniform3iv;
+const Message_Function Message::glUniform4f;
+const Message_Function Message::glUniform4fv;
+const Message_Function Message::glUniform4i;
+const Message_Function Message::glUniform4iv;
+const Message_Function Message::glUniformMatrix2fv;
+const Message_Function Message::glUniformMatrix3fv;
+const Message_Function Message::glUniformMatrix4fv;
+const Message_Function Message::glUseProgram;
+const Message_Function Message::glValidateProgram;
+const Message_Function Message::glVertexAttrib1f;
+const Message_Function Message::glVertexAttrib1fv;
+const Message_Function Message::glVertexAttrib2f;
+const Message_Function Message::glVertexAttrib2fv;
+const Message_Function Message::glVertexAttrib3f;
+const Message_Function Message::glVertexAttrib3fv;
+const Message_Function Message::glVertexAttrib4f;
+const Message_Function Message::glVertexAttrib4fv;
+const Message_Function Message::glVertexAttribPointer;
+const Message_Function Message::glViewport;
+const Message_Function Message::eglGetDisplay;
+const Message_Function Message::eglInitialize;
+const Message_Function Message::eglTerminate;
+const Message_Function Message::eglGetConfigs;
+const Message_Function Message::eglChooseConfig;
+const Message_Function Message::eglGetConfigAttrib;
+const Message_Function Message::eglCreateWindowSurface;
+const Message_Function Message::eglCreatePixmapSurface;
+const Message_Function Message::eglCreatePbufferSurface;
+const Message_Function Message::eglDestroySurface;
+const Message_Function Message::eglQuerySurface;
+const Message_Function Message::eglCreateContext;
+const Message_Function Message::eglDestroyContext;
+const Message_Function Message::eglMakeCurrent;
+const Message_Function Message::eglGetCurrentContext;
+const Message_Function Message::eglGetCurrentSurface;
+const Message_Function Message::eglGetCurrentDisplay;
+const Message_Function Message::eglQueryContext;
+const Message_Function Message::eglWaitGL;
+const Message_Function Message::eglWaitNative;
+const Message_Function Message::eglSwapBuffers;
+const Message_Function Message::eglCopyBuffers;
+const Message_Function Message::eglGetError;
+const Message_Function Message::eglQueryString;
+const Message_Function Message::eglGetProcAddress;
+const Message_Function Message::eglSurfaceAttrib;
+const Message_Function Message::eglBindTexImage;
+const Message_Function Message::eglReleaseTexImage;
+const Message_Function Message::eglSwapInterval;
+const Message_Function Message::eglBindAPI;
+const Message_Function Message::eglQueryAPI;
+const Message_Function Message::eglWaitClient;
+const Message_Function Message::eglReleaseThread;
+const Message_Function Message::eglCreatePbufferFromClientBuffer;
+const Message_Function Message::eglLockSurfaceKHR;
+const Message_Function Message::eglUnlockSurfaceKHR;
+const Message_Function Message::eglCreateImageKHR;
+const Message_Function Message::eglDestroyImageKHR;
+const Message_Function Message::eglCreateSyncKHR;
+const Message_Function Message::eglDestroySyncKHR;
+const Message_Function Message::eglClientWaitSyncKHR;
+const Message_Function Message::eglGetSyncAttribKHR;
+const Message_Function Message::eglSetSwapRectangleANDROID;
+const Message_Function Message::eglGetRenderBufferANDROID;
+const Message_Function Message::ACK;
+const Message_Function Message::NEG;
+const Message_Function Message::CONTINUE;
+const Message_Function Message::SKIP;
+const Message_Function Message::SETPROP;
+const Message_Function Message::CAPTURE;
+const Message_Function Message::Function_MIN;
+const Message_Function Message::Function_MAX;
+const int Message::Function_ARRAYSIZE;
+#endif // _MSC_VER
+bool Message_Type_IsValid(int value) {
+ switch(value) {
+ case 0:
+ case 1:
+ case 2:
+ return true;
+ default:
+ return false;
+ }
+}
+
+#ifndef _MSC_VER
+const Message_Type Message::BeforeCall;
+const Message_Type Message::AfterCall;
+const Message_Type Message::Response;
+const Message_Type Message::Type_MIN;
+const Message_Type Message::Type_MAX;
+const int Message::Type_ARRAYSIZE;
+#endif // _MSC_VER
+bool Message_Prop_IsValid(int value) {
+ switch(value) {
+ case 0:
+ case 1:
+ return true;
+ default:
+ return false;
+ }
+}
+
+#ifndef _MSC_VER
+const Message_Prop Message::Capture;
+const Message_Prop Message::TimeMode;
+const Message_Prop Message::Prop_MIN;
+const Message_Prop Message::Prop_MAX;
+const int Message::Prop_ARRAYSIZE;
+#endif // _MSC_VER
+const ::std::string Message::_default_data_;
+#ifndef _MSC_VER
+const int Message::kContextIdFieldNumber;
+const int Message::kFunctionFieldNumber;
+const int Message::kTypeFieldNumber;
+const int Message::kExpectResponseFieldNumber;
+const int Message::kRetFieldNumber;
+const int Message::kArg0FieldNumber;
+const int Message::kArg1FieldNumber;
+const int Message::kArg2FieldNumber;
+const int Message::kArg3FieldNumber;
+const int Message::kArg4FieldNumber;
+const int Message::kArg5FieldNumber;
+const int Message::kArg6FieldNumber;
+const int Message::kArg7FieldNumber;
+const int Message::kArg8FieldNumber;
+const int Message::kDataFieldNumber;
+const int Message::kTimeFieldNumber;
+const int Message::kPropFieldNumber;
+const int Message::kClockFieldNumber;
+#endif // !_MSC_VER
+
+Message::Message()
+ : ::google::protobuf::MessageLite() {
+ SharedCtor();
+}
+
+void Message::InitAsDefaultInstance() {
+}
+
+Message::Message(const Message& from)
+ : ::google::protobuf::MessageLite() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void Message::SharedCtor() {
+ _cached_size_ = 0;
+ context_id_ = 0;
+ function_ = 187;
+ type_ = 0;
+ expect_response_ = false;
+ ret_ = 0;
+ arg0_ = 0;
+ arg1_ = 0;
+ arg2_ = 0;
+ arg3_ = 0;
+ arg4_ = 0;
+ arg5_ = 0;
+ arg6_ = 0;
+ arg7_ = 0;
+ arg8_ = 0;
+ data_ = const_cast< ::std::string*>(&_default_data_);
+ time_ = 0;
+ prop_ = 0;
+ clock_ = 0;
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+Message::~Message() {
+ SharedDtor();
+}
+
+void Message::SharedDtor() {
+ if (data_ != &_default_data_) {
+ delete data_;
+ }
+ if (this != default_instance_) {
+ }
+}
+
+void Message::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const Message& Message::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_debugger_5fmessage_2eproto(); return *default_instance_;
+}
+
+Message* Message::default_instance_ = NULL;
+
+Message* Message::New() const {
+ return new Message;
+}
+
+void Message::Clear() {
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ context_id_ = 0;
+ function_ = 187;
+ type_ = 0;
+ expect_response_ = false;
+ ret_ = 0;
+ arg0_ = 0;
+ arg1_ = 0;
+ arg2_ = 0;
+ }
+ if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
+ arg3_ = 0;
+ arg4_ = 0;
+ arg5_ = 0;
+ arg6_ = 0;
+ arg7_ = 0;
+ arg8_ = 0;
+ if (_has_bit(14)) {
+ if (data_ != &_default_data_) {
+ data_->clear();
+ }
+ }
+ time_ = 0;
+ }
+ if (_has_bits_[16 / 32] & (0xffu << (16 % 32))) {
+ prop_ = 0;
+ clock_ = 0;
+ }
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+bool Message::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // required int32 context_id = 1;
+ case 1: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, &context_id_)));
+ _set_bit(0);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(16)) goto parse_function;
+ break;
+ }
+
+ // required .com.android.glesv2debugger.Message.Function function = 2 [default = NEG];
+ case 2: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_function:
+ int value;
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+ input, &value)));
+ if (::com::android::glesv2debugger::Message_Function_IsValid(value)) {
+ set_function(static_cast< ::com::android::glesv2debugger::Message_Function >(value));
+ }
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(24)) goto parse_type;
+ break;
+ }
+
+ // required .com.android.glesv2debugger.Message.Type type = 3;
+ case 3: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_type:
+ int value;
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+ input, &value)));
+ if (::com::android::glesv2debugger::Message_Type_IsValid(value)) {
+ set_type(static_cast< ::com::android::glesv2debugger::Message_Type >(value));
+ }
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(32)) goto parse_expect_response;
+ break;
+ }
+
+ // required bool expect_response = 4;
+ case 4: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_expect_response:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+ input, &expect_response_)));
+ _set_bit(3);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(40)) goto parse_ret;
+ break;
+ }
+
+ // optional int32 ret = 5;
+ case 5: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_ret:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, &ret_)));
+ _set_bit(4);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(48)) goto parse_arg0;
+ break;
+ }
+
+ // optional int32 arg0 = 6;
+ case 6: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_arg0:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, &arg0_)));
+ _set_bit(5);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(56)) goto parse_arg1;
+ break;
+ }
+
+ // optional int32 arg1 = 7;
+ case 7: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_arg1:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, &arg1_)));
+ _set_bit(6);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(64)) goto parse_arg2;
+ break;
+ }
+
+ // optional int32 arg2 = 8;
+ case 8: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_arg2:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, &arg2_)));
+ _set_bit(7);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(72)) goto parse_arg3;
+ break;
+ }
+
+ // optional int32 arg3 = 9;
+ case 9: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_arg3:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, &arg3_)));
+ _set_bit(8);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(82)) goto parse_data;
+ break;
+ }
+
+ // optional bytes data = 10;
+ case 10: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_data:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
+ input, this->mutable_data()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(93)) goto parse_time;
+ break;
+ }
+
+ // optional float time = 11;
+ case 11: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) {
+ parse_time:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>(
+ input, &time_)));
+ _set_bit(15);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(128)) goto parse_arg4;
+ break;
+ }
+
+ // optional int32 arg4 = 16;
+ case 16: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_arg4:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, &arg4_)));
+ _set_bit(9);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(136)) goto parse_arg5;
+ break;
+ }
+
+ // optional int32 arg5 = 17;
+ case 17: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_arg5:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, &arg5_)));
+ _set_bit(10);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(144)) goto parse_arg6;
+ break;
+ }
+
+ // optional int32 arg6 = 18;
+ case 18: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_arg6:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, &arg6_)));
+ _set_bit(11);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(152)) goto parse_arg7;
+ break;
+ }
+
+ // optional int32 arg7 = 19;
+ case 19: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_arg7:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, &arg7_)));
+ _set_bit(12);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(160)) goto parse_arg8;
+ break;
+ }
+
+ // optional int32 arg8 = 20;
+ case 20: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_arg8:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, &arg8_)));
+ _set_bit(13);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(168)) goto parse_prop;
+ break;
+ }
+
+ // optional .com.android.glesv2debugger.Message.Prop prop = 21;
+ case 21: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_prop:
+ int value;
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+ input, &value)));
+ if (::com::android::glesv2debugger::Message_Prop_IsValid(value)) {
+ set_prop(static_cast< ::com::android::glesv2debugger::Message_Prop >(value));
+ }
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(181)) goto parse_clock;
+ break;
+ }
+
+ // optional float clock = 22;
+ case 22: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) {
+ parse_clock:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>(
+ input, &clock_)));
+ _set_bit(17);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void Message::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // required int32 context_id = 1;
+ if (_has_bit(0)) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->context_id(), output);
+ }
+
+ // required .com.android.glesv2debugger.Message.Function function = 2 [default = NEG];
+ if (_has_bit(1)) {
+ ::google::protobuf::internal::WireFormatLite::WriteEnum(
+ 2, this->function(), output);
+ }
+
+ // required .com.android.glesv2debugger.Message.Type type = 3;
+ if (_has_bit(2)) {
+ ::google::protobuf::internal::WireFormatLite::WriteEnum(
+ 3, this->type(), output);
+ }
+
+ // required bool expect_response = 4;
+ if (_has_bit(3)) {
+ ::google::protobuf::internal::WireFormatLite::WriteBool(4, this->expect_response(), output);
+ }
+
+ // optional int32 ret = 5;
+ if (_has_bit(4)) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32(5, this->ret(), output);
+ }
+
+ // optional int32 arg0 = 6;
+ if (_has_bit(5)) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32(6, this->arg0(), output);
+ }
+
+ // optional int32 arg1 = 7;
+ if (_has_bit(6)) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32(7, this->arg1(), output);
+ }
+
+ // optional int32 arg2 = 8;
+ if (_has_bit(7)) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32(8, this->arg2(), output);
+ }
+
+ // optional int32 arg3 = 9;
+ if (_has_bit(8)) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32(9, this->arg3(), output);
+ }
+
+ // optional bytes data = 10;
+ if (_has_bit(14)) {
+ ::google::protobuf::internal::WireFormatLite::WriteBytes(
+ 10, this->data(), output);
+ }
+
+ // optional float time = 11;
+ if (_has_bit(15)) {
+ ::google::protobuf::internal::WireFormatLite::WriteFloat(11, this->time(), output);
+ }
+
+ // optional int32 arg4 = 16;
+ if (_has_bit(9)) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32(16, this->arg4(), output);
+ }
+
+ // optional int32 arg5 = 17;
+ if (_has_bit(10)) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32(17, this->arg5(), output);
+ }
+
+ // optional int32 arg6 = 18;
+ if (_has_bit(11)) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32(18, this->arg6(), output);
+ }
+
+ // optional int32 arg7 = 19;
+ if (_has_bit(12)) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32(19, this->arg7(), output);
+ }
+
+ // optional int32 arg8 = 20;
+ if (_has_bit(13)) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32(20, this->arg8(), output);
+ }
+
+ // optional .com.android.glesv2debugger.Message.Prop prop = 21;
+ if (_has_bit(16)) {
+ ::google::protobuf::internal::WireFormatLite::WriteEnum(
+ 21, this->prop(), output);
+ }
+
+ // optional float clock = 22;
+ if (_has_bit(17)) {
+ ::google::protobuf::internal::WireFormatLite::WriteFloat(22, this->clock(), output);
+ }
+
+}
+
+int Message::ByteSize() const {
+ int total_size = 0;
+
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ // required int32 context_id = 1;
+ if (has_context_id()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(
+ this->context_id());
+ }
+
+ // required .com.android.glesv2debugger.Message.Function function = 2 [default = NEG];
+ if (has_function()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::EnumSize(this->function());
+ }
+
+ // required .com.android.glesv2debugger.Message.Type type = 3;
+ if (has_type()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::EnumSize(this->type());
+ }
+
+ // required bool expect_response = 4;
+ if (has_expect_response()) {
+ total_size += 1 + 1;
+ }
+
+ // optional int32 ret = 5;
+ if (has_ret()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(
+ this->ret());
+ }
+
+ // optional int32 arg0 = 6;
+ if (has_arg0()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(
+ this->arg0());
+ }
+
+ // optional int32 arg1 = 7;
+ if (has_arg1()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(
+ this->arg1());
+ }
+
+ // optional int32 arg2 = 8;
+ if (has_arg2()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(
+ this->arg2());
+ }
+
+ }
+ if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
+ // optional int32 arg3 = 9;
+ if (has_arg3()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(
+ this->arg3());
+ }
+
+ // optional int32 arg4 = 16;
+ if (has_arg4()) {
+ total_size += 2 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(
+ this->arg4());
+ }
+
+ // optional int32 arg5 = 17;
+ if (has_arg5()) {
+ total_size += 2 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(
+ this->arg5());
+ }
+
+ // optional int32 arg6 = 18;
+ if (has_arg6()) {
+ total_size += 2 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(
+ this->arg6());
+ }
+
+ // optional int32 arg7 = 19;
+ if (has_arg7()) {
+ total_size += 2 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(
+ this->arg7());
+ }
+
+ // optional int32 arg8 = 20;
+ if (has_arg8()) {
+ total_size += 2 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(
+ this->arg8());
+ }
+
+ // optional bytes data = 10;
+ if (has_data()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::BytesSize(
+ this->data());
+ }
+
+ // optional float time = 11;
+ if (has_time()) {
+ total_size += 1 + 4;
+ }
+
+ }
+ if (_has_bits_[16 / 32] & (0xffu << (16 % 32))) {
+ // optional .com.android.glesv2debugger.Message.Prop prop = 21;
+ if (has_prop()) {
+ total_size += 2 +
+ ::google::protobuf::internal::WireFormatLite::EnumSize(this->prop());
+ }
+
+ // optional float clock = 22;
+ if (has_clock()) {
+ total_size += 2 + 4;
+ }
+
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void Message::CheckTypeAndMergeFrom(
+ const ::google::protobuf::MessageLite& from) {
+ MergeFrom(*::google::protobuf::down_cast<const Message*>(&from));
+}
+
+void Message::MergeFrom(const Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (from._has_bit(0)) {
+ set_context_id(from.context_id());
+ }
+ if (from._has_bit(1)) {
+ set_function(from.function());
+ }
+ if (from._has_bit(2)) {
+ set_type(from.type());
+ }
+ if (from._has_bit(3)) {
+ set_expect_response(from.expect_response());
+ }
+ if (from._has_bit(4)) {
+ set_ret(from.ret());
+ }
+ if (from._has_bit(5)) {
+ set_arg0(from.arg0());
+ }
+ if (from._has_bit(6)) {
+ set_arg1(from.arg1());
+ }
+ if (from._has_bit(7)) {
+ set_arg2(from.arg2());
+ }
+ }
+ if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) {
+ if (from._has_bit(8)) {
+ set_arg3(from.arg3());
+ }
+ if (from._has_bit(9)) {
+ set_arg4(from.arg4());
+ }
+ if (from._has_bit(10)) {
+ set_arg5(from.arg5());
+ }
+ if (from._has_bit(11)) {
+ set_arg6(from.arg6());
+ }
+ if (from._has_bit(12)) {
+ set_arg7(from.arg7());
+ }
+ if (from._has_bit(13)) {
+ set_arg8(from.arg8());
+ }
+ if (from._has_bit(14)) {
+ set_data(from.data());
+ }
+ if (from._has_bit(15)) {
+ set_time(from.time());
+ }
+ }
+ if (from._has_bits_[16 / 32] & (0xffu << (16 % 32))) {
+ if (from._has_bit(16)) {
+ set_prop(from.prop());
+ }
+ if (from._has_bit(17)) {
+ set_clock(from.clock());
+ }
+ }
+}
+
+void Message::CopyFrom(const Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool Message::IsInitialized() const {
+ if ((_has_bits_[0] & 0x0000000f) != 0x0000000f) return false;
+
+ return true;
+}
+
+void Message::Swap(Message* other) {
+ if (other != this) {
+ std::swap(context_id_, other->context_id_);
+ std::swap(function_, other->function_);
+ std::swap(type_, other->type_);
+ std::swap(expect_response_, other->expect_response_);
+ std::swap(ret_, other->ret_);
+ std::swap(arg0_, other->arg0_);
+ std::swap(arg1_, other->arg1_);
+ std::swap(arg2_, other->arg2_);
+ std::swap(arg3_, other->arg3_);
+ std::swap(arg4_, other->arg4_);
+ std::swap(arg5_, other->arg5_);
+ std::swap(arg6_, other->arg6_);
+ std::swap(arg7_, other->arg7_);
+ std::swap(arg8_, other->arg8_);
+ std::swap(data_, other->data_);
+ std::swap(time_, other->time_);
+ std::swap(prop_, other->prop_);
+ std::swap(clock_, other->clock_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ std::swap(_cached_size_, other->_cached_size_);
+ }
+}
+
+::std::string Message::GetTypeName() const {
+ return "com.android.glesv2debugger.Message";
+}
+
+
+// @@protoc_insertion_point(namespace_scope)
+
+} // namespace glesv2debugger
+} // namespace android
+} // namespace com
+
+// @@protoc_insertion_point(global_scope)
diff --git a/opengl/libs/GLES2_dbg/src/debugger_message.pb.h b/opengl/libs/GLES2_dbg/src/debugger_message.pb.h
new file mode 100644
index 0000000..3f2b842
--- /dev/null
+++ b/opengl/libs/GLES2_dbg/src/debugger_message.pb.h
@@ -0,0 +1,1036 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: debugger_message.proto
+
+#ifndef PROTOBUF_debugger_5fmessage_2eproto__INCLUDED
+#define PROTOBUF_debugger_5fmessage_2eproto__INCLUDED
+
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+#if GOOGLE_PROTOBUF_VERSION < 2003000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 2003000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
+#error This file was generated by an older version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please
+#error regenerate this file with a newer version of protoc.
+#endif
+
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/extension_set.h>
+// @@protoc_insertion_point(includes)
+
+namespace com {
+namespace android {
+namespace glesv2debugger {
+
+// Internal implementation detail -- do not call these.
+void protobuf_AddDesc_debugger_5fmessage_2eproto();
+void protobuf_AssignDesc_debugger_5fmessage_2eproto();
+void protobuf_ShutdownFile_debugger_5fmessage_2eproto();
+
+class Message;
+
+enum Message_Function {
+ Message_Function_glActiveTexture = 0,
+ Message_Function_glAttachShader = 1,
+ Message_Function_glBindAttribLocation = 2,
+ Message_Function_glBindBuffer = 3,
+ Message_Function_glBindFramebuffer = 4,
+ Message_Function_glBindRenderbuffer = 5,
+ Message_Function_glBindTexture = 6,
+ Message_Function_glBlendColor = 7,
+ Message_Function_glBlendEquation = 8,
+ Message_Function_glBlendEquationSeparate = 9,
+ Message_Function_glBlendFunc = 10,
+ Message_Function_glBlendFuncSeparate = 11,
+ Message_Function_glBufferData = 12,
+ Message_Function_glBufferSubData = 13,
+ Message_Function_glCheckFramebufferStatus = 14,
+ Message_Function_glClear = 15,
+ Message_Function_glClearColor = 16,
+ Message_Function_glClearDepthf = 17,
+ Message_Function_glClearStencil = 18,
+ Message_Function_glColorMask = 19,
+ Message_Function_glCompileShader = 20,
+ Message_Function_glCompressedTexImage2D = 21,
+ Message_Function_glCompressedTexSubImage2D = 22,
+ Message_Function_glCopyTexImage2D = 23,
+ Message_Function_glCopyTexSubImage2D = 24,
+ Message_Function_glCreateProgram = 25,
+ Message_Function_glCreateShader = 26,
+ Message_Function_glCullFace = 27,
+ Message_Function_glDeleteBuffers = 28,
+ Message_Function_glDeleteFramebuffers = 29,
+ Message_Function_glDeleteProgram = 30,
+ Message_Function_glDeleteRenderbuffers = 31,
+ Message_Function_glDeleteShader = 32,
+ Message_Function_glDeleteTextures = 33,
+ Message_Function_glDepthFunc = 34,
+ Message_Function_glDepthMask = 35,
+ Message_Function_glDepthRangef = 36,
+ Message_Function_glDetachShader = 37,
+ Message_Function_glDisable = 38,
+ Message_Function_glDisableVertexAttribArray = 39,
+ Message_Function_glDrawArrays = 40,
+ Message_Function_glDrawElements = 41,
+ Message_Function_glEnable = 42,
+ Message_Function_glEnableVertexAttribArray = 43,
+ Message_Function_glFinish = 44,
+ Message_Function_glFlush = 45,
+ Message_Function_glFramebufferRenderbuffer = 46,
+ Message_Function_glFramebufferTexture2D = 47,
+ Message_Function_glFrontFace = 48,
+ Message_Function_glGenBuffers = 49,
+ Message_Function_glGenerateMipmap = 50,
+ Message_Function_glGenFramebuffers = 51,
+ Message_Function_glGenRenderbuffers = 52,
+ Message_Function_glGenTextures = 53,
+ Message_Function_glGetActiveAttrib = 54,
+ Message_Function_glGetActiveUniform = 55,
+ Message_Function_glGetAttachedShaders = 56,
+ Message_Function_glGetAttribLocation = 57,
+ Message_Function_glGetBooleanv = 58,
+ Message_Function_glGetBufferParameteriv = 59,
+ Message_Function_glGetError = 60,
+ Message_Function_glGetFloatv = 61,
+ Message_Function_glGetFramebufferAttachmentParameteriv = 62,
+ Message_Function_glGetIntegerv = 63,
+ Message_Function_glGetProgramiv = 64,
+ Message_Function_glGetProgramInfoLog = 65,
+ Message_Function_glGetRenderbufferParameteriv = 66,
+ Message_Function_glGetShaderiv = 67,
+ Message_Function_glGetShaderInfoLog = 68,
+ Message_Function_glGetShaderPrecisionFormat = 69,
+ Message_Function_glGetShaderSource = 70,
+ Message_Function_glGetString = 71,
+ Message_Function_glGetTexParameterfv = 72,
+ Message_Function_glGetTexParameteriv = 73,
+ Message_Function_glGetUniformfv = 74,
+ Message_Function_glGetUniformiv = 75,
+ Message_Function_glGetUniformLocation = 76,
+ Message_Function_glGetVertexAttribfv = 77,
+ Message_Function_glGetVertexAttribiv = 78,
+ Message_Function_glGetVertexAttribPointerv = 79,
+ Message_Function_glHint = 80,
+ Message_Function_glIsBuffer = 81,
+ Message_Function_glIsEnabled = 82,
+ Message_Function_glIsFramebuffer = 83,
+ Message_Function_glIsProgram = 84,
+ Message_Function_glIsRenderbuffer = 85,
+ Message_Function_glIsShader = 86,
+ Message_Function_glIsTexture = 87,
+ Message_Function_glLineWidth = 88,
+ Message_Function_glLinkProgram = 89,
+ Message_Function_glPixelStorei = 90,
+ Message_Function_glPolygonOffset = 91,
+ Message_Function_glReadPixels = 92,
+ Message_Function_glReleaseShaderCompiler = 93,
+ Message_Function_glRenderbufferStorage = 94,
+ Message_Function_glSampleCoverage = 95,
+ Message_Function_glScissor = 96,
+ Message_Function_glShaderBinary = 97,
+ Message_Function_glShaderSource = 98,
+ Message_Function_glStencilFunc = 99,
+ Message_Function_glStencilFuncSeparate = 100,
+ Message_Function_glStencilMask = 101,
+ Message_Function_glStencilMaskSeparate = 102,
+ Message_Function_glStencilOp = 103,
+ Message_Function_glStencilOpSeparate = 104,
+ Message_Function_glTexImage2D = 105,
+ Message_Function_glTexParameterf = 106,
+ Message_Function_glTexParameterfv = 107,
+ Message_Function_glTexParameteri = 108,
+ Message_Function_glTexParameteriv = 109,
+ Message_Function_glTexSubImage2D = 110,
+ Message_Function_glUniform1f = 111,
+ Message_Function_glUniform1fv = 112,
+ Message_Function_glUniform1i = 113,
+ Message_Function_glUniform1iv = 114,
+ Message_Function_glUniform2f = 115,
+ Message_Function_glUniform2fv = 116,
+ Message_Function_glUniform2i = 117,
+ Message_Function_glUniform2iv = 118,
+ Message_Function_glUniform3f = 119,
+ Message_Function_glUniform3fv = 120,
+ Message_Function_glUniform3i = 121,
+ Message_Function_glUniform3iv = 122,
+ Message_Function_glUniform4f = 123,
+ Message_Function_glUniform4fv = 124,
+ Message_Function_glUniform4i = 125,
+ Message_Function_glUniform4iv = 126,
+ Message_Function_glUniformMatrix2fv = 127,
+ Message_Function_glUniformMatrix3fv = 128,
+ Message_Function_glUniformMatrix4fv = 129,
+ Message_Function_glUseProgram = 130,
+ Message_Function_glValidateProgram = 131,
+ Message_Function_glVertexAttrib1f = 132,
+ Message_Function_glVertexAttrib1fv = 133,
+ Message_Function_glVertexAttrib2f = 134,
+ Message_Function_glVertexAttrib2fv = 135,
+ Message_Function_glVertexAttrib3f = 136,
+ Message_Function_glVertexAttrib3fv = 137,
+ Message_Function_glVertexAttrib4f = 138,
+ Message_Function_glVertexAttrib4fv = 139,
+ Message_Function_glVertexAttribPointer = 140,
+ Message_Function_glViewport = 141,
+ Message_Function_eglGetDisplay = 142,
+ Message_Function_eglInitialize = 143,
+ Message_Function_eglTerminate = 144,
+ Message_Function_eglGetConfigs = 145,
+ Message_Function_eglChooseConfig = 146,
+ Message_Function_eglGetConfigAttrib = 147,
+ Message_Function_eglCreateWindowSurface = 148,
+ Message_Function_eglCreatePixmapSurface = 149,
+ Message_Function_eglCreatePbufferSurface = 150,
+ Message_Function_eglDestroySurface = 151,
+ Message_Function_eglQuerySurface = 152,
+ Message_Function_eglCreateContext = 153,
+ Message_Function_eglDestroyContext = 154,
+ Message_Function_eglMakeCurrent = 155,
+ Message_Function_eglGetCurrentContext = 156,
+ Message_Function_eglGetCurrentSurface = 157,
+ Message_Function_eglGetCurrentDisplay = 158,
+ Message_Function_eglQueryContext = 159,
+ Message_Function_eglWaitGL = 160,
+ Message_Function_eglWaitNative = 161,
+ Message_Function_eglSwapBuffers = 162,
+ Message_Function_eglCopyBuffers = 163,
+ Message_Function_eglGetError = 164,
+ Message_Function_eglQueryString = 165,
+ Message_Function_eglGetProcAddress = 166,
+ Message_Function_eglSurfaceAttrib = 167,
+ Message_Function_eglBindTexImage = 168,
+ Message_Function_eglReleaseTexImage = 169,
+ Message_Function_eglSwapInterval = 170,
+ Message_Function_eglBindAPI = 171,
+ Message_Function_eglQueryAPI = 172,
+ Message_Function_eglWaitClient = 173,
+ Message_Function_eglReleaseThread = 174,
+ Message_Function_eglCreatePbufferFromClientBuffer = 175,
+ Message_Function_eglLockSurfaceKHR = 176,
+ Message_Function_eglUnlockSurfaceKHR = 177,
+ Message_Function_eglCreateImageKHR = 178,
+ Message_Function_eglDestroyImageKHR = 179,
+ Message_Function_eglCreateSyncKHR = 180,
+ Message_Function_eglDestroySyncKHR = 181,
+ Message_Function_eglClientWaitSyncKHR = 182,
+ Message_Function_eglGetSyncAttribKHR = 183,
+ Message_Function_eglSetSwapRectangleANDROID = 184,
+ Message_Function_eglGetRenderBufferANDROID = 185,
+ Message_Function_ACK = 186,
+ Message_Function_NEG = 187,
+ Message_Function_CONTINUE = 188,
+ Message_Function_SKIP = 189,
+ Message_Function_SETPROP = 190,
+ Message_Function_CAPTURE = 191
+};
+bool Message_Function_IsValid(int value);
+const Message_Function Message_Function_Function_MIN = Message_Function_glActiveTexture;
+const Message_Function Message_Function_Function_MAX = Message_Function_CAPTURE;
+const int Message_Function_Function_ARRAYSIZE = Message_Function_Function_MAX + 1;
+
+enum Message_Type {
+ Message_Type_BeforeCall = 0,
+ Message_Type_AfterCall = 1,
+ Message_Type_Response = 2
+};
+bool Message_Type_IsValid(int value);
+const Message_Type Message_Type_Type_MIN = Message_Type_BeforeCall;
+const Message_Type Message_Type_Type_MAX = Message_Type_Response;
+const int Message_Type_Type_ARRAYSIZE = Message_Type_Type_MAX + 1;
+
+enum Message_Prop {
+ Message_Prop_Capture = 0,
+ Message_Prop_TimeMode = 1
+};
+bool Message_Prop_IsValid(int value);
+const Message_Prop Message_Prop_Prop_MIN = Message_Prop_Capture;
+const Message_Prop Message_Prop_Prop_MAX = Message_Prop_TimeMode;
+const int Message_Prop_Prop_ARRAYSIZE = Message_Prop_Prop_MAX + 1;
+
+// ===================================================================
+
+class Message : public ::google::protobuf::MessageLite {
+ public:
+ Message();
+ virtual ~Message();
+
+ Message(const Message& from);
+
+ inline Message& operator=(const Message& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ static const Message& default_instance();
+
+ void Swap(Message* other);
+
+ // implements Message ----------------------------------------------
+
+ Message* New() const;
+ void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
+ void CopyFrom(const Message& from);
+ void MergeFrom(const Message& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::std::string GetTypeName() const;
+
+ // nested types ----------------------------------------------------
+
+ typedef Message_Function Function;
+ static const Function glActiveTexture = Message_Function_glActiveTexture;
+ static const Function glAttachShader = Message_Function_glAttachShader;
+ static const Function glBindAttribLocation = Message_Function_glBindAttribLocation;
+ static const Function glBindBuffer = Message_Function_glBindBuffer;
+ static const Function glBindFramebuffer = Message_Function_glBindFramebuffer;
+ static const Function glBindRenderbuffer = Message_Function_glBindRenderbuffer;
+ static const Function glBindTexture = Message_Function_glBindTexture;
+ static const Function glBlendColor = Message_Function_glBlendColor;
+ static const Function glBlendEquation = Message_Function_glBlendEquation;
+ static const Function glBlendEquationSeparate = Message_Function_glBlendEquationSeparate;
+ static const Function glBlendFunc = Message_Function_glBlendFunc;
+ static const Function glBlendFuncSeparate = Message_Function_glBlendFuncSeparate;
+ static const Function glBufferData = Message_Function_glBufferData;
+ static const Function glBufferSubData = Message_Function_glBufferSubData;
+ static const Function glCheckFramebufferStatus = Message_Function_glCheckFramebufferStatus;
+ static const Function glClear = Message_Function_glClear;
+ static const Function glClearColor = Message_Function_glClearColor;
+ static const Function glClearDepthf = Message_Function_glClearDepthf;
+ static const Function glClearStencil = Message_Function_glClearStencil;
+ static const Function glColorMask = Message_Function_glColorMask;
+ static const Function glCompileShader = Message_Function_glCompileShader;
+ static const Function glCompressedTexImage2D = Message_Function_glCompressedTexImage2D;
+ static const Function glCompressedTexSubImage2D = Message_Function_glCompressedTexSubImage2D;
+ static const Function glCopyTexImage2D = Message_Function_glCopyTexImage2D;
+ static const Function glCopyTexSubImage2D = Message_Function_glCopyTexSubImage2D;
+ static const Function glCreateProgram = Message_Function_glCreateProgram;
+ static const Function glCreateShader = Message_Function_glCreateShader;
+ static const Function glCullFace = Message_Function_glCullFace;
+ static const Function glDeleteBuffers = Message_Function_glDeleteBuffers;
+ static const Function glDeleteFramebuffers = Message_Function_glDeleteFramebuffers;
+ static const Function glDeleteProgram = Message_Function_glDeleteProgram;
+ static const Function glDeleteRenderbuffers = Message_Function_glDeleteRenderbuffers;
+ static const Function glDeleteShader = Message_Function_glDeleteShader;
+ static const Function glDeleteTextures = Message_Function_glDeleteTextures;
+ static const Function glDepthFunc = Message_Function_glDepthFunc;
+ static const Function glDepthMask = Message_Function_glDepthMask;
+ static const Function glDepthRangef = Message_Function_glDepthRangef;
+ static const Function glDetachShader = Message_Function_glDetachShader;
+ static const Function glDisable = Message_Function_glDisable;
+ static const Function glDisableVertexAttribArray = Message_Function_glDisableVertexAttribArray;
+ static const Function glDrawArrays = Message_Function_glDrawArrays;
+ static const Function glDrawElements = Message_Function_glDrawElements;
+ static const Function glEnable = Message_Function_glEnable;
+ static const Function glEnableVertexAttribArray = Message_Function_glEnableVertexAttribArray;
+ static const Function glFinish = Message_Function_glFinish;
+ static const Function glFlush = Message_Function_glFlush;
+ static const Function glFramebufferRenderbuffer = Message_Function_glFramebufferRenderbuffer;
+ static const Function glFramebufferTexture2D = Message_Function_glFramebufferTexture2D;
+ static const Function glFrontFace = Message_Function_glFrontFace;
+ static const Function glGenBuffers = Message_Function_glGenBuffers;
+ static const Function glGenerateMipmap = Message_Function_glGenerateMipmap;
+ static const Function glGenFramebuffers = Message_Function_glGenFramebuffers;
+ static const Function glGenRenderbuffers = Message_Function_glGenRenderbuffers;
+ static const Function glGenTextures = Message_Function_glGenTextures;
+ static const Function glGetActiveAttrib = Message_Function_glGetActiveAttrib;
+ static const Function glGetActiveUniform = Message_Function_glGetActiveUniform;
+ static const Function glGetAttachedShaders = Message_Function_glGetAttachedShaders;
+ static const Function glGetAttribLocation = Message_Function_glGetAttribLocation;
+ static const Function glGetBooleanv = Message_Function_glGetBooleanv;
+ static const Function glGetBufferParameteriv = Message_Function_glGetBufferParameteriv;
+ static const Function glGetError = Message_Function_glGetError;
+ static const Function glGetFloatv = Message_Function_glGetFloatv;
+ static const Function glGetFramebufferAttachmentParameteriv = Message_Function_glGetFramebufferAttachmentParameteriv;
+ static const Function glGetIntegerv = Message_Function_glGetIntegerv;
+ static const Function glGetProgramiv = Message_Function_glGetProgramiv;
+ static const Function glGetProgramInfoLog = Message_Function_glGetProgramInfoLog;
+ static const Function glGetRenderbufferParameteriv = Message_Function_glGetRenderbufferParameteriv;
+ static const Function glGetShaderiv = Message_Function_glGetShaderiv;
+ static const Function glGetShaderInfoLog = Message_Function_glGetShaderInfoLog;
+ static const Function glGetShaderPrecisionFormat = Message_Function_glGetShaderPrecisionFormat;
+ static const Function glGetShaderSource = Message_Function_glGetShaderSource;
+ static const Function glGetString = Message_Function_glGetString;
+ static const Function glGetTexParameterfv = Message_Function_glGetTexParameterfv;
+ static const Function glGetTexParameteriv = Message_Function_glGetTexParameteriv;
+ static const Function glGetUniformfv = Message_Function_glGetUniformfv;
+ static const Function glGetUniformiv = Message_Function_glGetUniformiv;
+ static const Function glGetUniformLocation = Message_Function_glGetUniformLocation;
+ static const Function glGetVertexAttribfv = Message_Function_glGetVertexAttribfv;
+ static const Function glGetVertexAttribiv = Message_Function_glGetVertexAttribiv;
+ static const Function glGetVertexAttribPointerv = Message_Function_glGetVertexAttribPointerv;
+ static const Function glHint = Message_Function_glHint;
+ static const Function glIsBuffer = Message_Function_glIsBuffer;
+ static const Function glIsEnabled = Message_Function_glIsEnabled;
+ static const Function glIsFramebuffer = Message_Function_glIsFramebuffer;
+ static const Function glIsProgram = Message_Function_glIsProgram;
+ static const Function glIsRenderbuffer = Message_Function_glIsRenderbuffer;
+ static const Function glIsShader = Message_Function_glIsShader;
+ static const Function glIsTexture = Message_Function_glIsTexture;
+ static const Function glLineWidth = Message_Function_glLineWidth;
+ static const Function glLinkProgram = Message_Function_glLinkProgram;
+ static const Function glPixelStorei = Message_Function_glPixelStorei;
+ static const Function glPolygonOffset = Message_Function_glPolygonOffset;
+ static const Function glReadPixels = Message_Function_glReadPixels;
+ static const Function glReleaseShaderCompiler = Message_Function_glReleaseShaderCompiler;
+ static const Function glRenderbufferStorage = Message_Function_glRenderbufferStorage;
+ static const Function glSampleCoverage = Message_Function_glSampleCoverage;
+ static const Function glScissor = Message_Function_glScissor;
+ static const Function glShaderBinary = Message_Function_glShaderBinary;
+ static const Function glShaderSource = Message_Function_glShaderSource;
+ static const Function glStencilFunc = Message_Function_glStencilFunc;
+ static const Function glStencilFuncSeparate = Message_Function_glStencilFuncSeparate;
+ static const Function glStencilMask = Message_Function_glStencilMask;
+ static const Function glStencilMaskSeparate = Message_Function_glStencilMaskSeparate;
+ static const Function glStencilOp = Message_Function_glStencilOp;
+ static const Function glStencilOpSeparate = Message_Function_glStencilOpSeparate;
+ static const Function glTexImage2D = Message_Function_glTexImage2D;
+ static const Function glTexParameterf = Message_Function_glTexParameterf;
+ static const Function glTexParameterfv = Message_Function_glTexParameterfv;
+ static const Function glTexParameteri = Message_Function_glTexParameteri;
+ static const Function glTexParameteriv = Message_Function_glTexParameteriv;
+ static const Function glTexSubImage2D = Message_Function_glTexSubImage2D;
+ static const Function glUniform1f = Message_Function_glUniform1f;
+ static const Function glUniform1fv = Message_Function_glUniform1fv;
+ static const Function glUniform1i = Message_Function_glUniform1i;
+ static const Function glUniform1iv = Message_Function_glUniform1iv;
+ static const Function glUniform2f = Message_Function_glUniform2f;
+ static const Function glUniform2fv = Message_Function_glUniform2fv;
+ static const Function glUniform2i = Message_Function_glUniform2i;
+ static const Function glUniform2iv = Message_Function_glUniform2iv;
+ static const Function glUniform3f = Message_Function_glUniform3f;
+ static const Function glUniform3fv = Message_Function_glUniform3fv;
+ static const Function glUniform3i = Message_Function_glUniform3i;
+ static const Function glUniform3iv = Message_Function_glUniform3iv;
+ static const Function glUniform4f = Message_Function_glUniform4f;
+ static const Function glUniform4fv = Message_Function_glUniform4fv;
+ static const Function glUniform4i = Message_Function_glUniform4i;
+ static const Function glUniform4iv = Message_Function_glUniform4iv;
+ static const Function glUniformMatrix2fv = Message_Function_glUniformMatrix2fv;
+ static const Function glUniformMatrix3fv = Message_Function_glUniformMatrix3fv;
+ static const Function glUniformMatrix4fv = Message_Function_glUniformMatrix4fv;
+ static const Function glUseProgram = Message_Function_glUseProgram;
+ static const Function glValidateProgram = Message_Function_glValidateProgram;
+ static const Function glVertexAttrib1f = Message_Function_glVertexAttrib1f;
+ static const Function glVertexAttrib1fv = Message_Function_glVertexAttrib1fv;
+ static const Function glVertexAttrib2f = Message_Function_glVertexAttrib2f;
+ static const Function glVertexAttrib2fv = Message_Function_glVertexAttrib2fv;
+ static const Function glVertexAttrib3f = Message_Function_glVertexAttrib3f;
+ static const Function glVertexAttrib3fv = Message_Function_glVertexAttrib3fv;
+ static const Function glVertexAttrib4f = Message_Function_glVertexAttrib4f;
+ static const Function glVertexAttrib4fv = Message_Function_glVertexAttrib4fv;
+ static const Function glVertexAttribPointer = Message_Function_glVertexAttribPointer;
+ static const Function glViewport = Message_Function_glViewport;
+ static const Function eglGetDisplay = Message_Function_eglGetDisplay;
+ static const Function eglInitialize = Message_Function_eglInitialize;
+ static const Function eglTerminate = Message_Function_eglTerminate;
+ static const Function eglGetConfigs = Message_Function_eglGetConfigs;
+ static const Function eglChooseConfig = Message_Function_eglChooseConfig;
+ static const Function eglGetConfigAttrib = Message_Function_eglGetConfigAttrib;
+ static const Function eglCreateWindowSurface = Message_Function_eglCreateWindowSurface;
+ static const Function eglCreatePixmapSurface = Message_Function_eglCreatePixmapSurface;
+ static const Function eglCreatePbufferSurface = Message_Function_eglCreatePbufferSurface;
+ static const Function eglDestroySurface = Message_Function_eglDestroySurface;
+ static const Function eglQuerySurface = Message_Function_eglQuerySurface;
+ static const Function eglCreateContext = Message_Function_eglCreateContext;
+ static const Function eglDestroyContext = Message_Function_eglDestroyContext;
+ static const Function eglMakeCurrent = Message_Function_eglMakeCurrent;
+ static const Function eglGetCurrentContext = Message_Function_eglGetCurrentContext;
+ static const Function eglGetCurrentSurface = Message_Function_eglGetCurrentSurface;
+ static const Function eglGetCurrentDisplay = Message_Function_eglGetCurrentDisplay;
+ static const Function eglQueryContext = Message_Function_eglQueryContext;
+ static const Function eglWaitGL = Message_Function_eglWaitGL;
+ static const Function eglWaitNative = Message_Function_eglWaitNative;
+ static const Function eglSwapBuffers = Message_Function_eglSwapBuffers;
+ static const Function eglCopyBuffers = Message_Function_eglCopyBuffers;
+ static const Function eglGetError = Message_Function_eglGetError;
+ static const Function eglQueryString = Message_Function_eglQueryString;
+ static const Function eglGetProcAddress = Message_Function_eglGetProcAddress;
+ static const Function eglSurfaceAttrib = Message_Function_eglSurfaceAttrib;
+ static const Function eglBindTexImage = Message_Function_eglBindTexImage;
+ static const Function eglReleaseTexImage = Message_Function_eglReleaseTexImage;
+ static const Function eglSwapInterval = Message_Function_eglSwapInterval;
+ static const Function eglBindAPI = Message_Function_eglBindAPI;
+ static const Function eglQueryAPI = Message_Function_eglQueryAPI;
+ static const Function eglWaitClient = Message_Function_eglWaitClient;
+ static const Function eglReleaseThread = Message_Function_eglReleaseThread;
+ static const Function eglCreatePbufferFromClientBuffer = Message_Function_eglCreatePbufferFromClientBuffer;
+ static const Function eglLockSurfaceKHR = Message_Function_eglLockSurfaceKHR;
+ static const Function eglUnlockSurfaceKHR = Message_Function_eglUnlockSurfaceKHR;
+ static const Function eglCreateImageKHR = Message_Function_eglCreateImageKHR;
+ static const Function eglDestroyImageKHR = Message_Function_eglDestroyImageKHR;
+ static const Function eglCreateSyncKHR = Message_Function_eglCreateSyncKHR;
+ static const Function eglDestroySyncKHR = Message_Function_eglDestroySyncKHR;
+ static const Function eglClientWaitSyncKHR = Message_Function_eglClientWaitSyncKHR;
+ static const Function eglGetSyncAttribKHR = Message_Function_eglGetSyncAttribKHR;
+ static const Function eglSetSwapRectangleANDROID = Message_Function_eglSetSwapRectangleANDROID;
+ static const Function eglGetRenderBufferANDROID = Message_Function_eglGetRenderBufferANDROID;
+ static const Function ACK = Message_Function_ACK;
+ static const Function NEG = Message_Function_NEG;
+ static const Function CONTINUE = Message_Function_CONTINUE;
+ static const Function SKIP = Message_Function_SKIP;
+ static const Function SETPROP = Message_Function_SETPROP;
+ static const Function CAPTURE = Message_Function_CAPTURE;
+ static inline bool Function_IsValid(int value) {
+ return Message_Function_IsValid(value);
+ }
+ static const Function Function_MIN =
+ Message_Function_Function_MIN;
+ static const Function Function_MAX =
+ Message_Function_Function_MAX;
+ static const int Function_ARRAYSIZE =
+ Message_Function_Function_ARRAYSIZE;
+
+ typedef Message_Type Type;
+ static const Type BeforeCall = Message_Type_BeforeCall;
+ static const Type AfterCall = Message_Type_AfterCall;
+ static const Type Response = Message_Type_Response;
+ static inline bool Type_IsValid(int value) {
+ return Message_Type_IsValid(value);
+ }
+ static const Type Type_MIN =
+ Message_Type_Type_MIN;
+ static const Type Type_MAX =
+ Message_Type_Type_MAX;
+ static const int Type_ARRAYSIZE =
+ Message_Type_Type_ARRAYSIZE;
+
+ typedef Message_Prop Prop;
+ static const Prop Capture = Message_Prop_Capture;
+ static const Prop TimeMode = Message_Prop_TimeMode;
+ static inline bool Prop_IsValid(int value) {
+ return Message_Prop_IsValid(value);
+ }
+ static const Prop Prop_MIN =
+ Message_Prop_Prop_MIN;
+ static const Prop Prop_MAX =
+ Message_Prop_Prop_MAX;
+ static const int Prop_ARRAYSIZE =
+ Message_Prop_Prop_ARRAYSIZE;
+
+ // accessors -------------------------------------------------------
+
+ // required int32 context_id = 1;
+ inline bool has_context_id() const;
+ inline void clear_context_id();
+ static const int kContextIdFieldNumber = 1;
+ inline ::google::protobuf::int32 context_id() const;
+ inline void set_context_id(::google::protobuf::int32 value);
+
+ // required .com.android.glesv2debugger.Message.Function function = 2 [default = NEG];
+ inline bool has_function() const;
+ inline void clear_function();
+ static const int kFunctionFieldNumber = 2;
+ inline ::com::android::glesv2debugger::Message_Function function() const;
+ inline void set_function(::com::android::glesv2debugger::Message_Function value);
+
+ // required .com.android.glesv2debugger.Message.Type type = 3;
+ inline bool has_type() const;
+ inline void clear_type();
+ static const int kTypeFieldNumber = 3;
+ inline ::com::android::glesv2debugger::Message_Type type() const;
+ inline void set_type(::com::android::glesv2debugger::Message_Type value);
+
+ // required bool expect_response = 4;
+ inline bool has_expect_response() const;
+ inline void clear_expect_response();
+ static const int kExpectResponseFieldNumber = 4;
+ inline bool expect_response() const;
+ inline void set_expect_response(bool value);
+
+ // optional int32 ret = 5;
+ inline bool has_ret() const;
+ inline void clear_ret();
+ static const int kRetFieldNumber = 5;
+ inline ::google::protobuf::int32 ret() const;
+ inline void set_ret(::google::protobuf::int32 value);
+
+ // optional int32 arg0 = 6;
+ inline bool has_arg0() const;
+ inline void clear_arg0();
+ static const int kArg0FieldNumber = 6;
+ inline ::google::protobuf::int32 arg0() const;
+ inline void set_arg0(::google::protobuf::int32 value);
+
+ // optional int32 arg1 = 7;
+ inline bool has_arg1() const;
+ inline void clear_arg1();
+ static const int kArg1FieldNumber = 7;
+ inline ::google::protobuf::int32 arg1() const;
+ inline void set_arg1(::google::protobuf::int32 value);
+
+ // optional int32 arg2 = 8;
+ inline bool has_arg2() const;
+ inline void clear_arg2();
+ static const int kArg2FieldNumber = 8;
+ inline ::google::protobuf::int32 arg2() const;
+ inline void set_arg2(::google::protobuf::int32 value);
+
+ // optional int32 arg3 = 9;
+ inline bool has_arg3() const;
+ inline void clear_arg3();
+ static const int kArg3FieldNumber = 9;
+ inline ::google::protobuf::int32 arg3() const;
+ inline void set_arg3(::google::protobuf::int32 value);
+
+ // optional int32 arg4 = 16;
+ inline bool has_arg4() const;
+ inline void clear_arg4();
+ static const int kArg4FieldNumber = 16;
+ inline ::google::protobuf::int32 arg4() const;
+ inline void set_arg4(::google::protobuf::int32 value);
+
+ // optional int32 arg5 = 17;
+ inline bool has_arg5() const;
+ inline void clear_arg5();
+ static const int kArg5FieldNumber = 17;
+ inline ::google::protobuf::int32 arg5() const;
+ inline void set_arg5(::google::protobuf::int32 value);
+
+ // optional int32 arg6 = 18;
+ inline bool has_arg6() const;
+ inline void clear_arg6();
+ static const int kArg6FieldNumber = 18;
+ inline ::google::protobuf::int32 arg6() const;
+ inline void set_arg6(::google::protobuf::int32 value);
+
+ // optional int32 arg7 = 19;
+ inline bool has_arg7() const;
+ inline void clear_arg7();
+ static const int kArg7FieldNumber = 19;
+ inline ::google::protobuf::int32 arg7() const;
+ inline void set_arg7(::google::protobuf::int32 value);
+
+ // optional int32 arg8 = 20;
+ inline bool has_arg8() const;
+ inline void clear_arg8();
+ static const int kArg8FieldNumber = 20;
+ inline ::google::protobuf::int32 arg8() const;
+ inline void set_arg8(::google::protobuf::int32 value);
+
+ // optional bytes data = 10;
+ inline bool has_data() const;
+ inline void clear_data();
+ static const int kDataFieldNumber = 10;
+ inline const ::std::string& data() const;
+ inline void set_data(const ::std::string& value);
+ inline void set_data(const char* value);
+ inline void set_data(const void* value, size_t size);
+ inline ::std::string* mutable_data();
+
+ // optional float time = 11;
+ inline bool has_time() const;
+ inline void clear_time();
+ static const int kTimeFieldNumber = 11;
+ inline float time() const;
+ inline void set_time(float value);
+
+ // optional .com.android.glesv2debugger.Message.Prop prop = 21;
+ inline bool has_prop() const;
+ inline void clear_prop();
+ static const int kPropFieldNumber = 21;
+ inline ::com::android::glesv2debugger::Message_Prop prop() const;
+ inline void set_prop(::com::android::glesv2debugger::Message_Prop value);
+
+ // optional float clock = 22;
+ inline bool has_clock() const;
+ inline void clear_clock();
+ static const int kClockFieldNumber = 22;
+ inline float clock() const;
+ inline void set_clock(float value);
+
+ // @@protoc_insertion_point(class_scope:com.android.glesv2debugger.Message)
+ private:
+ mutable int _cached_size_;
+
+ ::google::protobuf::int32 context_id_;
+ int function_;
+ int type_;
+ bool expect_response_;
+ ::google::protobuf::int32 ret_;
+ ::google::protobuf::int32 arg0_;
+ ::google::protobuf::int32 arg1_;
+ ::google::protobuf::int32 arg2_;
+ ::google::protobuf::int32 arg3_;
+ ::google::protobuf::int32 arg4_;
+ ::google::protobuf::int32 arg5_;
+ ::google::protobuf::int32 arg6_;
+ ::google::protobuf::int32 arg7_;
+ ::google::protobuf::int32 arg8_;
+ ::std::string* data_;
+ static const ::std::string _default_data_;
+ float time_;
+ int prop_;
+ float clock_;
+ friend void protobuf_AddDesc_debugger_5fmessage_2eproto();
+ friend void protobuf_AssignDesc_debugger_5fmessage_2eproto();
+ friend void protobuf_ShutdownFile_debugger_5fmessage_2eproto();
+
+ ::google::protobuf::uint32 _has_bits_[(18 + 31) / 32];
+
+ // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
+ inline bool _has_bit(int index) const {
+ return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
+ }
+ inline void _set_bit(int index) {
+ _has_bits_[index / 32] |= (1u << (index % 32));
+ }
+ inline void _clear_bit(int index) {
+ _has_bits_[index / 32] &= ~(1u << (index % 32));
+ }
+
+ void InitAsDefaultInstance();
+ static Message* default_instance_;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+// Message
+
+// required int32 context_id = 1;
+inline bool Message::has_context_id() const {
+ return _has_bit(0);
+}
+inline void Message::clear_context_id() {
+ context_id_ = 0;
+ _clear_bit(0);
+}
+inline ::google::protobuf::int32 Message::context_id() const {
+ return context_id_;
+}
+inline void Message::set_context_id(::google::protobuf::int32 value) {
+ _set_bit(0);
+ context_id_ = value;
+}
+
+// required .com.android.glesv2debugger.Message.Function function = 2 [default = NEG];
+inline bool Message::has_function() const {
+ return _has_bit(1);
+}
+inline void Message::clear_function() {
+ function_ = 187;
+ _clear_bit(1);
+}
+inline ::com::android::glesv2debugger::Message_Function Message::function() const {
+ return static_cast< ::com::android::glesv2debugger::Message_Function >(function_);
+}
+inline void Message::set_function(::com::android::glesv2debugger::Message_Function value) {
+ GOOGLE_DCHECK(::com::android::glesv2debugger::Message_Function_IsValid(value));
+ _set_bit(1);
+ function_ = value;
+}
+
+// required .com.android.glesv2debugger.Message.Type type = 3;
+inline bool Message::has_type() const {
+ return _has_bit(2);
+}
+inline void Message::clear_type() {
+ type_ = 0;
+ _clear_bit(2);
+}
+inline ::com::android::glesv2debugger::Message_Type Message::type() const {
+ return static_cast< ::com::android::glesv2debugger::Message_Type >(type_);
+}
+inline void Message::set_type(::com::android::glesv2debugger::Message_Type value) {
+ GOOGLE_DCHECK(::com::android::glesv2debugger::Message_Type_IsValid(value));
+ _set_bit(2);
+ type_ = value;
+}
+
+// required bool expect_response = 4;
+inline bool Message::has_expect_response() const {
+ return _has_bit(3);
+}
+inline void Message::clear_expect_response() {
+ expect_response_ = false;
+ _clear_bit(3);
+}
+inline bool Message::expect_response() const {
+ return expect_response_;
+}
+inline void Message::set_expect_response(bool value) {
+ _set_bit(3);
+ expect_response_ = value;
+}
+
+// optional int32 ret = 5;
+inline bool Message::has_ret() const {
+ return _has_bit(4);
+}
+inline void Message::clear_ret() {
+ ret_ = 0;
+ _clear_bit(4);
+}
+inline ::google::protobuf::int32 Message::ret() const {
+ return ret_;
+}
+inline void Message::set_ret(::google::protobuf::int32 value) {
+ _set_bit(4);
+ ret_ = value;
+}
+
+// optional int32 arg0 = 6;
+inline bool Message::has_arg0() const {
+ return _has_bit(5);
+}
+inline void Message::clear_arg0() {
+ arg0_ = 0;
+ _clear_bit(5);
+}
+inline ::google::protobuf::int32 Message::arg0() const {
+ return arg0_;
+}
+inline void Message::set_arg0(::google::protobuf::int32 value) {
+ _set_bit(5);
+ arg0_ = value;
+}
+
+// optional int32 arg1 = 7;
+inline bool Message::has_arg1() const {
+ return _has_bit(6);
+}
+inline void Message::clear_arg1() {
+ arg1_ = 0;
+ _clear_bit(6);
+}
+inline ::google::protobuf::int32 Message::arg1() const {
+ return arg1_;
+}
+inline void Message::set_arg1(::google::protobuf::int32 value) {
+ _set_bit(6);
+ arg1_ = value;
+}
+
+// optional int32 arg2 = 8;
+inline bool Message::has_arg2() const {
+ return _has_bit(7);
+}
+inline void Message::clear_arg2() {
+ arg2_ = 0;
+ _clear_bit(7);
+}
+inline ::google::protobuf::int32 Message::arg2() const {
+ return arg2_;
+}
+inline void Message::set_arg2(::google::protobuf::int32 value) {
+ _set_bit(7);
+ arg2_ = value;
+}
+
+// optional int32 arg3 = 9;
+inline bool Message::has_arg3() const {
+ return _has_bit(8);
+}
+inline void Message::clear_arg3() {
+ arg3_ = 0;
+ _clear_bit(8);
+}
+inline ::google::protobuf::int32 Message::arg3() const {
+ return arg3_;
+}
+inline void Message::set_arg3(::google::protobuf::int32 value) {
+ _set_bit(8);
+ arg3_ = value;
+}
+
+// optional int32 arg4 = 16;
+inline bool Message::has_arg4() const {
+ return _has_bit(9);
+}
+inline void Message::clear_arg4() {
+ arg4_ = 0;
+ _clear_bit(9);
+}
+inline ::google::protobuf::int32 Message::arg4() const {
+ return arg4_;
+}
+inline void Message::set_arg4(::google::protobuf::int32 value) {
+ _set_bit(9);
+ arg4_ = value;
+}
+
+// optional int32 arg5 = 17;
+inline bool Message::has_arg5() const {
+ return _has_bit(10);
+}
+inline void Message::clear_arg5() {
+ arg5_ = 0;
+ _clear_bit(10);
+}
+inline ::google::protobuf::int32 Message::arg5() const {
+ return arg5_;
+}
+inline void Message::set_arg5(::google::protobuf::int32 value) {
+ _set_bit(10);
+ arg5_ = value;
+}
+
+// optional int32 arg6 = 18;
+inline bool Message::has_arg6() const {
+ return _has_bit(11);
+}
+inline void Message::clear_arg6() {
+ arg6_ = 0;
+ _clear_bit(11);
+}
+inline ::google::protobuf::int32 Message::arg6() const {
+ return arg6_;
+}
+inline void Message::set_arg6(::google::protobuf::int32 value) {
+ _set_bit(11);
+ arg6_ = value;
+}
+
+// optional int32 arg7 = 19;
+inline bool Message::has_arg7() const {
+ return _has_bit(12);
+}
+inline void Message::clear_arg7() {
+ arg7_ = 0;
+ _clear_bit(12);
+}
+inline ::google::protobuf::int32 Message::arg7() const {
+ return arg7_;
+}
+inline void Message::set_arg7(::google::protobuf::int32 value) {
+ _set_bit(12);
+ arg7_ = value;
+}
+
+// optional int32 arg8 = 20;
+inline bool Message::has_arg8() const {
+ return _has_bit(13);
+}
+inline void Message::clear_arg8() {
+ arg8_ = 0;
+ _clear_bit(13);
+}
+inline ::google::protobuf::int32 Message::arg8() const {
+ return arg8_;
+}
+inline void Message::set_arg8(::google::protobuf::int32 value) {
+ _set_bit(13);
+ arg8_ = value;
+}
+
+// optional bytes data = 10;
+inline bool Message::has_data() const {
+ return _has_bit(14);
+}
+inline void Message::clear_data() {
+ if (data_ != &_default_data_) {
+ data_->clear();
+ }
+ _clear_bit(14);
+}
+inline const ::std::string& Message::data() const {
+ return *data_;
+}
+inline void Message::set_data(const ::std::string& value) {
+ _set_bit(14);
+ if (data_ == &_default_data_) {
+ data_ = new ::std::string;
+ }
+ data_->assign(value);
+}
+inline void Message::set_data(const char* value) {
+ _set_bit(14);
+ if (data_ == &_default_data_) {
+ data_ = new ::std::string;
+ }
+ data_->assign(value);
+}
+inline void Message::set_data(const void* value, size_t size) {
+ _set_bit(14);
+ if (data_ == &_default_data_) {
+ data_ = new ::std::string;
+ }
+ data_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* Message::mutable_data() {
+ _set_bit(14);
+ if (data_ == &_default_data_) {
+ data_ = new ::std::string;
+ }
+ return data_;
+}
+
+// optional float time = 11;
+inline bool Message::has_time() const {
+ return _has_bit(15);
+}
+inline void Message::clear_time() {
+ time_ = 0;
+ _clear_bit(15);
+}
+inline float Message::time() const {
+ return time_;
+}
+inline void Message::set_time(float value) {
+ _set_bit(15);
+ time_ = value;
+}
+
+// optional .com.android.glesv2debugger.Message.Prop prop = 21;
+inline bool Message::has_prop() const {
+ return _has_bit(16);
+}
+inline void Message::clear_prop() {
+ prop_ = 0;
+ _clear_bit(16);
+}
+inline ::com::android::glesv2debugger::Message_Prop Message::prop() const {
+ return static_cast< ::com::android::glesv2debugger::Message_Prop >(prop_);
+}
+inline void Message::set_prop(::com::android::glesv2debugger::Message_Prop value) {
+ GOOGLE_DCHECK(::com::android::glesv2debugger::Message_Prop_IsValid(value));
+ _set_bit(16);
+ prop_ = value;
+}
+
+// optional float clock = 22;
+inline bool Message::has_clock() const {
+ return _has_bit(17);
+}
+inline void Message::clear_clock() {
+ clock_ = 0;
+ _clear_bit(17);
+}
+inline float Message::clock() const {
+ return clock_;
+}
+inline void Message::set_clock(float value) {
+ _set_bit(17);
+ clock_ = value;
+}
+
+
+// @@protoc_insertion_point(namespace_scope)
+
+} // namespace glesv2debugger
+} // namespace android
+} // namespace com
+
+// @@protoc_insertion_point(global_scope)
+
+#endif // PROTOBUF_debugger_5fmessage_2eproto__INCLUDED
diff --git a/opengl/libs/GLES2_dbg/src/egl.cpp b/opengl/libs/GLES2_dbg/src/egl.cpp
new file mode 100644
index 0000000..b3979a3
--- /dev/null
+++ b/opengl/libs/GLES2_dbg/src/egl.cpp
@@ -0,0 +1,41 @@
+/*
+ ** Copyright 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.
+ */
+
+#include "header.h"
+
+EGLBoolean Debug_eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = true;
+ struct : public FunctionCall {
+ EGLDisplay dpy;
+ EGLSurface draw;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ msg.set_time(-1);
+ return reinterpret_cast<const int *>(true);
+ }
+ } caller;
+ caller.dpy = dpy;
+ caller.draw = draw;
+
+ msg.set_arg0(reinterpret_cast<int>(dpy));
+ msg.set_arg1(reinterpret_cast<int>(draw));
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_eglSwapBuffers);
+ return static_cast<EGLBoolean>(reinterpret_cast<int>(ret));
+}
diff --git a/opengl/libs/GLES2_dbg/src/header.h b/opengl/libs/GLES2_dbg/src/header.h
new file mode 100644
index 0000000..cbd448a
--- /dev/null
+++ b/opengl/libs/GLES2_dbg/src/header.h
@@ -0,0 +1,129 @@
+/*
+ ** Copyright 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.
+ */
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <errno.h>
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <cutils/log.h>
+#include <utils/Timers.h>
+#include <../../../libcore/include/StaticAssert.h>
+
+#define EGL_TRACE 1
+#include "hooks.h"
+
+#include "glesv2dbg.h"
+
+#define GL_ENTRY(_r, _api, ...) _r Debug_##_api ( __VA_ARGS__ );
+#include "glesv2dbg_functions.h"
+
+#include "debugger_message.pb.h"
+
+using namespace android;
+using namespace com::android;
+
+#define API_ENTRY(_api) Debug_##_api
+
+#ifndef __location__
+#define __HIERALLOC_STRING_0__(s) #s
+#define __HIERALLOC_STRING_1__(s) __HIERALLOC_STRING_0__(s)
+#define __HIERALLOC_STRING_2__ __HIERALLOC_STRING_1__(__LINE__)
+#define __location__ __FILE__ ":" __HIERALLOC_STRING_2__
+#endif
+
+#undef assert
+#define assert(expr) if (!(expr)) { LOGD("\n*\n*\n* assert: %s at %s \n*\n*", #expr, __location__); int * x = 0; *x = 5; }
+//#undef LOGD
+//#define LOGD(...)
+
+namespace android
+{
+
+struct DbgContext {
+ const unsigned version; // 0 is GLES1, 1 is GLES2
+ const gl_hooks_t * const hooks;
+ const unsigned MAX_VERTEX_ATTRIBS;
+
+ struct VertexAttrib {
+ GLenum type; // element data type
+ unsigned size; // number of data per element
+ unsigned stride; // calculated number of bytes between elements
+ const void * ptr;
+ unsigned elemSize; // calculated number of bytes per element
+ GLuint buffer; // buffer name
+ GLboolean normalized : 1;
+ GLboolean enabled : 1;
+ VertexAttrib() : type(0), size(0), stride(0), ptr(NULL), elemSize(0),
+ buffer(0), normalized(0), enabled(0) {}
+ } * vertexAttribs;
+ bool hasNonVBOAttribs; // whether any enabled vertexAttrib is user pointer
+
+ struct VBO {
+ const GLuint name;
+ const GLenum target;
+ VBO * next;
+ void * data; // malloc/free
+ unsigned size; // in bytes
+ VBO(const GLuint name, const GLenum target, VBO * head) : name(name),
+ target(target), next(head), data(NULL), size(0) {}
+ } * indexBuffers; // linked list of all index buffers
+ VBO * indexBuffer; // currently bound index buffer
+
+ GLuint program;
+ unsigned maxAttrib; // number of slots used by program
+
+ DbgContext(const unsigned version, const gl_hooks_t * const hooks, const unsigned MAX_VERTEX_ATTRIBS);
+ ~DbgContext();
+
+ void Fetch(const unsigned index, std::string * const data) const;
+
+ void glUseProgram(GLuint program);
+ void glEnableVertexAttribArray(GLuint index);
+ void glDisableVertexAttribArray(GLuint index);
+ void glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr);
+ void glBindBuffer(GLenum target, GLuint buffer);
+ void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
+ void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
+ void glDeleteBuffers(GLsizei n, const GLuint *buffers);
+};
+
+
+DbgContext * getDbgContextThreadSpecific();
+#define DBGCONTEXT(ctx) DbgContext * const ctx = getDbgContextThreadSpecific();
+
+struct FunctionCall {
+ virtual const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) = 0;
+ virtual ~FunctionCall() {}
+};
+
+// move these into DbgContext
+extern bool capture;
+extern int timeMode; // SYSTEM_TIME_
+
+extern int clientSock, serverSock;
+
+unsigned GetBytesPerPixel(const GLenum format, const GLenum type);
+
+int * MessageLoop(FunctionCall & functionCall, glesv2debugger::Message & msg,
+ const bool expectResponse, const glesv2debugger::Message_Function function);
+void Receive(glesv2debugger::Message & cmd);
+float Send(const glesv2debugger::Message & msg, glesv2debugger::Message & cmd);
+void SetProp(const glesv2debugger::Message & cmd);
+}; // namespace android {
diff --git a/opengl/libs/GLES2_dbg/src/server.cpp b/opengl/libs/GLES2_dbg/src/server.cpp
new file mode 100644
index 0000000..820e9de
--- /dev/null
+++ b/opengl/libs/GLES2_dbg/src/server.cpp
@@ -0,0 +1,228 @@
+/*
+ ** Copyright 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.
+ */
+
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <pthread.h>
+
+#include "header.h"
+
+namespace android
+{
+
+int serverSock = -1, clientSock = -1;
+
+int timeMode = SYSTEM_TIME_THREAD;
+
+static void Die(const char * msg)
+{
+ LOGD("\n*\n*\n* GLESv2_dbg: Die: %s \n*\n*", msg);
+ StopDebugServer();
+ exit(1);
+}
+
+void StartDebugServer()
+{
+ LOGD("GLESv2_dbg: StartDebugServer");
+ if (serverSock >= 0)
+ return;
+
+ LOGD("GLESv2_dbg: StartDebugServer create socket");
+ struct sockaddr_in server = {}, client = {};
+
+ /* Create the TCP socket */
+ if ((serverSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+ Die("Failed to create socket");
+ }
+ /* Construct the server sockaddr_in structure */
+ server.sin_family = AF_INET; /* Internet/IP */
+ server.sin_addr.s_addr = htonl(INADDR_ANY); /* Incoming addr */
+ server.sin_port = htons(5039); /* server port */
+
+ /* Bind the server socket */
+ socklen_t sizeofSockaddr_in = sizeof(sockaddr_in);
+ if (bind(serverSock, (struct sockaddr *) &server,
+ sizeof(server)) < 0) {
+ Die("Failed to bind the server socket");
+ }
+ /* Listen on the server socket */
+ if (listen(serverSock, 1) < 0) {
+ Die("Failed to listen on server socket");
+ }
+
+ LOGD("server started on %d \n", server.sin_port);
+
+
+ /* Wait for client connection */
+ if ((clientSock =
+ accept(serverSock, (struct sockaddr *) &client,
+ &sizeofSockaddr_in)) < 0) {
+ Die("Failed to accept client connection");
+ }
+
+ LOGD("Client connected: %s\n", inet_ntoa(client.sin_addr));
+// fcntl(clientSock, F_SETFL, O_NONBLOCK);
+
+ glesv2debugger::Message msg, cmd;
+ msg.set_context_id(0);
+ msg.set_function(glesv2debugger::Message_Function_ACK);
+ msg.set_type(glesv2debugger::Message_Type_Response);
+ msg.set_expect_response(false);
+ Send(msg, cmd);
+}
+
+void StopDebugServer()
+{
+ LOGD("GLESv2_dbg: StopDebugServer");
+ if (clientSock > 0) {
+ close(clientSock);
+ clientSock = -1;
+ }
+ if (serverSock > 0) {
+ close(serverSock);
+ serverSock = -1;
+ }
+
+}
+
+void Receive(glesv2debugger::Message & cmd)
+{
+ unsigned len = 0;
+
+ int received = recv(clientSock, &len, 4, MSG_WAITALL);
+ if (received < 0)
+ Die("Failed to receive response length");
+ else if (4 != received) {
+ LOGD("received %dB: %.8X", received, len);
+ Die("Received length mismatch, expected 4");
+ }
+ len = ntohl(len);
+ static void * buffer = NULL;
+ static unsigned bufferSize = 0;
+ if (bufferSize < len) {
+ buffer = realloc(buffer, len);
+ assert(buffer);
+ bufferSize = len;
+ }
+ received = recv(clientSock, buffer, len, MSG_WAITALL);
+ if (received < 0)
+ Die("Failed to receive response");
+ else if (len != received)
+ Die("Received length mismatch");
+ cmd.Clear();
+ cmd.ParseFromArray(buffer, len);
+}
+
+float Send(const glesv2debugger::Message & msg, glesv2debugger::Message & cmd)
+{
+ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+ pthread_mutex_lock(&mutex); // TODO: this is just temporary
+
+ if (msg.function() != glesv2debugger::Message_Function_ACK)
+ assert(msg.has_context_id() && msg.context_id() != 0);
+ static std::string str;
+ msg.SerializeToString(&str);
+ unsigned len = str.length();
+ len = htonl(len);
+ int sent = -1;
+ sent = send(clientSock, (const char *)&len, sizeof(len), 0);
+ if (sent != sizeof(len)) {
+ LOGD("actual sent=%d expected=%d clientSock=%d", sent, sizeof(len), clientSock);
+ Die("Failed to send message length");
+ }
+ nsecs_t c0 = systemTime(timeMode);
+ sent = send(clientSock, str.c_str(), str.length(), 0);
+ float t = (float)ns2ms(systemTime(timeMode) - c0);
+ if (sent != str.length()) {
+ LOGD("actual sent=%d expected=%d clientSock=%d", sent, str.length(), clientSock);
+ Die("Failed to send message");
+ }
+
+ if (!msg.expect_response()) {
+ pthread_mutex_unlock(&mutex);
+ return t;
+ }
+
+ Receive(cmd);
+
+ //LOGD("Message sent tid=%lu len=%d", pthread_self(), str.length());
+ pthread_mutex_unlock(&mutex);
+ return t;
+}
+
+void SetProp(const glesv2debugger::Message & cmd)
+{
+ switch (cmd.prop()) {
+ case glesv2debugger::Message_Prop_Capture:
+ LOGD("SetProp Message_Prop_Capture %d", cmd.arg0());
+ capture = cmd.arg0();
+ break;
+ case glesv2debugger::Message_Prop_TimeMode:
+ LOGD("SetProp Message_Prop_TimeMode %d", cmd.arg0());
+ timeMode = cmd.arg0();
+ break;
+ default:
+ assert(0);
+ }
+}
+
+int * MessageLoop(FunctionCall & functionCall, glesv2debugger::Message & msg,
+ const bool expectResponse, const glesv2debugger::Message_Function function)
+{
+ DbgContext * const dbg = getDbgContextThreadSpecific();
+ const int * ret = 0;
+ glesv2debugger::Message cmd;
+ msg.set_context_id(reinterpret_cast<int>(dbg));
+ msg.set_type(glesv2debugger::Message_Type_BeforeCall);
+ msg.set_expect_response(expectResponse);
+ msg.set_function(function);
+ Send(msg, cmd);
+ if (!expectResponse)
+ cmd.set_function(glesv2debugger::Message_Function_CONTINUE);
+ while (true) {
+ msg.Clear();
+ nsecs_t c0 = systemTime(timeMode);
+ switch (cmd.function()) {
+ case glesv2debugger::Message_Function_CONTINUE:
+ ret = functionCall(&dbg->hooks->gl, msg);
+ if (!msg.has_time()) // some has output data copy, so time inside call
+ msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
+ msg.set_context_id(reinterpret_cast<int>(dbg));
+ msg.set_function(function);
+ msg.set_type(glesv2debugger::Message_Type_AfterCall);
+ msg.set_expect_response(expectResponse);
+ Send(msg, cmd);
+ if (!expectResponse)
+ cmd.set_function(glesv2debugger::Message_Function_SKIP);
+ break;
+ case glesv2debugger::Message_Function_SKIP:
+ return const_cast<int *>(ret);
+ case glesv2debugger::Message_Function_SETPROP:
+ SetProp(cmd);
+ Receive(cmd);
+ break;
+ default:
+ assert(0); //GenerateCall(msg, cmd);
+ break;
+ }
+ }
+ return 0;
+}
+}; // namespace android {
diff --git a/opengl/libs/GLES2_dbg/src/texture.cpp b/opengl/libs/GLES2_dbg/src/texture.cpp
new file mode 100644
index 0000000..3aa0aab
--- /dev/null
+++ b/opengl/libs/GLES2_dbg/src/texture.cpp
@@ -0,0 +1,265 @@
+/*
+ ** Copyright 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.
+ */
+
+#include "header.h"
+
+namespace android
+{
+unsigned GetBytesPerPixel(const GLenum format, const GLenum type)
+{
+ switch (type) {
+ case GL_UNSIGNED_SHORT_5_6_5:
+ return 2;
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ return 2;
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ return 2;
+ case GL_UNSIGNED_BYTE:
+ break;
+ default:
+ assert(0);
+ }
+
+ switch (format) {
+ case GL_ALPHA:
+ return 1;
+ case GL_LUMINANCE:
+ return 1;
+ break;
+ case GL_LUMINANCE_ALPHA:
+ return 2;
+ case GL_RGB:
+ return 3;
+ case GL_RGBA:
+ return 4;
+ default:
+ assert(0);
+ return 0;
+ }
+}
+
+#define USE_RLE 0
+#if USE_RLE
+export template<typename T>
+void * RLEEncode(const void * pixels, unsigned count, unsigned * encodedSize)
+{
+ // first is a byte indicating data size [1,2,4] bytes
+ // then an unsigned indicating decompressed size
+ // then a byte of header: MSB == 1 indicates run, else literal
+ // LSB7 is run or literal length (actual length - 1)
+
+ const T * data = (T *)pixels;
+ unsigned bufferSize = sizeof(T) * count / 2 + 8;
+ unsigned char * buffer = (unsigned char *)malloc(bufferSize);
+ buffer[0] = sizeof(T);
+ unsigned bufferWritten = 1; // number of bytes written
+ *(unsigned *)(buffer + bufferWritten) = count;
+ bufferWritten += sizeof(count);
+ while (count) {
+ unsigned char run = 1;
+ bool repeat = true;
+ for (run = 1; run < count; run++)
+ if (data[0] != data[run]) {
+ repeat = false;
+ break;
+ } else if (run > 126)
+ break;
+ if (!repeat) {
+ // find literal length
+ for (run = 1; run < count; run++)
+ if (data[run - 1] == data[run])
+ break;
+ else if (run > 126)
+ break;
+ unsigned bytesToWrite = 1 + sizeof(T) * run;
+ if (bufferWritten + bytesToWrite > bufferSize) {
+ bufferSize += sizeof(T) * run + 256;
+ buffer = (unsigned char *)realloc(buffer, bufferSize);
+ }
+ buffer[bufferWritten++] = run - 1;
+ for (unsigned i = 0; i < run; i++) {
+ *(T *)(buffer + bufferWritten) = *data;
+ bufferWritten += sizeof(T);
+ data++;
+ }
+ count -= run;
+ } else {
+ unsigned bytesToWrite = 1 + sizeof(T);
+ if (bufferWritten + bytesToWrite > bufferSize) {
+ bufferSize += 256;
+ buffer = (unsigned char *)realloc(buffer, bufferSize);
+ }
+ buffer[bufferWritten++] = (run - 1) | 0x80;
+ *(T *)(buffer + bufferWritten) = data[0];
+ bufferWritten += sizeof(T);
+ data += run;
+ count -= run;
+ }
+ }
+ if (encodedSize)
+ *encodedSize = bufferWritten;
+ return buffer;
+}
+
+void * RLEEncode(const void * pixels, const unsigned bytesPerPixel, const unsigned count, unsigned * encodedSize)
+{
+ switch (bytesPerPixel) {
+ case 4:
+ return RLEEncode<int>(pixels, count, encodedSize);
+ case 2:
+ return RLEEncode<short>(pixels, count, encodedSize);
+ case 1:
+ return RLEEncode<char>(pixels, count, encodedSize);
+ default:
+ assert(0);
+ return NULL;
+ }
+}
+#endif
+}; // namespace android
+
+void Debug_glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum target;
+ GLint level;
+ GLint internalformat;
+ GLsizei width;
+ GLsizei height;
+ GLint border;
+ GLenum format;
+ GLenum type;
+ const GLvoid* pixels;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ nsecs_t c0 = systemTime(timeMode);
+ _c->glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
+ msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
+ return 0;
+ }
+ } caller;
+ caller.target = target;
+ caller.level = level;
+ caller.internalformat = internalformat;
+ caller.width = width;
+ caller.height = height;
+ caller.border = border;
+ caller.format = format;
+ caller.type = type;
+ caller.pixels = pixels;
+
+ msg.set_arg0(target);
+ msg.set_arg1(level);
+ msg.set_arg2(internalformat);
+ msg.set_arg3(width);
+ msg.set_arg4(height);
+ msg.set_arg5(border);
+ msg.set_arg6(format);
+ msg.set_arg7(type);
+ msg.set_arg8(reinterpret_cast<int>(pixels));
+
+ if (pixels) {
+ assert(internalformat == format);
+ assert(0 == border);
+
+ unsigned bytesPerPixel = GetBytesPerPixel(format, type);
+ assert(0 < bytesPerPixel);
+
+// LOGD("GLESv2_dbg: glTexImage2D width=%d height=%d level=%d bytesPerPixel=%d",
+// width, height, level, bytesPerPixel);
+#if USE_RLE
+ unsigned encodedSize = 0;
+ void * data = RLEEncode(pixels, bytesPerPixel, width * height, &encodedSize);
+ msg.set_data(data, encodedSize);
+ free(data);
+ if (encodedSize > bytesPerPixel * width * height)
+ LOGD("GLESv2_dbg: glTexImage2D sending data encodedSize=%d size=%d", encodedSize, bytesPerPixel * width * height);
+#else
+ msg.set_data(pixels, bytesPerPixel * width * height);
+#endif
+ }
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glTexImage2D);
+}
+
+void Debug_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels)
+{
+ glesv2debugger::Message msg;
+ const bool expectResponse = false;
+ struct : public FunctionCall {
+ GLenum target;
+ GLint level;
+ GLint xoffset;
+ GLint yoffset;
+ GLsizei width;
+ GLsizei height;
+ GLenum format;
+ GLenum type;
+ const GLvoid* pixels;
+
+ const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+ nsecs_t c0 = systemTime(timeMode);
+ _c->glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+ msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
+ return 0;
+ }
+ } caller;
+ caller.target = target;
+ caller.level = level;
+ caller.xoffset = xoffset;
+ caller.yoffset = yoffset;
+ caller.width = width;
+ caller.height = height;
+ caller.format = format;
+ caller.type = type;
+ caller.pixels = pixels;
+
+ msg.set_arg0(target);
+ msg.set_arg1(level);
+ msg.set_arg2(xoffset);
+ msg.set_arg3(yoffset);
+ msg.set_arg4(width);
+ msg.set_arg5(height);
+ msg.set_arg6(format);
+ msg.set_arg7(type);
+ msg.set_arg8(reinterpret_cast<int>(pixels));
+
+ assert(pixels);
+ if (pixels) {
+ unsigned bytesPerPixel = GetBytesPerPixel(format, type);
+ assert(0 < bytesPerPixel);
+
+// LOGD("GLESv2_dbg: glTexSubImage2D width=%d height=%d level=%d bytesPerPixel=%d",
+// width, height, level, bytesPerPixel);
+
+#if USE_RLE
+ unsigned encodedSize = 0;
+ void * data = RLEEncode(pixels, bytesPerPixel, width * height, &encodedSize);
+ msg.set_data(data, encodedSize);
+ free(data);
+ if (encodedSize > bytesPerPixel * width * height)
+ LOGD("GLESv2_dbg: glTexImage2D sending data encodedSize=%d size=%d", encodedSize, bytesPerPixel * width * height);
+#else
+ msg.set_data(pixels, bytesPerPixel * width * height);
+#endif
+ }
+
+ int * ret = MessageLoop(caller, msg, expectResponse,
+ glesv2debugger::Message_Function_glTexSubImage2D);
+}
\ No newline at end of file
diff --git a/opengl/libs/GLES2_dbg/src/vertex.cpp b/opengl/libs/GLES2_dbg/src/vertex.cpp
new file mode 100644
index 0000000..52ce907
--- /dev/null
+++ b/opengl/libs/GLES2_dbg/src/vertex.cpp
@@ -0,0 +1,231 @@
+/*
+ ** Copyright 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.
+ */
+
+#include "header.h"
+
+namespace android
+{
+bool capture; // capture after each glDraw*
+
+void * RLEEncode(const void * pixels, const unsigned bytesPerPixel, const unsigned count, unsigned * encodedSize);
+}
+
+void Debug_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
+{
+ DbgContext * const dbg = getDbgContextThreadSpecific();
+ glesv2debugger::Message msg, cmd;
+ msg.set_context_id(reinterpret_cast<int>(dbg));
+ msg.set_type(glesv2debugger::Message_Type_BeforeCall);
+ const bool expectResponse = false;
+ msg.set_expect_response(expectResponse);
+ msg.set_function(glesv2debugger::Message_Function_glReadPixels);
+ msg.set_arg0(x);
+ msg.set_arg1(y);
+ msg.set_arg2(width);
+ msg.set_arg3(height);
+ msg.set_arg4(format);
+ msg.set_arg5(type);
+ msg.set_arg6(reinterpret_cast<int>(pixels));
+ //void * data = NULL;
+ //unsigned encodedSize = 0;
+ Send(msg, cmd);
+ float t = 0;
+ if (!expectResponse)
+ cmd.set_function(glesv2debugger::Message_Function_CONTINUE);
+ while (true) {
+ msg.Clear();
+ nsecs_t c0 = systemTime(timeMode);
+ switch (cmd.function()) {
+ case glesv2debugger::Message_Function_CONTINUE:
+ dbg->hooks->gl.glReadPixels(x, y, width, height, format, type, pixels);
+ msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
+ msg.set_context_id(reinterpret_cast<int>(dbg));
+ msg.set_function(glesv2debugger::Message_Function_glReadPixels);
+ msg.set_type(glesv2debugger::Message_Type_AfterCall);
+ msg.set_expect_response(expectResponse);
+ //data = RLEEncode(pixels, GetBytesPerPixel(format, type), width * height, &encodedSize);
+ msg.set_data(pixels, width * height * GetBytesPerPixel(format, type));
+ //msg.set_data(data, encodedSize);
+ //free(data);
+ c0 = systemTime(timeMode);
+ t = Send(msg, cmd);
+ msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
+ msg.set_clock(t);
+ // time is total send time in seconds, clock is msg serialization time in seconds
+ msg.clear_data();
+ msg.set_expect_response(false);
+ msg.set_type(glesv2debugger::Message_Type_AfterCall);
+ //Send(msg, cmd);
+ if (!expectResponse)
+ cmd.set_function(glesv2debugger::Message_Function_SKIP);
+ break;
+ case glesv2debugger::Message_Function_SKIP:
+ return;
+ default:
+ assert(0); //GenerateCall(msg, cmd);
+ break;
+ }
+ }
+}
+
+void Debug_glDrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+ DbgContext * const dbg = getDbgContextThreadSpecific();
+ glesv2debugger::Message msg, cmd;
+ msg.set_context_id(reinterpret_cast<int>(dbg));
+ msg.set_type(glesv2debugger::Message_Type_BeforeCall);
+ const bool expectResponse = false;
+ msg.set_expect_response(expectResponse);
+ msg.set_function(glesv2debugger::Message_Function_glDrawArrays);
+ msg.set_arg0(mode);
+ msg.set_arg1(first);
+ msg.set_arg2(count);
+
+ msg.set_arg7(dbg->maxAttrib); // indicate capturing vertex data
+ if (dbg->hasNonVBOAttribs) {
+ std::string * const data = msg.mutable_data();
+ for (unsigned i = 0; i < count; i++)
+ dbg->Fetch(i + first, data);
+ }
+
+ void * pixels = NULL;
+ GLint readFormat = 0, readType = 0;
+ int viewport[4] = {};
+ Send(msg, cmd);
+ if (!expectResponse)
+ cmd.set_function(glesv2debugger::Message_Function_CONTINUE);
+ while (true) {
+ msg.Clear();
+ nsecs_t c0 = systemTime(timeMode);
+ switch (cmd.function()) {
+ case glesv2debugger::Message_Function_CONTINUE:
+ dbg->hooks->gl.glDrawArrays(mode, first, count);
+ msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
+ msg.set_context_id(reinterpret_cast<int>(dbg));
+ msg.set_function(glesv2debugger::Message_Function_glDrawArrays);
+ msg.set_type(glesv2debugger::Message_Type_AfterCall);
+ msg.set_expect_response(expectResponse);
+ Send(msg, cmd);
+ if (capture)
+ cmd.set_function(glesv2debugger::Message_Function_CAPTURE);
+ else if (!expectResponse)
+ cmd.set_function(glesv2debugger::Message_Function_SKIP);
+ break;
+ case glesv2debugger::Message_Function_SKIP:
+ return;
+ case glesv2debugger::Message_Function_CAPTURE:
+ dbg->hooks->gl.glGetIntegerv(GL_VIEWPORT, viewport);
+ dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &readFormat);
+ dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &readType);
+ LOGD("glDrawArrays CAPTURE: x=%d y=%d width=%d height=%d format=0x%.4X type=0x%.4X",
+ viewport[0], viewport[1], viewport[2], viewport[3], readFormat, readType);
+ pixels = malloc(viewport[2] * viewport[3] * 4);
+ Debug_glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
+ readFormat, readType, pixels);
+ free(pixels);
+ cmd.set_function(glesv2debugger::Message_Function_SKIP);
+ break;
+ default:
+ assert(0); //GenerateCall(msg, cmd);
+ break;
+ }
+ }
+}
+
+template<typename T>
+static inline void FetchIndexed(const unsigned count, const T * indices,
+ std::string * const data, const DbgContext * const ctx)
+{
+ for (unsigned i = 0; i < count; i++) {
+ if (!ctx->indexBuffer)
+ data->append((const char *)(indices + i), sizeof(*indices));
+ if (ctx->hasNonVBOAttribs)
+ ctx->Fetch(indices[i], data);
+ }
+}
+
+void Debug_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
+{
+ DbgContext * const dbg = getDbgContextThreadSpecific();
+ glesv2debugger::Message msg, cmd;
+ msg.set_context_id(reinterpret_cast<int>(dbg));
+ msg.set_type(glesv2debugger::Message_Type_BeforeCall);
+ const bool expectResponse = false;
+ msg.set_expect_response(expectResponse);
+ msg.set_function(glesv2debugger::Message_Function_glDrawElements);
+ msg.set_arg0(mode);
+ msg.set_arg1(count);
+ msg.set_arg2(type);
+ msg.set_arg3(reinterpret_cast<int>(indices));
+
+ msg.set_arg7(dbg->maxAttrib); // indicate capturing vertex data
+ std::string * const data = msg.mutable_data();
+ if (GL_UNSIGNED_BYTE == type) {
+ if (dbg->indexBuffer)
+ FetchIndexed(count, (unsigned char *)dbg->indexBuffer->data + (unsigned long)indices, data, dbg);
+ else
+ FetchIndexed(count, (unsigned char *)indices, data, dbg);
+ } else if (GL_UNSIGNED_SHORT == type) {
+ if (dbg->indexBuffer)
+ FetchIndexed(count, (unsigned short *)((char *)dbg->indexBuffer->data + (unsigned long)indices), data, dbg);
+ else
+ FetchIndexed(count, (unsigned short *)indices, data, dbg);
+ } else
+ assert(0);
+
+ void * pixels = NULL;
+ GLint readFormat = 0, readType = 0;
+ int viewport[4] = {};
+ Send(msg, cmd);
+ if (!expectResponse)
+ cmd.set_function(glesv2debugger::Message_Function_CONTINUE);
+ while (true) {
+ msg.Clear();
+ nsecs_t c0 = systemTime(timeMode);
+ switch (cmd.function()) {
+ case glesv2debugger::Message_Function_CONTINUE:
+ dbg->hooks->gl.glDrawElements(mode, count, type, indices);
+ msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
+ msg.set_context_id(reinterpret_cast<int>(dbg));
+ msg.set_function(glesv2debugger::Message_Function_glDrawElements);
+ msg.set_type(glesv2debugger::Message_Type_AfterCall);
+ msg.set_expect_response(expectResponse);
+ Send(msg, cmd);
+ if (capture)
+ cmd.set_function(glesv2debugger::Message_Function_CAPTURE);
+ else if (!expectResponse)
+ cmd.set_function(glesv2debugger::Message_Function_SKIP);
+ break;
+ case glesv2debugger::Message_Function_SKIP:
+ return;
+ case glesv2debugger::Message_Function_CAPTURE:
+ dbg->hooks->gl.glGetIntegerv(GL_VIEWPORT, viewport);
+ dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &readFormat);
+ dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &readType);
+ LOGD("glDrawArrays CAPTURE: x=%d y=%d width=%d height=%d format=0x%.4X type=0x%.4X",
+ viewport[0], viewport[1], viewport[2], viewport[3], readFormat, readType);
+ pixels = malloc(viewport[2] * viewport[3] * 4);
+ Debug_glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
+ readFormat, readType, pixels);
+ free(pixels);
+ cmd.set_function(glesv2debugger::Message_Function_SKIP);
+ break;
+ default:
+ assert(0); //GenerateCall(msg, cmd);
+ break;
+ }
+ }
+}
diff --git a/opengl/libs/debug.in b/opengl/libs/debug.in
new file mode 100644
index 0000000..882b2da
--- /dev/null
+++ b/opengl/libs/debug.in
@@ -0,0 +1,235 @@
+// the following functions are not defined in GLESv2_dbg
+TRACE_GL_VOID(glAlphaFunc, (GLenum func, GLclampf ref), (func, ref), 2, "GLenum", func, "GLclampf", ref)
+TRACE_GL_VOID(glAlphaFuncx, (GLenum func, GLclampx ref), (func, ref), 2, "GLenum", func, "GLclampx", ref)
+TRACE_GL_VOID(glAlphaFuncxOES, (GLenum func, GLclampx ref), (func, ref), 2, "GLenum", func, "GLclampx", ref)
+TRACE_GL_VOID(glBeginPerfMonitorAMD, (GLuint monitor), (monitor), 1, "GLuint", monitor)
+TRACE_GL_VOID(glBindFramebufferOES, (GLenum target, GLuint framebuffer), (target, framebuffer), 2, "GLenum", target, "GLuint", framebuffer)
+TRACE_GL_VOID(glBindRenderbufferOES, (GLenum target, GLuint renderbuffer), (target, renderbuffer), 2, "GLenum", target, "GLuint", renderbuffer)
+TRACE_GL_VOID(glBindVertexArrayOES, (GLuint array), (array), 1, "GLuint", array)
+TRACE_GL_VOID(glBlendEquationOES, (GLenum mode), (mode), 1, "GLenum", mode)
+TRACE_GL_VOID(glBlendEquationSeparateOES, (GLenum modeRGB, GLenum modeAlpha), (modeRGB, modeAlpha), 2, "GLenum", modeRGB, "GLenum", modeAlpha)
+TRACE_GL_VOID(glBlendFuncSeparateOES, (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha), (srcRGB, dstRGB, srcAlpha, dstAlpha), 4, "GLenum", srcRGB, "GLenum", dstRGB, "GLenum", srcAlpha, "GLenum", dstAlpha)
+TRACE_GL(GLenum, glCheckFramebufferStatusOES, (GLenum target), (target), 1, "GLenum", target)
+TRACE_GL_VOID(glClearColorx, (GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha), (red, green, blue, alpha), 4, "GLclampx", red, "GLclampx", green, "GLclampx", blue, "GLclampx", alpha)
+TRACE_GL_VOID(glClearColorxOES, (GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha), (red, green, blue, alpha), 4, "GLclampx", red, "GLclampx", green, "GLclampx", blue, "GLclampx", alpha)
+TRACE_GL_VOID(glClearDepthfOES, (GLclampf depth), (depth), 1, "GLclampf", depth)
+TRACE_GL_VOID(glClearDepthx, (GLclampx depth), (depth), 1, "GLclampx", depth)
+TRACE_GL_VOID(glClearDepthxOES, (GLclampx depth), (depth), 1, "GLclampx", depth)
+TRACE_GL_VOID(glClientActiveTexture, (GLenum texture), (texture), 1, "GLenum", texture)
+TRACE_GL_VOID(glClipPlanef, (GLenum plane, const GLfloat *equation), (plane, equation), 2, "GLenum", plane, "const GLfloat *", equation)
+TRACE_GL_VOID(glClipPlanefIMG, (GLenum p, const GLfloat *eqn), (p, eqn), 2, "GLenum", p, "const GLfloat *", eqn)
+TRACE_GL_VOID(glClipPlanefOES, (GLenum plane, const GLfloat *equation), (plane, equation), 2, "GLenum", plane, "const GLfloat *", equation)
+TRACE_GL_VOID(glClipPlanex, (GLenum plane, const GLfixed *equation), (plane, equation), 2, "GLenum", plane, "const GLfixed *", equation)
+TRACE_GL_VOID(glClipPlanexIMG, (GLenum p, const GLfixed *eqn), (p, eqn), 2, "GLenum", p, "const GLfixed *", eqn)
+TRACE_GL_VOID(glClipPlanexOES, (GLenum plane, const GLfixed *equation), (plane, equation), 2, "GLenum", plane, "const GLfixed *", equation)
+TRACE_GL_VOID(glColor4f, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha), (red, green, blue, alpha), 4, "GLfloat", red, "GLfloat", green, "GLfloat", blue, "GLfloat", alpha)
+TRACE_GL_VOID(glColor4ub, (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha), (red, green, blue, alpha), 4, "GLubyte", red, "GLubyte", green, "GLubyte", blue, "GLubyte", alpha)
+TRACE_GL_VOID(glColor4x, (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha), (red, green, blue, alpha), 4, "GLfixed", red, "GLfixed", green, "GLfixed", blue, "GLfixed", alpha)
+TRACE_GL_VOID(glColor4xOES, (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha), (red, green, blue, alpha), 4, "GLfixed", red, "GLfixed", green, "GLfixed", blue, "GLfixed", alpha)
+TRACE_GL_VOID(glColorPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer), (size, type, stride, pointer), 4, "GLint", size, "GLenum", type, "GLsizei", stride, "const GLvoid *", pointer)
+TRACE_GL_VOID(glCompressedTexImage3DOES, (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data), (target, level, internalformat, width, height, depth, border, imageSize, data), 9, "GLenum", target, "GLint", level, "GLenum", internalformat, "GLsizei", width, "GLsizei", height, "GLsizei", depth, "GLint", border, "GLsizei", imageSize, "const GLvoid*", data)
+TRACE_GL_VOID(glCompressedTexSubImage3DOES, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data), (target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data), 11, "GLenum", target, "GLint", level, "GLint", xoffset, "GLint", yoffset, "GLint", zoffset, "GLsizei", width, "GLsizei", height, "GLsizei", depth, "GLenum", format, "GLsizei", imageSize, "const GLvoid*", data)
+TRACE_GL_VOID(glCopyTexSubImage3DOES, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height), (target, level, xoffset, yoffset, zoffset, x, y, width, height), 9, "GLenum", target, "GLint", level, "GLint", xoffset, "GLint", yoffset, "GLint", zoffset, "GLint", x, "GLint", y, "GLsizei", width, "GLsizei", height)
+TRACE_GL_VOID(glCoverageMaskNV, (GLboolean mask), (mask), 1, "GLboolean", mask)
+TRACE_GL_VOID(glCoverageOperationNV, (GLenum operation), (operation), 1, "GLenum", operation)
+TRACE_GL_VOID(glCurrentPaletteMatrixOES, (GLuint matrixpaletteindex), (matrixpaletteindex), 1, "GLuint", matrixpaletteindex)
+TRACE_GL_VOID(glDeleteFencesNV, (GLsizei n, const GLuint *fences), (n, fences), 2, "GLsizei", n, "const GLuint *", fences)
+TRACE_GL_VOID(glDeleteFramebuffersOES, (GLsizei n, const GLuint* framebuffers), (n, framebuffers), 2, "GLsizei", n, "const GLuint*", framebuffers)
+TRACE_GL_VOID(glDeletePerfMonitorsAMD, (GLsizei n, GLuint *monitors), (n, monitors), 2, "GLsizei", n, "GLuint *", monitors)
+TRACE_GL_VOID(glDeleteRenderbuffersOES, (GLsizei n, const GLuint* renderbuffers), (n, renderbuffers), 2, "GLsizei", n, "const GLuint*", renderbuffers)
+TRACE_GL_VOID(glDeleteVertexArraysOES, (GLsizei n, const GLuint *arrays), (n, arrays), 2, "GLsizei", n, "const GLuint *", arrays)
+TRACE_GL_VOID(glDepthRangefOES, (GLclampf zNear, GLclampf zFar), (zNear, zFar), 2, "GLclampf", zNear, "GLclampf", zFar)
+TRACE_GL_VOID(glDepthRangex, (GLclampx zNear, GLclampx zFar), (zNear, zFar), 2, "GLclampx", zNear, "GLclampx", zFar)
+TRACE_GL_VOID(glDepthRangexOES, (GLclampx zNear, GLclampx zFar), (zNear, zFar), 2, "GLclampx", zNear, "GLclampx", zFar)
+TRACE_GL_VOID(glDisableClientState, (GLenum array), (array), 1, "GLenum", array)
+TRACE_GL_VOID(glDisableDriverControlQCOM, (GLuint driverControl), (driverControl), 1, "GLuint", driverControl)
+TRACE_GL_VOID(glDiscardFramebufferEXT, (GLenum target, GLsizei numAttachments, const GLenum *attachments), (target, numAttachments, attachments), 3, "GLenum", target, "GLsizei", numAttachments, "const GLenum *", attachments)
+TRACE_GL_VOID(glDrawTexfOES, (GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height), (x, y, z, width, height), 5, "GLfloat", x, "GLfloat", y, "GLfloat", z, "GLfloat", width, "GLfloat", height)
+TRACE_GL_VOID(glDrawTexfvOES, (const GLfloat *coords), (coords), 1, "const GLfloat *", coords)
+TRACE_GL_VOID(glDrawTexiOES, (GLint x, GLint y, GLint z, GLint width, GLint height), (x, y, z, width, height), 5, "GLint", x, "GLint", y, "GLint", z, "GLint", width, "GLint", height)
+TRACE_GL_VOID(glDrawTexivOES, (const GLint *coords), (coords), 1, "const GLint *", coords)
+TRACE_GL_VOID(glDrawTexsOES, (GLshort x, GLshort y, GLshort z, GLshort width, GLshort height), (x, y, z, width, height), 5, "GLshort", x, "GLshort", y, "GLshort", z, "GLshort", width, "GLshort", height)
+TRACE_GL_VOID(glDrawTexsvOES, (const GLshort *coords), (coords), 1, "const GLshort *", coords)
+TRACE_GL_VOID(glDrawTexxOES, (GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height), (x, y, z, width, height), 5, "GLfixed", x, "GLfixed", y, "GLfixed", z, "GLfixed", width, "GLfixed", height)
+TRACE_GL_VOID(glDrawTexxvOES, (const GLfixed *coords), (coords), 1, "const GLfixed *", coords)
+TRACE_GL_VOID(glEGLImageTargetRenderbufferStorageOES, (GLenum target, GLeglImageOES image), (target, image), 2, "GLenum", target, "GLeglImageOES", image)
+TRACE_GL_VOID(glEGLImageTargetTexture2DOES, (GLenum target, GLeglImageOES image), (target, image), 2, "GLenum", target, "GLeglImageOES", image)
+TRACE_GL_VOID(glEnableClientState, (GLenum array), (array), 1, "GLenum", array)
+TRACE_GL_VOID(glEnableDriverControlQCOM, (GLuint driverControl), (driverControl), 1, "GLuint", driverControl)
+TRACE_GL_VOID(glEndPerfMonitorAMD, (GLuint monitor), (monitor), 1, "GLuint", monitor)
+TRACE_GL_VOID(glEndTilingQCOM, (GLbitfield preserveMask), (preserveMask), 1, "GLbitfield", preserveMask)
+TRACE_GL_VOID(glExtGetBufferPointervQCOM, (GLenum target, GLvoid **params), (target, params), 2, "GLenum", target, "GLvoid **", params)
+TRACE_GL_VOID(glExtGetBuffersQCOM, (GLuint *buffers, GLint maxBuffers, GLint *numBuffers), (buffers, maxBuffers, numBuffers), 3, "GLuint *", buffers, "GLint", maxBuffers, "GLint *", numBuffers)
+TRACE_GL_VOID(glExtGetFramebuffersQCOM, (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers), (framebuffers, maxFramebuffers, numFramebuffers), 3, "GLuint *", framebuffers, "GLint", maxFramebuffers, "GLint *", numFramebuffers)
+TRACE_GL_VOID(glExtGetProgramBinarySourceQCOM, (GLuint program, GLenum shadertype, GLchar *source, GLint *length), (program, shadertype, source, length), 4, "GLuint", program, "GLenum", shadertype, "GLchar *", source, "GLint *", length)
+TRACE_GL_VOID(glExtGetProgramsQCOM, (GLuint *programs, GLint maxPrograms, GLint *numPrograms), (programs, maxPrograms, numPrograms), 3, "GLuint *", programs, "GLint", maxPrograms, "GLint *", numPrograms)
+TRACE_GL_VOID(glExtGetRenderbuffersQCOM, (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers), (renderbuffers, maxRenderbuffers, numRenderbuffers), 3, "GLuint *", renderbuffers, "GLint", maxRenderbuffers, "GLint *", numRenderbuffers)
+TRACE_GL_VOID(glExtGetShadersQCOM, (GLuint *shaders, GLint maxShaders, GLint *numShaders), (shaders, maxShaders, numShaders), 3, "GLuint *", shaders, "GLint", maxShaders, "GLint *", numShaders)
+TRACE_GL_VOID(glExtGetTexLevelParameterivQCOM, (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params), (texture, face, level, pname, params), 5, "GLuint", texture, "GLenum", face, "GLint", level, "GLenum", pname, "GLint *", params)
+TRACE_GL_VOID(glExtGetTexSubImageQCOM, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels), (target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, texels), 11, "GLenum", target, "GLint", level, "GLint", xoffset, "GLint", yoffset, "GLint", zoffset, "GLsizei", width, "GLsizei", height, "GLsizei", depth, "GLenum", format, "GLenum", type, "GLvoid *", texels)
+TRACE_GL_VOID(glExtGetTexturesQCOM, (GLuint *textures, GLint maxTextures, GLint *numTextures), (textures, maxTextures, numTextures), 3, "GLuint *", textures, "GLint", maxTextures, "GLint *", numTextures)
+TRACE_GL(GLboolean, glExtIsProgramBinaryQCOM, (GLuint program), (program), 1, "GLuint", program)
+TRACE_GL_VOID(glExtTexObjectStateOverrideiQCOM, (GLenum target, GLenum pname, GLint param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLint", param)
+TRACE_GL_VOID(glFinishFenceNV, (GLuint fence), (fence), 1, "GLuint", fence)
+TRACE_GL_VOID(glFogf, (GLenum pname, GLfloat param), (pname, param), 2, "GLenum", pname, "GLfloat", param)
+TRACE_GL_VOID(glFogfv, (GLenum pname, const GLfloat *params), (pname, params), 2, "GLenum", pname, "const GLfloat *", params)
+TRACE_GL_VOID(glFogx, (GLenum pname, GLfixed param), (pname, param), 2, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glFogxOES, (GLenum pname, GLfixed param), (pname, param), 2, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glFogxv, (GLenum pname, const GLfixed *params), (pname, params), 2, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glFogxvOES, (GLenum pname, const GLfixed *params), (pname, params), 2, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glFramebufferRenderbufferOES, (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer), (target, attachment, renderbuffertarget, renderbuffer), 4, "GLenum", target, "GLenum", attachment, "GLenum", renderbuffertarget, "GLuint", renderbuffer)
+TRACE_GL_VOID(glFramebufferTexture2DMultisampleIMG, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples), (target, attachment, textarget, texture, level, samples), 6, "GLenum", target, "GLenum", attachment, "GLenum", textarget, "GLuint", texture, "GLint", level, "GLsizei", samples)
+TRACE_GL_VOID(glFramebufferTexture2DOES, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level), (target, attachment, textarget, texture, level), 5, "GLenum", target, "GLenum", attachment, "GLenum", textarget, "GLuint", texture, "GLint", level)
+TRACE_GL_VOID(glFramebufferTexture3DOES, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset), (target, attachment, textarget, texture, level, zoffset), 6, "GLenum", target, "GLenum", attachment, "GLenum", textarget, "GLuint", texture, "GLint", level, "GLint", zoffset)
+TRACE_GL_VOID(glFrustumf, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfloat", left, "GLfloat", right, "GLfloat", bottom, "GLfloat", top, "GLfloat", zNear, "GLfloat", zFar)
+TRACE_GL_VOID(glFrustumfOES, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfloat", left, "GLfloat", right, "GLfloat", bottom, "GLfloat", top, "GLfloat", zNear, "GLfloat", zFar)
+TRACE_GL_VOID(glFrustumx, (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfixed", left, "GLfixed", right, "GLfixed", bottom, "GLfixed", top, "GLfixed", zNear, "GLfixed", zFar)
+TRACE_GL_VOID(glFrustumxOES, (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfixed", left, "GLfixed", right, "GLfixed", bottom, "GLfixed", top, "GLfixed", zNear, "GLfixed", zFar)
+TRACE_GL_VOID(glGenFencesNV, (GLsizei n, GLuint *fences), (n, fences), 2, "GLsizei", n, "GLuint *", fences)
+TRACE_GL_VOID(glGenFramebuffersOES, (GLsizei n, GLuint* framebuffers), (n, framebuffers), 2, "GLsizei", n, "GLuint*", framebuffers)
+TRACE_GL_VOID(glGenPerfMonitorsAMD, (GLsizei n, GLuint *monitors), (n, monitors), 2, "GLsizei", n, "GLuint *", monitors)
+TRACE_GL_VOID(glGenRenderbuffersOES, (GLsizei n, GLuint* renderbuffers), (n, renderbuffers), 2, "GLsizei", n, "GLuint*", renderbuffers)
+TRACE_GL_VOID(glGenVertexArraysOES, (GLsizei n, GLuint *arrays), (n, arrays), 2, "GLsizei", n, "GLuint *", arrays)
+TRACE_GL_VOID(glGenerateMipmapOES, (GLenum target), (target), 1, "GLenum", target)
+TRACE_GL_VOID(glGetBufferPointervOES, (GLenum target, GLenum pname, GLvoid ** params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLvoid **", params)
+TRACE_GL_VOID(glGetClipPlanef, (GLenum pname, GLfloat eqn[4]), (pname, eqn), 2, "GLenum", pname, "GLfloat", eqn)
+TRACE_GL_VOID(glGetClipPlanefOES, (GLenum pname, GLfloat eqn[4]), (pname, eqn), 2, "GLenum", pname, "GLfloat", eqn)
+TRACE_GL_VOID(glGetClipPlanex, (GLenum pname, GLfixed eqn[4]), (pname, eqn), 2, "GLenum", pname, "GLfixed", eqn)
+TRACE_GL_VOID(glGetClipPlanexOES, (GLenum pname, GLfixed eqn[4]), (pname, eqn), 2, "GLenum", pname, "GLfixed", eqn)
+TRACE_GL_VOID(glGetDriverControlStringQCOM, (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString), (driverControl, bufSize, length, driverControlString), 4, "GLuint", driverControl, "GLsizei", bufSize, "GLsizei *", length, "GLchar *", driverControlString)
+TRACE_GL_VOID(glGetDriverControlsQCOM, (GLint *num, GLsizei size, GLuint *driverControls), (num, size, driverControls), 3, "GLint *", num, "GLsizei", size, "GLuint *", driverControls)
+TRACE_GL_VOID(glGetFenceivNV, (GLuint fence, GLenum pname, GLint *params), (fence, pname, params), 3, "GLuint", fence, "GLenum", pname, "GLint *", params)
+TRACE_GL_VOID(glGetFixedv, (GLenum pname, GLfixed *params), (pname, params), 2, "GLenum", pname, "GLfixed *", params)
+TRACE_GL_VOID(glGetFixedvOES, (GLenum pname, GLfixed *params), (pname, params), 2, "GLenum", pname, "GLfixed *", params)
+TRACE_GL_VOID(glGetFramebufferAttachmentParameterivOES, (GLenum target, GLenum attachment, GLenum pname, GLint* params), (target, attachment, pname, params), 4, "GLenum", target, "GLenum", attachment, "GLenum", pname, "GLint*", params)
+TRACE_GL_VOID(glGetLightfv, (GLenum light, GLenum pname, GLfloat *params), (light, pname, params), 3, "GLenum", light, "GLenum", pname, "GLfloat *", params)
+TRACE_GL_VOID(glGetLightxv, (GLenum light, GLenum pname, GLfixed *params), (light, pname, params), 3, "GLenum", light, "GLenum", pname, "GLfixed *", params)
+TRACE_GL_VOID(glGetLightxvOES, (GLenum light, GLenum pname, GLfixed *params), (light, pname, params), 3, "GLenum", light, "GLenum", pname, "GLfixed *", params)
+TRACE_GL_VOID(glGetMaterialfv, (GLenum face, GLenum pname, GLfloat *params), (face, pname, params), 3, "GLenum", face, "GLenum", pname, "GLfloat *", params)
+TRACE_GL_VOID(glGetMaterialxv, (GLenum face, GLenum pname, GLfixed *params), (face, pname, params), 3, "GLenum", face, "GLenum", pname, "GLfixed *", params)
+TRACE_GL_VOID(glGetMaterialxvOES, (GLenum face, GLenum pname, GLfixed *params), (face, pname, params), 3, "GLenum", face, "GLenum", pname, "GLfixed *", params)
+TRACE_GL_VOID(glGetPerfMonitorCounterDataAMD, (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten), (monitor, pname, dataSize, data, bytesWritten), 5, "GLuint", monitor, "GLenum", pname, "GLsizei", dataSize, "GLuint *", data, "GLint *", bytesWritten)
+TRACE_GL_VOID(glGetPerfMonitorCounterInfoAMD, (GLuint group, GLuint counter, GLenum pname, GLvoid *data), (group, counter, pname, data), 4, "GLuint", group, "GLuint", counter, "GLenum", pname, "GLvoid *", data)
+TRACE_GL_VOID(glGetPerfMonitorCounterStringAMD, (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString), (group, counter, bufSize, length, counterString), 5, "GLuint", group, "GLuint", counter, "GLsizei", bufSize, "GLsizei *", length, "GLchar *", counterString)
+TRACE_GL_VOID(glGetPerfMonitorCountersAMD, (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters), (group, numCounters, maxActiveCounters, counterSize, counters), 5, "GLuint", group, "GLint *", numCounters, "GLint *", maxActiveCounters, "GLsizei", counterSize, "GLuint *", counters)
+TRACE_GL_VOID(glGetPerfMonitorGroupStringAMD, (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString), (group, bufSize, length, groupString), 4, "GLuint", group, "GLsizei", bufSize, "GLsizei *", length, "GLchar *", groupString)
+TRACE_GL_VOID(glGetPerfMonitorGroupsAMD, (GLint *numGroups, GLsizei groupsSize, GLuint *groups), (numGroups, groupsSize, groups), 3, "GLint *", numGroups, "GLsizei", groupsSize, "GLuint *", groups)
+TRACE_GL_VOID(glGetPointerv, (GLenum pname, GLvoid **params), (pname, params), 2, "GLenum", pname, "GLvoid **", params)
+TRACE_GL_VOID(glGetProgramBinaryOES, (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary), (program, bufSize, length, binaryFormat, binary), 5, "GLuint", program, "GLsizei", bufSize, "GLsizei *", length, "GLenum *", binaryFormat, "GLvoid *", binary)
+TRACE_GL_VOID(glGetRenderbufferParameterivOES, (GLenum target, GLenum pname, GLint* params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLint*", params)
+TRACE_GL_VOID(glGetTexEnvfv, (GLenum env, GLenum pname, GLfloat *params), (env, pname, params), 3, "GLenum", env, "GLenum", pname, "GLfloat *", params)
+TRACE_GL_VOID(glGetTexEnviv, (GLenum env, GLenum pname, GLint *params), (env, pname, params), 3, "GLenum", env, "GLenum", pname, "GLint *", params)
+TRACE_GL_VOID(glGetTexEnvxv, (GLenum env, GLenum pname, GLfixed *params), (env, pname, params), 3, "GLenum", env, "GLenum", pname, "GLfixed *", params)
+TRACE_GL_VOID(glGetTexEnvxvOES, (GLenum env, GLenum pname, GLfixed *params), (env, pname, params), 3, "GLenum", env, "GLenum", pname, "GLfixed *", params)
+TRACE_GL_VOID(glGetTexGenfvOES, (GLenum coord, GLenum pname, GLfloat *params), (coord, pname, params), 3, "GLenum", coord, "GLenum", pname, "GLfloat *", params)
+TRACE_GL_VOID(glGetTexGenivOES, (GLenum coord, GLenum pname, GLint *params), (coord, pname, params), 3, "GLenum", coord, "GLenum", pname, "GLint *", params)
+TRACE_GL_VOID(glGetTexGenxvOES, (GLenum coord, GLenum pname, GLfixed *params), (coord, pname, params), 3, "GLenum", coord, "GLenum", pname, "GLfixed *", params)
+TRACE_GL_VOID(glGetTexParameterxv, (GLenum target, GLenum pname, GLfixed *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLfixed *", params)
+TRACE_GL_VOID(glGetTexParameterxvOES, (GLenum target, GLenum pname, GLfixed *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLfixed *", params)
+TRACE_GL(GLboolean, glIsFenceNV, (GLuint fence), (fence), 1, "GLuint", fence)
+TRACE_GL(GLboolean, glIsFramebufferOES, (GLuint framebuffer), (framebuffer), 1, "GLuint", framebuffer)
+TRACE_GL(GLboolean, glIsRenderbufferOES, (GLuint renderbuffer), (renderbuffer), 1, "GLuint", renderbuffer)
+TRACE_GL(GLboolean, glIsVertexArrayOES, (GLuint array), (array), 1, "GLuint", array)
+TRACE_GL_VOID(glLightModelf, (GLenum pname, GLfloat param), (pname, param), 2, "GLenum", pname, "GLfloat", param)
+TRACE_GL_VOID(glLightModelfv, (GLenum pname, const GLfloat *params), (pname, params), 2, "GLenum", pname, "const GLfloat *", params)
+TRACE_GL_VOID(glLightModelx, (GLenum pname, GLfixed param), (pname, param), 2, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glLightModelxOES, (GLenum pname, GLfixed param), (pname, param), 2, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glLightModelxv, (GLenum pname, const GLfixed *params), (pname, params), 2, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glLightModelxvOES, (GLenum pname, const GLfixed *params), (pname, params), 2, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glLightf, (GLenum light, GLenum pname, GLfloat param), (light, pname, param), 3, "GLenum", light, "GLenum", pname, "GLfloat", param)
+TRACE_GL_VOID(glLightfv, (GLenum light, GLenum pname, const GLfloat *params), (light, pname, params), 3, "GLenum", light, "GLenum", pname, "const GLfloat *", params)
+TRACE_GL_VOID(glLightx, (GLenum light, GLenum pname, GLfixed param), (light, pname, param), 3, "GLenum", light, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glLightxOES, (GLenum light, GLenum pname, GLfixed param), (light, pname, param), 3, "GLenum", light, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glLightxv, (GLenum light, GLenum pname, const GLfixed *params), (light, pname, params), 3, "GLenum", light, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glLightxvOES, (GLenum light, GLenum pname, const GLfixed *params), (light, pname, params), 3, "GLenum", light, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glLineWidthx, (GLfixed width), (width), 1, "GLfixed", width)
+TRACE_GL_VOID(glLineWidthxOES, (GLfixed width), (width), 1, "GLfixed", width)
+TRACE_GL_VOID(glLoadIdentity, (void), (), 0)
+TRACE_GL_VOID(glLoadMatrixf, (const GLfloat *m), (m), 1, "const GLfloat *", m)
+TRACE_GL_VOID(glLoadMatrixx, (const GLfixed *m), (m), 1, "const GLfixed *", m)
+TRACE_GL_VOID(glLoadMatrixxOES, (const GLfixed *m), (m), 1, "const GLfixed *", m)
+TRACE_GL_VOID(glLoadPaletteFromModelViewMatrixOES, (void), (), 0)
+TRACE_GL_VOID(glLogicOp, (GLenum opcode), (opcode), 1, "GLenum", opcode)
+TRACE_GL(void*, glMapBufferOES, (GLenum target, GLenum access), (target, access), 2, "GLenum", target, "GLenum", access)
+TRACE_GL_VOID(glMaterialf, (GLenum face, GLenum pname, GLfloat param), (face, pname, param), 3, "GLenum", face, "GLenum", pname, "GLfloat", param)
+TRACE_GL_VOID(glMaterialfv, (GLenum face, GLenum pname, const GLfloat *params), (face, pname, params), 3, "GLenum", face, "GLenum", pname, "const GLfloat *", params)
+TRACE_GL_VOID(glMaterialx, (GLenum face, GLenum pname, GLfixed param), (face, pname, param), 3, "GLenum", face, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glMaterialxOES, (GLenum face, GLenum pname, GLfixed param), (face, pname, param), 3, "GLenum", face, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glMaterialxv, (GLenum face, GLenum pname, const GLfixed *params), (face, pname, params), 3, "GLenum", face, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glMaterialxvOES, (GLenum face, GLenum pname, const GLfixed *params), (face, pname, params), 3, "GLenum", face, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glMatrixIndexPointerOES, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer), (size, type, stride, pointer), 4, "GLint", size, "GLenum", type, "GLsizei", stride, "const GLvoid *", pointer)
+TRACE_GL_VOID(glMatrixMode, (GLenum mode), (mode), 1, "GLenum", mode)
+TRACE_GL_VOID(glMultMatrixf, (const GLfloat *m), (m), 1, "const GLfloat *", m)
+TRACE_GL_VOID(glMultMatrixx, (const GLfixed *m), (m), 1, "const GLfixed *", m)
+TRACE_GL_VOID(glMultMatrixxOES, (const GLfixed *m), (m), 1, "const GLfixed *", m)
+TRACE_GL_VOID(glMultiDrawArraysEXT, (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount), (mode, first, count, primcount), 4, "GLenum", mode, "GLint *", first, "GLsizei *", count, "GLsizei", primcount)
+TRACE_GL_VOID(glMultiDrawElementsEXT, (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount), (mode, count, type, indices, primcount), 5, "GLenum", mode, "const GLsizei *", count, "GLenum", type, "const GLvoid* *", indices, "GLsizei", primcount)
+TRACE_GL_VOID(glMultiTexCoord4f, (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q), (target, s, t, r, q), 5, "GLenum", target, "GLfloat", s, "GLfloat", t, "GLfloat", r, "GLfloat", q)
+TRACE_GL_VOID(glMultiTexCoord4x, (GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q), (target, s, t, r, q), 5, "GLenum", target, "GLfixed", s, "GLfixed", t, "GLfixed", r, "GLfixed", q)
+TRACE_GL_VOID(glMultiTexCoord4xOES, (GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q), (target, s, t, r, q), 5, "GLenum", target, "GLfixed", s, "GLfixed", t, "GLfixed", r, "GLfixed", q)
+TRACE_GL_VOID(glNormal3f, (GLfloat nx, GLfloat ny, GLfloat nz), (nx, ny, nz), 3, "GLfloat", nx, "GLfloat", ny, "GLfloat", nz)
+TRACE_GL_VOID(glNormal3x, (GLfixed nx, GLfixed ny, GLfixed nz), (nx, ny, nz), 3, "GLfixed", nx, "GLfixed", ny, "GLfixed", nz)
+TRACE_GL_VOID(glNormal3xOES, (GLfixed nx, GLfixed ny, GLfixed nz), (nx, ny, nz), 3, "GLfixed", nx, "GLfixed", ny, "GLfixed", nz)
+TRACE_GL_VOID(glNormalPointer, (GLenum type, GLsizei stride, const GLvoid *pointer), (type, stride, pointer), 3, "GLenum", type, "GLsizei", stride, "const GLvoid *", pointer)
+TRACE_GL_VOID(glOrthof, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfloat", left, "GLfloat", right, "GLfloat", bottom, "GLfloat", top, "GLfloat", zNear, "GLfloat", zFar)
+TRACE_GL_VOID(glOrthofOES, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfloat", left, "GLfloat", right, "GLfloat", bottom, "GLfloat", top, "GLfloat", zNear, "GLfloat", zFar)
+TRACE_GL_VOID(glOrthox, (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfixed", left, "GLfixed", right, "GLfixed", bottom, "GLfixed", top, "GLfixed", zNear, "GLfixed", zFar)
+TRACE_GL_VOID(glOrthoxOES, (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfixed", left, "GLfixed", right, "GLfixed", bottom, "GLfixed", top, "GLfixed", zNear, "GLfixed", zFar)
+TRACE_GL_VOID(glPointParameterf, (GLenum pname, GLfloat param), (pname, param), 2, "GLenum", pname, "GLfloat", param)
+TRACE_GL_VOID(glPointParameterfv, (GLenum pname, const GLfloat *params), (pname, params), 2, "GLenum", pname, "const GLfloat *", params)
+TRACE_GL_VOID(glPointParameterx, (GLenum pname, GLfixed param), (pname, param), 2, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glPointParameterxOES, (GLenum pname, GLfixed param), (pname, param), 2, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glPointParameterxv, (GLenum pname, const GLfixed *params), (pname, params), 2, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glPointParameterxvOES, (GLenum pname, const GLfixed *params), (pname, params), 2, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glPointSize, (GLfloat size), (size), 1, "GLfloat", size)
+TRACE_GL_VOID(glPointSizePointerOES, (GLenum type, GLsizei stride, const GLvoid *pointer), (type, stride, pointer), 3, "GLenum", type, "GLsizei", stride, "const GLvoid *", pointer)
+TRACE_GL_VOID(glPointSizex, (GLfixed size), (size), 1, "GLfixed", size)
+TRACE_GL_VOID(glPointSizexOES, (GLfixed size), (size), 1, "GLfixed", size)
+TRACE_GL_VOID(glPolygonOffsetx, (GLfixed factor, GLfixed units), (factor, units), 2, "GLfixed", factor, "GLfixed", units)
+TRACE_GL_VOID(glPolygonOffsetxOES, (GLfixed factor, GLfixed units), (factor, units), 2, "GLfixed", factor, "GLfixed", units)
+TRACE_GL_VOID(glPopMatrix, (void), (), 0)
+TRACE_GL_VOID(glProgramBinaryOES, (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length), (program, binaryFormat, binary, length), 4, "GLuint", program, "GLenum", binaryFormat, "const GLvoid *", binary, "GLint", length)
+TRACE_GL_VOID(glPushMatrix, (void), (), 0)
+TRACE_GL(GLbitfield, glQueryMatrixxOES, (GLfixed mantissa[16], GLint exponent[16]), (mantissa, exponent), 2, "GLfixed", mantissa, "GLint", exponent)
+TRACE_GL_VOID(glRenderbufferStorageMultisampleIMG, (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height), (target, samples, internalformat, width, height), 5, "GLenum", target, "GLsizei", samples, "GLenum", internalformat, "GLsizei", width, "GLsizei", height)
+TRACE_GL_VOID(glRenderbufferStorageOES, (GLenum target, GLenum internalformat, GLsizei width, GLsizei height), (target, internalformat, width, height), 4, "GLenum", target, "GLenum", internalformat, "GLsizei", width, "GLsizei", height)
+TRACE_GL_VOID(glRotatef, (GLfloat angle, GLfloat x, GLfloat y, GLfloat z), (angle, x, y, z), 4, "GLfloat", angle, "GLfloat", x, "GLfloat", y, "GLfloat", z)
+TRACE_GL_VOID(glRotatex, (GLfixed angle, GLfixed x, GLfixed y, GLfixed z), (angle, x, y, z), 4, "GLfixed", angle, "GLfixed", x, "GLfixed", y, "GLfixed", z)
+TRACE_GL_VOID(glRotatexOES, (GLfixed angle, GLfixed x, GLfixed y, GLfixed z), (angle, x, y, z), 4, "GLfixed", angle, "GLfixed", x, "GLfixed", y, "GLfixed", z)
+TRACE_GL_VOID(glSampleCoveragex, (GLclampx value, GLboolean invert), (value, invert), 2, "GLclampx", value, "GLboolean", invert)
+TRACE_GL_VOID(glSampleCoveragexOES, (GLclampx value, GLboolean invert), (value, invert), 2, "GLclampx", value, "GLboolean", invert)
+TRACE_GL_VOID(glScalef, (GLfloat x, GLfloat y, GLfloat z), (x, y, z), 3, "GLfloat", x, "GLfloat", y, "GLfloat", z)
+TRACE_GL_VOID(glScalex, (GLfixed x, GLfixed y, GLfixed z), (x, y, z), 3, "GLfixed", x, "GLfixed", y, "GLfixed", z)
+TRACE_GL_VOID(glScalexOES, (GLfixed x, GLfixed y, GLfixed z), (x, y, z), 3, "GLfixed", x, "GLfixed", y, "GLfixed", z)
+TRACE_GL_VOID(glSelectPerfMonitorCountersAMD, (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList), (monitor, enable, group, numCounters, countersList), 5, "GLuint", monitor, "GLboolean", enable, "GLuint", group, "GLint", numCounters, "GLuint *", countersList)
+TRACE_GL_VOID(glSetFenceNV, (GLuint fence, GLenum condition), (fence, condition), 2, "GLuint", fence, "GLenum", condition)
+TRACE_GL_VOID(glShadeModel, (GLenum mode), (mode), 1, "GLenum", mode)
+TRACE_GL_VOID(glStartTilingQCOM, (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask), (x, y, width, height, preserveMask), 5, "GLuint", x, "GLuint", y, "GLuint", width, "GLuint", height, "GLbitfield", preserveMask)
+TRACE_GL(GLboolean, glTestFenceNV, (GLuint fence), (fence), 1, "GLuint", fence)
+TRACE_GL_VOID(glTexCoordPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer), (size, type, stride, pointer), 4, "GLint", size, "GLenum", type, "GLsizei", stride, "const GLvoid *", pointer)
+TRACE_GL_VOID(glTexEnvf, (GLenum target, GLenum pname, GLfloat param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLfloat", param)
+TRACE_GL_VOID(glTexEnvfv, (GLenum target, GLenum pname, const GLfloat *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLfloat *", params)
+TRACE_GL_VOID(glTexEnvi, (GLenum target, GLenum pname, GLint param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLint", param)
+TRACE_GL_VOID(glTexEnviv, (GLenum target, GLenum pname, const GLint *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLint *", params)
+TRACE_GL_VOID(glTexEnvx, (GLenum target, GLenum pname, GLfixed param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glTexEnvxOES, (GLenum target, GLenum pname, GLfixed param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glTexEnvxv, (GLenum target, GLenum pname, const GLfixed *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glTexEnvxvOES, (GLenum target, GLenum pname, const GLfixed *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glTexGenfOES, (GLenum coord, GLenum pname, GLfloat param), (coord, pname, param), 3, "GLenum", coord, "GLenum", pname, "GLfloat", param)
+TRACE_GL_VOID(glTexGenfvOES, (GLenum coord, GLenum pname, const GLfloat *params), (coord, pname, params), 3, "GLenum", coord, "GLenum", pname, "const GLfloat *", params)
+TRACE_GL_VOID(glTexGeniOES, (GLenum coord, GLenum pname, GLint param), (coord, pname, param), 3, "GLenum", coord, "GLenum", pname, "GLint", param)
+TRACE_GL_VOID(glTexGenivOES, (GLenum coord, GLenum pname, const GLint *params), (coord, pname, params), 3, "GLenum", coord, "GLenum", pname, "const GLint *", params)
+TRACE_GL_VOID(glTexGenxOES, (GLenum coord, GLenum pname, GLfixed param), (coord, pname, param), 3, "GLenum", coord, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glTexGenxvOES, (GLenum coord, GLenum pname, const GLfixed *params), (coord, pname, params), 3, "GLenum", coord, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glTexImage3DOES, (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels), (target, level, internalformat, width, height, depth, border, format, type, pixels), 10, "GLenum", target, "GLint", level, "GLenum", internalformat, "GLsizei", width, "GLsizei", height, "GLsizei", depth, "GLint", border, "GLenum", format, "GLenum", type, "const GLvoid*", pixels)
+TRACE_GL_VOID(glTexParameterx, (GLenum target, GLenum pname, GLfixed param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glTexParameterxOES, (GLenum target, GLenum pname, GLfixed param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glTexParameterxv, (GLenum target, GLenum pname, const GLfixed *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glTexParameterxvOES, (GLenum target, GLenum pname, const GLfixed *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glTexSubImage3DOES, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels), (target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels), 11, "GLenum", target, "GLint", level, "GLint", xoffset, "GLint", yoffset, "GLint", zoffset, "GLsizei", width, "GLsizei", height, "GLsizei", depth, "GLenum", format, "GLenum", type, "const GLvoid*", pixels)
+TRACE_GL_VOID(glTranslatef, (GLfloat x, GLfloat y, GLfloat z), (x, y, z), 3, "GLfloat", x, "GLfloat", y, "GLfloat", z)
+TRACE_GL_VOID(glTranslatex, (GLfixed x, GLfixed y, GLfixed z), (x, y, z), 3, "GLfixed", x, "GLfixed", y, "GLfixed", z)
+TRACE_GL_VOID(glTranslatexOES, (GLfixed x, GLfixed y, GLfixed z), (x, y, z), 3, "GLfixed", x, "GLfixed", y, "GLfixed", z)
+TRACE_GL(GLboolean, glUnmapBufferOES, (GLenum target), (target), 1, "GLenum", target)
+TRACE_GL_VOID(glVertexPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer), (size, type, stride, pointer), 4, "GLint", size, "GLenum", type, "GLsizei", stride, "const GLvoid *", pointer)
+TRACE_GL_VOID(glWeightPointerOES, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer), (size, type, stride, pointer), 4, "GLint", size, "GLenum", type, "GLsizei", stride, "const GLvoid *", pointer)
diff --git a/opengl/libs/glesv2dbg.h b/opengl/libs/glesv2dbg.h
new file mode 100644
index 0000000..b988eb7
--- /dev/null
+++ b/opengl/libs/glesv2dbg.h
@@ -0,0 +1,32 @@
+/*
+ ** Copyright 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.
+ */
+
+#ifndef _GLESV2_DBG_H_
+#define _GLESV2_DBG_H_
+
+namespace android
+{
+ struct DbgContext;
+
+ DbgContext * CreateDbgContext(const unsigned version, const gl_hooks_t * const hooks);
+ void DestroyDbgContext(DbgContext * const dbg);
+
+ void StartDebugServer(); // create and bind socket if haven't already
+ void StopDebugServer(); // close socket if open
+
+}; // namespace android
+
+#endif // #ifndef _GLESV2_DBG_H_
diff --git a/opengl/libs/glesv2dbg_functions.h b/opengl/libs/glesv2dbg_functions.h
new file mode 100644
index 0000000..2d70032
--- /dev/null
+++ b/opengl/libs/glesv2dbg_functions.h
@@ -0,0 +1,381 @@
+extern "C"
+{
+GL_ENTRY(void, glActiveTexture, GLenum texture)
+GL_ENTRY(void, glAlphaFunc, GLenum func, GLclampf ref)
+GL_ENTRY(void, glAlphaFuncx, GLenum func, GLclampx ref)
+GL_ENTRY(void, glAlphaFuncxOES, GLenum func, GLclampx ref)
+GL_ENTRY(void, glAttachShader, GLuint program, GLuint shader)
+GL_ENTRY(void, glBeginPerfMonitorAMD, GLuint monitor)
+GL_ENTRY(void, glBindAttribLocation, GLuint program, GLuint index, const GLchar* name)
+GL_ENTRY(void, glBindBuffer, GLenum target, GLuint buffer)
+GL_ENTRY(void, glBindFramebuffer, GLenum target, GLuint framebuffer)
+GL_ENTRY(void, glBindFramebufferOES, GLenum target, GLuint framebuffer)
+GL_ENTRY(void, glBindRenderbuffer, GLenum target, GLuint renderbuffer)
+GL_ENTRY(void, glBindRenderbufferOES, GLenum target, GLuint renderbuffer)
+GL_ENTRY(void, glBindTexture, GLenum target, GLuint texture)
+GL_ENTRY(void, glBindVertexArrayOES, GLuint array)
+GL_ENTRY(void, glBlendColor, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+GL_ENTRY(void, glBlendEquation, GLenum mode )
+GL_ENTRY(void, glBlendEquationOES, GLenum mode)
+GL_ENTRY(void, glBlendEquationSeparate, GLenum modeRGB, GLenum modeAlpha)
+GL_ENTRY(void, glBlendEquationSeparateOES, GLenum modeRGB, GLenum modeAlpha)
+GL_ENTRY(void, glBlendFunc, GLenum sfactor, GLenum dfactor)
+GL_ENTRY(void, glBlendFuncSeparate, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+GL_ENTRY(void, glBlendFuncSeparateOES, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+GL_ENTRY(void, glBufferData, GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
+GL_ENTRY(void, glBufferSubData, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
+GL_ENTRY(GLenum, glCheckFramebufferStatus, GLenum target)
+GL_ENTRY(GLenum, glCheckFramebufferStatusOES, GLenum target)
+GL_ENTRY(void, glClear, GLbitfield mask)
+GL_ENTRY(void, glClearColor, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+GL_ENTRY(void, glClearColorx, GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)
+GL_ENTRY(void, glClearColorxOES, GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)
+GL_ENTRY(void, glClearDepthf, GLclampf depth)
+GL_ENTRY(void, glClearDepthfOES, GLclampf depth)
+GL_ENTRY(void, glClearDepthx, GLclampx depth)
+GL_ENTRY(void, glClearDepthxOES, GLclampx depth)
+GL_ENTRY(void, glClearStencil, GLint s)
+GL_ENTRY(void, glClientActiveTexture, GLenum texture)
+GL_ENTRY(void, glClipPlanef, GLenum plane, const GLfloat *equation)
+GL_ENTRY(void, glClipPlanefIMG, GLenum p, const GLfloat *eqn)
+GL_ENTRY(void, glClipPlanefOES, GLenum plane, const GLfloat *equation)
+GL_ENTRY(void, glClipPlanex, GLenum plane, const GLfixed *equation)
+GL_ENTRY(void, glClipPlanexIMG, GLenum p, const GLfixed *eqn)
+GL_ENTRY(void, glClipPlanexOES, GLenum plane, const GLfixed *equation)
+GL_ENTRY(void, glColor4f, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+GL_ENTRY(void, glColor4ub, GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
+GL_ENTRY(void, glColor4x, GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
+GL_ENTRY(void, glColor4xOES, GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
+GL_ENTRY(void, glColorMask, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+GL_ENTRY(void, glColorPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+GL_ENTRY(void, glCompileShader, GLuint shader)
+GL_ENTRY(void, glCompressedTexImage2D, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data)
+GL_ENTRY(void, glCompressedTexImage3DOES, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data)
+GL_ENTRY(void, glCompressedTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data)
+GL_ENTRY(void, glCompressedTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data)
+GL_ENTRY(void, glCopyTexImage2D, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+GL_ENTRY(void, glCopyTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+GL_ENTRY(void, glCopyTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+GL_ENTRY(void, glCoverageMaskNV, GLboolean mask)
+GL_ENTRY(void, glCoverageOperationNV, GLenum operation)
+GL_ENTRY(GLuint, glCreateProgram, void)
+GL_ENTRY(GLuint, glCreateShader, GLenum type)
+GL_ENTRY(void, glCullFace, GLenum mode)
+GL_ENTRY(void, glCurrentPaletteMatrixOES, GLuint matrixpaletteindex)
+GL_ENTRY(void, glDeleteBuffers, GLsizei n, const GLuint *buffers)
+GL_ENTRY(void, glDeleteFencesNV, GLsizei n, const GLuint *fences)
+GL_ENTRY(void, glDeleteFramebuffers, GLsizei n, const GLuint* framebuffers)
+GL_ENTRY(void, glDeleteFramebuffersOES, GLsizei n, const GLuint* framebuffers)
+GL_ENTRY(void, glDeletePerfMonitorsAMD, GLsizei n, GLuint *monitors)
+GL_ENTRY(void, glDeleteProgram, GLuint program)
+GL_ENTRY(void, glDeleteRenderbuffers, GLsizei n, const GLuint* renderbuffers)
+GL_ENTRY(void, glDeleteRenderbuffersOES, GLsizei n, const GLuint* renderbuffers)
+GL_ENTRY(void, glDeleteShader, GLuint shader)
+GL_ENTRY(void, glDeleteTextures, GLsizei n, const GLuint *textures)
+GL_ENTRY(void, glDeleteVertexArraysOES, GLsizei n, const GLuint *arrays)
+GL_ENTRY(void, glDepthFunc, GLenum func)
+GL_ENTRY(void, glDepthMask, GLboolean flag)
+GL_ENTRY(void, glDepthRangef, GLclampf zNear, GLclampf zFar)
+GL_ENTRY(void, glDepthRangefOES, GLclampf zNear, GLclampf zFar)
+GL_ENTRY(void, glDepthRangex, GLclampx zNear, GLclampx zFar)
+GL_ENTRY(void, glDepthRangexOES, GLclampx zNear, GLclampx zFar)
+GL_ENTRY(void, glDetachShader, GLuint program, GLuint shader)
+GL_ENTRY(void, glDisable, GLenum cap)
+GL_ENTRY(void, glDisableClientState, GLenum array)
+GL_ENTRY(void, glDisableDriverControlQCOM, GLuint driverControl)
+GL_ENTRY(void, glDisableVertexAttribArray, GLuint index)
+GL_ENTRY(void, glDiscardFramebufferEXT, GLenum target, GLsizei numAttachments, const GLenum *attachments)
+GL_ENTRY(void, glDrawArrays, GLenum mode, GLint first, GLsizei count)
+GL_ENTRY(void, glDrawElements, GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
+GL_ENTRY(void, glDrawTexfOES, GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
+GL_ENTRY(void, glDrawTexfvOES, const GLfloat *coords)
+GL_ENTRY(void, glDrawTexiOES, GLint x, GLint y, GLint z, GLint width, GLint height)
+GL_ENTRY(void, glDrawTexivOES, const GLint *coords)
+GL_ENTRY(void, glDrawTexsOES, GLshort x, GLshort y, GLshort z, GLshort width, GLshort height)
+GL_ENTRY(void, glDrawTexsvOES, const GLshort *coords)
+GL_ENTRY(void, glDrawTexxOES, GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height)
+GL_ENTRY(void, glDrawTexxvOES, const GLfixed *coords)
+GL_ENTRY(void, glEGLImageTargetRenderbufferStorageOES, GLenum target, GLeglImageOES image)
+GL_ENTRY(void, glEGLImageTargetTexture2DOES, GLenum target, GLeglImageOES image)
+GL_ENTRY(void, glEnable, GLenum cap)
+GL_ENTRY(void, glEnableClientState, GLenum array)
+GL_ENTRY(void, glEnableDriverControlQCOM, GLuint driverControl)
+GL_ENTRY(void, glEnableVertexAttribArray, GLuint index)
+GL_ENTRY(void, glEndPerfMonitorAMD, GLuint monitor)
+GL_ENTRY(void, glEndTilingQCOM, GLbitfield preserveMask)
+GL_ENTRY(void, glExtGetBufferPointervQCOM, GLenum target, GLvoid **params)
+GL_ENTRY(void, glExtGetBuffersQCOM, GLuint *buffers, GLint maxBuffers, GLint *numBuffers)
+GL_ENTRY(void, glExtGetFramebuffersQCOM, GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers)
+GL_ENTRY(void, glExtGetProgramBinarySourceQCOM, GLuint program, GLenum shadertype, GLchar *source, GLint *length)
+GL_ENTRY(void, glExtGetProgramsQCOM, GLuint *programs, GLint maxPrograms, GLint *numPrograms)
+GL_ENTRY(void, glExtGetRenderbuffersQCOM, GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers)
+GL_ENTRY(void, glExtGetShadersQCOM, GLuint *shaders, GLint maxShaders, GLint *numShaders)
+GL_ENTRY(void, glExtGetTexLevelParameterivQCOM, GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params)
+GL_ENTRY(void, glExtGetTexSubImageQCOM, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels)
+GL_ENTRY(void, glExtGetTexturesQCOM, GLuint *textures, GLint maxTextures, GLint *numTextures)
+GL_ENTRY(GLboolean, glExtIsProgramBinaryQCOM, GLuint program)
+GL_ENTRY(void, glExtTexObjectStateOverrideiQCOM, GLenum target, GLenum pname, GLint param)
+GL_ENTRY(void, glFinish, void)
+GL_ENTRY(void, glFinishFenceNV, GLuint fence)
+GL_ENTRY(void, glFlush, void)
+GL_ENTRY(void, glFogf, GLenum pname, GLfloat param)
+GL_ENTRY(void, glFogfv, GLenum pname, const GLfloat *params)
+GL_ENTRY(void, glFogx, GLenum pname, GLfixed param)
+GL_ENTRY(void, glFogxOES, GLenum pname, GLfixed param)
+GL_ENTRY(void, glFogxv, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glFogxvOES, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glFramebufferRenderbuffer, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+GL_ENTRY(void, glFramebufferRenderbufferOES, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+GL_ENTRY(void, glFramebufferTexture2D, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+GL_ENTRY(void, glFramebufferTexture2DMultisampleIMG, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples)
+GL_ENTRY(void, glFramebufferTexture2DOES, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+GL_ENTRY(void, glFramebufferTexture3DOES, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
+GL_ENTRY(void, glFrontFace, GLenum mode)
+GL_ENTRY(void, glFrustumf, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+GL_ENTRY(void, glFrustumfOES, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+GL_ENTRY(void, glFrustumx, GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+GL_ENTRY(void, glFrustumxOES, GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+GL_ENTRY(void, glGenBuffers, GLsizei n, GLuint *buffers)
+GL_ENTRY(void, glGenFencesNV, GLsizei n, GLuint *fences)
+GL_ENTRY(void, glGenFramebuffers, GLsizei n, GLuint* framebuffers)
+GL_ENTRY(void, glGenFramebuffersOES, GLsizei n, GLuint* framebuffers)
+GL_ENTRY(void, glGenPerfMonitorsAMD, GLsizei n, GLuint *monitors)
+GL_ENTRY(void, glGenRenderbuffers, GLsizei n, GLuint* renderbuffers)
+GL_ENTRY(void, glGenRenderbuffersOES, GLsizei n, GLuint* renderbuffers)
+GL_ENTRY(void, glGenTextures, GLsizei n, GLuint *textures)
+GL_ENTRY(void, glGenVertexArraysOES, GLsizei n, GLuint *arrays)
+GL_ENTRY(void, glGenerateMipmap, GLenum target)
+GL_ENTRY(void, glGenerateMipmapOES, GLenum target)
+GL_ENTRY(void, glGetActiveAttrib, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
+GL_ENTRY(void, glGetActiveUniform, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
+GL_ENTRY(void, glGetAttachedShaders, GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
+GL_ENTRY(int, glGetAttribLocation, GLuint program, const GLchar* name)
+GL_ENTRY(void, glGetBooleanv, GLenum pname, GLboolean *params)
+GL_ENTRY(void, glGetBufferParameteriv, GLenum target, GLenum pname, GLint *params)
+GL_ENTRY(void, glGetBufferPointervOES, GLenum target, GLenum pname, GLvoid ** params)
+GL_ENTRY(void, glGetClipPlanef, GLenum pname, GLfloat eqn[4])
+GL_ENTRY(void, glGetClipPlanefOES, GLenum pname, GLfloat eqn[4])
+GL_ENTRY(void, glGetClipPlanex, GLenum pname, GLfixed eqn[4])
+GL_ENTRY(void, glGetClipPlanexOES, GLenum pname, GLfixed eqn[4])
+GL_ENTRY(void, glGetDriverControlStringQCOM, GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString)
+GL_ENTRY(void, glGetDriverControlsQCOM, GLint *num, GLsizei size, GLuint *driverControls)
+GL_ENTRY(GLenum, glGetError, void)
+GL_ENTRY(void, glGetFenceivNV, GLuint fence, GLenum pname, GLint *params)
+GL_ENTRY(void, glGetFixedv, GLenum pname, GLfixed *params)
+GL_ENTRY(void, glGetFixedvOES, GLenum pname, GLfixed *params)
+GL_ENTRY(void, glGetFloatv, GLenum pname, GLfloat *params)
+GL_ENTRY(void, glGetFramebufferAttachmentParameteriv, GLenum target, GLenum attachment, GLenum pname, GLint* params)
+GL_ENTRY(void, glGetFramebufferAttachmentParameterivOES, GLenum target, GLenum attachment, GLenum pname, GLint* params)
+GL_ENTRY(void, glGetIntegerv, GLenum pname, GLint *params)
+GL_ENTRY(void, glGetLightfv, GLenum light, GLenum pname, GLfloat *params)
+GL_ENTRY(void, glGetLightxv, GLenum light, GLenum pname, GLfixed *params)
+GL_ENTRY(void, glGetLightxvOES, GLenum light, GLenum pname, GLfixed *params)
+GL_ENTRY(void, glGetMaterialfv, GLenum face, GLenum pname, GLfloat *params)
+GL_ENTRY(void, glGetMaterialxv, GLenum face, GLenum pname, GLfixed *params)
+GL_ENTRY(void, glGetMaterialxvOES, GLenum face, GLenum pname, GLfixed *params)
+GL_ENTRY(void, glGetPerfMonitorCounterDataAMD, GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten)
+GL_ENTRY(void, glGetPerfMonitorCounterInfoAMD, GLuint group, GLuint counter, GLenum pname, GLvoid *data)
+GL_ENTRY(void, glGetPerfMonitorCounterStringAMD, GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString)
+GL_ENTRY(void, glGetPerfMonitorCountersAMD, GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters)
+GL_ENTRY(void, glGetPerfMonitorGroupStringAMD, GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString)
+GL_ENTRY(void, glGetPerfMonitorGroupsAMD, GLint *numGroups, GLsizei groupsSize, GLuint *groups)
+GL_ENTRY(void, glGetPointerv, GLenum pname, GLvoid **params)
+GL_ENTRY(void, glGetProgramBinaryOES, GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary)
+GL_ENTRY(void, glGetProgramInfoLog, GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
+GL_ENTRY(void, glGetProgramiv, GLuint program, GLenum pname, GLint* params)
+GL_ENTRY(void, glGetRenderbufferParameteriv, GLenum target, GLenum pname, GLint* params)
+GL_ENTRY(void, glGetRenderbufferParameterivOES, GLenum target, GLenum pname, GLint* params)
+GL_ENTRY(void, glGetShaderInfoLog, GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
+GL_ENTRY(void, glGetShaderPrecisionFormat, GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
+GL_ENTRY(void, glGetShaderSource, GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
+GL_ENTRY(void, glGetShaderiv, GLuint shader, GLenum pname, GLint* params)
+GL_ENTRY(const GLubyte *, glGetString, GLenum name)
+GL_ENTRY(void, glGetTexEnvfv, GLenum env, GLenum pname, GLfloat *params)
+GL_ENTRY(void, glGetTexEnviv, GLenum env, GLenum pname, GLint *params)
+GL_ENTRY(void, glGetTexEnvxv, GLenum env, GLenum pname, GLfixed *params)
+GL_ENTRY(void, glGetTexEnvxvOES, GLenum env, GLenum pname, GLfixed *params)
+GL_ENTRY(void, glGetTexGenfvOES, GLenum coord, GLenum pname, GLfloat *params)
+GL_ENTRY(void, glGetTexGenivOES, GLenum coord, GLenum pname, GLint *params)
+GL_ENTRY(void, glGetTexGenxvOES, GLenum coord, GLenum pname, GLfixed *params)
+GL_ENTRY(void, glGetTexParameterfv, GLenum target, GLenum pname, GLfloat *params)
+GL_ENTRY(void, glGetTexParameteriv, GLenum target, GLenum pname, GLint *params)
+GL_ENTRY(void, glGetTexParameterxv, GLenum target, GLenum pname, GLfixed *params)
+GL_ENTRY(void, glGetTexParameterxvOES, GLenum target, GLenum pname, GLfixed *params)
+GL_ENTRY(int, glGetUniformLocation, GLuint program, const GLchar* name)
+GL_ENTRY(void, glGetUniformfv, GLuint program, GLint location, GLfloat* params)
+GL_ENTRY(void, glGetUniformiv, GLuint program, GLint location, GLint* params)
+GL_ENTRY(void, glGetVertexAttribPointerv, GLuint index, GLenum pname, GLvoid** pointer)
+GL_ENTRY(void, glGetVertexAttribfv, GLuint index, GLenum pname, GLfloat* params)
+GL_ENTRY(void, glGetVertexAttribiv, GLuint index, GLenum pname, GLint* params)
+GL_ENTRY(void, glHint, GLenum target, GLenum mode)
+GL_ENTRY(GLboolean, glIsBuffer, GLuint buffer)
+GL_ENTRY(GLboolean, glIsEnabled, GLenum cap)
+GL_ENTRY(GLboolean, glIsFenceNV, GLuint fence)
+GL_ENTRY(GLboolean, glIsFramebuffer, GLuint framebuffer)
+GL_ENTRY(GLboolean, glIsFramebufferOES, GLuint framebuffer)
+GL_ENTRY(GLboolean, glIsProgram, GLuint program)
+GL_ENTRY(GLboolean, glIsRenderbuffer, GLuint renderbuffer)
+GL_ENTRY(GLboolean, glIsRenderbufferOES, GLuint renderbuffer)
+GL_ENTRY(GLboolean, glIsShader, GLuint shader)
+GL_ENTRY(GLboolean, glIsTexture, GLuint texture)
+GL_ENTRY(GLboolean, glIsVertexArrayOES, GLuint array)
+GL_ENTRY(void, glLightModelf, GLenum pname, GLfloat param)
+GL_ENTRY(void, glLightModelfv, GLenum pname, const GLfloat *params)
+GL_ENTRY(void, glLightModelx, GLenum pname, GLfixed param)
+GL_ENTRY(void, glLightModelxOES, GLenum pname, GLfixed param)
+GL_ENTRY(void, glLightModelxv, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glLightModelxvOES, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glLightf, GLenum light, GLenum pname, GLfloat param)
+GL_ENTRY(void, glLightfv, GLenum light, GLenum pname, const GLfloat *params)
+GL_ENTRY(void, glLightx, GLenum light, GLenum pname, GLfixed param)
+GL_ENTRY(void, glLightxOES, GLenum light, GLenum pname, GLfixed param)
+GL_ENTRY(void, glLightxv, GLenum light, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glLightxvOES, GLenum light, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glLineWidth, GLfloat width)
+GL_ENTRY(void, glLineWidthx, GLfixed width)
+GL_ENTRY(void, glLineWidthxOES, GLfixed width)
+GL_ENTRY(void, glLinkProgram, GLuint program)
+GL_ENTRY(void, glLoadIdentity, void)
+GL_ENTRY(void, glLoadMatrixf, const GLfloat *m)
+GL_ENTRY(void, glLoadMatrixx, const GLfixed *m)
+GL_ENTRY(void, glLoadMatrixxOES, const GLfixed *m)
+GL_ENTRY(void, glLoadPaletteFromModelViewMatrixOES, void)
+GL_ENTRY(void, glLogicOp, GLenum opcode)
+GL_ENTRY(void*, glMapBufferOES, GLenum target, GLenum access)
+GL_ENTRY(void, glMaterialf, GLenum face, GLenum pname, GLfloat param)
+GL_ENTRY(void, glMaterialfv, GLenum face, GLenum pname, const GLfloat *params)
+GL_ENTRY(void, glMaterialx, GLenum face, GLenum pname, GLfixed param)
+GL_ENTRY(void, glMaterialxOES, GLenum face, GLenum pname, GLfixed param)
+GL_ENTRY(void, glMaterialxv, GLenum face, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glMaterialxvOES, GLenum face, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glMatrixIndexPointerOES, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+GL_ENTRY(void, glMatrixMode, GLenum mode)
+GL_ENTRY(void, glMultMatrixf, const GLfloat *m)
+GL_ENTRY(void, glMultMatrixx, const GLfixed *m)
+GL_ENTRY(void, glMultMatrixxOES, const GLfixed *m)
+GL_ENTRY(void, glMultiDrawArraysEXT, GLenum mode, GLint *first, GLsizei *count, GLsizei primcount)
+GL_ENTRY(void, glMultiDrawElementsEXT, GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount)
+GL_ENTRY(void, glMultiTexCoord4f, GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
+GL_ENTRY(void, glMultiTexCoord4x, GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
+GL_ENTRY(void, glMultiTexCoord4xOES, GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
+GL_ENTRY(void, glNormal3f, GLfloat nx, GLfloat ny, GLfloat nz)
+GL_ENTRY(void, glNormal3x, GLfixed nx, GLfixed ny, GLfixed nz)
+GL_ENTRY(void, glNormal3xOES, GLfixed nx, GLfixed ny, GLfixed nz)
+GL_ENTRY(void, glNormalPointer, GLenum type, GLsizei stride, const GLvoid *pointer)
+GL_ENTRY(void, glOrthof, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+GL_ENTRY(void, glOrthofOES, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+GL_ENTRY(void, glOrthox, GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+GL_ENTRY(void, glOrthoxOES, GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+GL_ENTRY(void, glPixelStorei, GLenum pname, GLint param)
+GL_ENTRY(void, glPointParameterf, GLenum pname, GLfloat param)
+GL_ENTRY(void, glPointParameterfv, GLenum pname, const GLfloat *params)
+GL_ENTRY(void, glPointParameterx, GLenum pname, GLfixed param)
+GL_ENTRY(void, glPointParameterxOES, GLenum pname, GLfixed param)
+GL_ENTRY(void, glPointParameterxv, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glPointParameterxvOES, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glPointSize, GLfloat size)
+GL_ENTRY(void, glPointSizePointerOES, GLenum type, GLsizei stride, const GLvoid *pointer)
+GL_ENTRY(void, glPointSizex, GLfixed size)
+GL_ENTRY(void, glPointSizexOES, GLfixed size)
+GL_ENTRY(void, glPolygonOffset, GLfloat factor, GLfloat units)
+GL_ENTRY(void, glPolygonOffsetx, GLfixed factor, GLfixed units)
+GL_ENTRY(void, glPolygonOffsetxOES, GLfixed factor, GLfixed units)
+GL_ENTRY(void, glPopMatrix, void)
+GL_ENTRY(void, glProgramBinaryOES, GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length)
+GL_ENTRY(void, glPushMatrix, void)
+GL_ENTRY(GLbitfield, glQueryMatrixxOES, GLfixed mantissa[16], GLint exponent[16])
+GL_ENTRY(void, glReadPixels, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)
+GL_ENTRY(void, glReleaseShaderCompiler, void)
+GL_ENTRY(void, glRenderbufferStorage, GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+GL_ENTRY(void, glRenderbufferStorageMultisampleIMG, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
+GL_ENTRY(void, glRenderbufferStorageOES, GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+GL_ENTRY(void, glRotatef, GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
+GL_ENTRY(void, glRotatex, GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
+GL_ENTRY(void, glRotatexOES, GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
+GL_ENTRY(void, glSampleCoverage, GLclampf value, GLboolean invert)
+GL_ENTRY(void, glSampleCoveragex, GLclampx value, GLboolean invert)
+GL_ENTRY(void, glSampleCoveragexOES, GLclampx value, GLboolean invert)
+GL_ENTRY(void, glScalef, GLfloat x, GLfloat y, GLfloat z)
+GL_ENTRY(void, glScalex, GLfixed x, GLfixed y, GLfixed z)
+GL_ENTRY(void, glScalexOES, GLfixed x, GLfixed y, GLfixed z)
+GL_ENTRY(void, glScissor, GLint x, GLint y, GLsizei width, GLsizei height)
+GL_ENTRY(void, glSelectPerfMonitorCountersAMD, GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList)
+GL_ENTRY(void, glSetFenceNV, GLuint fence, GLenum condition)
+GL_ENTRY(void, glShadeModel, GLenum mode)
+GL_ENTRY(void, glShaderBinary, GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
+GL_ENTRY(void, glShaderSource, GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
+GL_ENTRY(void, glStartTilingQCOM, GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask)
+GL_ENTRY(void, glStencilFunc, GLenum func, GLint ref, GLuint mask)
+GL_ENTRY(void, glStencilFuncSeparate, GLenum face, GLenum func, GLint ref, GLuint mask)
+GL_ENTRY(void, glStencilMask, GLuint mask)
+GL_ENTRY(void, glStencilMaskSeparate, GLenum face, GLuint mask)
+GL_ENTRY(void, glStencilOp, GLenum fail, GLenum zfail, GLenum zpass)
+GL_ENTRY(void, glStencilOpSeparate, GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+GL_ENTRY(GLboolean, glTestFenceNV, GLuint fence)
+GL_ENTRY(void, glTexCoordPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+GL_ENTRY(void, glTexEnvf, GLenum target, GLenum pname, GLfloat param)
+GL_ENTRY(void, glTexEnvfv, GLenum target, GLenum pname, const GLfloat *params)
+GL_ENTRY(void, glTexEnvi, GLenum target, GLenum pname, GLint param)
+GL_ENTRY(void, glTexEnviv, GLenum target, GLenum pname, const GLint *params)
+GL_ENTRY(void, glTexEnvx, GLenum target, GLenum pname, GLfixed param)
+GL_ENTRY(void, glTexEnvxOES, GLenum target, GLenum pname, GLfixed param)
+GL_ENTRY(void, glTexEnvxv, GLenum target, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glTexEnvxvOES, GLenum target, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glTexGenfOES, GLenum coord, GLenum pname, GLfloat param)
+GL_ENTRY(void, glTexGenfvOES, GLenum coord, GLenum pname, const GLfloat *params)
+GL_ENTRY(void, glTexGeniOES, GLenum coord, GLenum pname, GLint param)
+GL_ENTRY(void, glTexGenivOES, GLenum coord, GLenum pname, const GLint *params)
+GL_ENTRY(void, glTexGenxOES, GLenum coord, GLenum pname, GLfixed param)
+GL_ENTRY(void, glTexGenxvOES, GLenum coord, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glTexImage2D, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+GL_ENTRY(void, glTexImage3DOES, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
+GL_ENTRY(void, glTexParameterf, GLenum target, GLenum pname, GLfloat param)
+GL_ENTRY(void, glTexParameterfv, GLenum target, GLenum pname, const GLfloat *params)
+GL_ENTRY(void, glTexParameteri, GLenum target, GLenum pname, GLint param)
+GL_ENTRY(void, glTexParameteriv, GLenum target, GLenum pname, const GLint *params)
+GL_ENTRY(void, glTexParameterx, GLenum target, GLenum pname, GLfixed param)
+GL_ENTRY(void, glTexParameterxOES, GLenum target, GLenum pname, GLfixed param)
+GL_ENTRY(void, glTexParameterxv, GLenum target, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glTexParameterxvOES, GLenum target, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
+GL_ENTRY(void, glTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels)
+GL_ENTRY(void, glTranslatef, GLfloat x, GLfloat y, GLfloat z)
+GL_ENTRY(void, glTranslatex, GLfixed x, GLfixed y, GLfixed z)
+GL_ENTRY(void, glTranslatexOES, GLfixed x, GLfixed y, GLfixed z)
+GL_ENTRY(void, glUniform1f, GLint location, GLfloat x)
+GL_ENTRY(void, glUniform1fv, GLint location, GLsizei count, const GLfloat* v)
+GL_ENTRY(void, glUniform1i, GLint location, GLint x)
+GL_ENTRY(void, glUniform1iv, GLint location, GLsizei count, const GLint* v)
+GL_ENTRY(void, glUniform2f, GLint location, GLfloat x, GLfloat y)
+GL_ENTRY(void, glUniform2fv, GLint location, GLsizei count, const GLfloat* v)
+GL_ENTRY(void, glUniform2i, GLint location, GLint x, GLint y)
+GL_ENTRY(void, glUniform2iv, GLint location, GLsizei count, const GLint* v)
+GL_ENTRY(void, glUniform3f, GLint location, GLfloat x, GLfloat y, GLfloat z)
+GL_ENTRY(void, glUniform3fv, GLint location, GLsizei count, const GLfloat* v)
+GL_ENTRY(void, glUniform3i, GLint location, GLint x, GLint y, GLint z)
+GL_ENTRY(void, glUniform3iv, GLint location, GLsizei count, const GLint* v)
+GL_ENTRY(void, glUniform4f, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+GL_ENTRY(void, glUniform4fv, GLint location, GLsizei count, const GLfloat* v)
+GL_ENTRY(void, glUniform4i, GLint location, GLint x, GLint y, GLint z, GLint w)
+GL_ENTRY(void, glUniform4iv, GLint location, GLsizei count, const GLint* v)
+GL_ENTRY(void, glUniformMatrix2fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+GL_ENTRY(void, glUniformMatrix3fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+GL_ENTRY(void, glUniformMatrix4fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+GL_ENTRY(GLboolean, glUnmapBufferOES, GLenum target)
+GL_ENTRY(void, glUseProgram, GLuint program)
+GL_ENTRY(void, glValidateProgram, GLuint program)
+GL_ENTRY(void, glVertexAttrib1f, GLuint indx, GLfloat x)
+GL_ENTRY(void, glVertexAttrib1fv, GLuint indx, const GLfloat* values)
+GL_ENTRY(void, glVertexAttrib2f, GLuint indx, GLfloat x, GLfloat y)
+GL_ENTRY(void, glVertexAttrib2fv, GLuint indx, const GLfloat* values)
+GL_ENTRY(void, glVertexAttrib3f, GLuint indx, GLfloat x, GLfloat y, GLfloat z)
+GL_ENTRY(void, glVertexAttrib3fv, GLuint indx, const GLfloat* values)
+GL_ENTRY(void, glVertexAttrib4f, GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+GL_ENTRY(void, glVertexAttrib4fv, GLuint indx, const GLfloat* values)
+GL_ENTRY(void, glVertexAttribPointer, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
+GL_ENTRY(void, glVertexPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+GL_ENTRY(void, glViewport, GLint x, GLint y, GLsizei width, GLsizei height)
+GL_ENTRY(void, glWeightPointerOES, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+
+
+}
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index d3d1750..bbe146d6 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -8,6 +8,7 @@
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.GET_TASKS" />
+ <uses-permission android:name="android.permission.MANAGE_USB" />
<application
android:persistent="true"
@@ -39,5 +40,40 @@
android:exported="true">
</activity>
+ <!-- started from UsbDeviceSettingsManager -->
+ <activity android:name=".usb.UsbConfirmActivity"
+ android:exported="true"
+ android:permission="android.permission.MANAGE_USB"
+ android:theme="@*android:style/Theme.Holo.Dialog.Alert"
+ android:finishOnCloseSystemDialogs="true"
+ android:excludeFromRecents="true">
+ </activity>
+
+ <!-- started from UsbDeviceSettingsManager -->
+ <activity android:name=".usb.UsbPermissionActivity"
+ android:exported="true"
+ android:permission="android.permission.MANAGE_USB"
+ android:theme="@*android:style/Theme.Holo.Dialog.Alert"
+ android:finishOnCloseSystemDialogs="true"
+ android:excludeFromRecents="true">
+ </activity>
+
+ <!-- started from UsbDeviceSettingsManager -->
+ <activity android:name=".usb.UsbResolverActivity"
+ android:exported="true"
+ android:permission="android.permission.MANAGE_USB"
+ android:theme="@*android:style/Theme.Holo.Dialog.Alert"
+ android:finishOnCloseSystemDialogs="true"
+ android:excludeFromRecents="true">
+ </activity>
+
+ <!-- started from UsbDeviceSettingsManager -->
+ <activity android:name=".usb.UsbAccessoryUriActivity"
+ android:exported="true"
+ android:permission="android.permission.MANAGE_USB"
+ android:theme="@*android:style/Theme.Holo.Dialog.Alert"
+ android:finishOnCloseSystemDialogs="true"
+ android:excludeFromRecents="true">
+ </activity>
</application>
</manifest>
diff --git a/packages/SystemUI/res/drawable-hdpi/notify_panel_clock_bg_pressed.9.png b/packages/SystemUI/res/drawable-hdpi/notify_panel_clock_bg_pressed.9.png
new file mode 100644
index 0000000..0c40c73
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/notify_panel_clock_bg_pressed.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_notify_alarm.png b/packages/SystemUI/res/drawable-hdpi/stat_notify_alarm.png
index 51b4f3f..4ec771a 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_notify_alarm.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_notify_alarm.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_notify_more.png b/packages/SystemUI/res/drawable-hdpi/stat_notify_more.png
index 170178c..2ea2609 100755
--- a/packages/SystemUI/res/drawable-hdpi/stat_notify_more.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_notify_more.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_gps_acquiring.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_gps_acquiring.png
index 61f65bf..765cdd7 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_gps_acquiring.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_gps_acquiring.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_0.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_0.png
index ff74c35..6ff0899 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_0.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1.png
index 6375b1b..6dcdefb 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1_fully.png
index ef886b8..5ee9e0a 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2.png
index 92882bd..a74e731 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2_fully.png
index cf5c4c3..441739a 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3.png
index 24b6d25..a666c75 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3_fully.png
index b147583..2045c0c 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4.png
index 594ad6a..063a86c 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4_fully.png
index 2879550..1e4aebb 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_flightmode.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_flightmode.png
index c763976..52e8a8e 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_flightmode.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_flightmode.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_in.png
index 883808a..c69c44f 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_in.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_inout.png
new file mode 100644
index 0000000..0413ae3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_out.png
index 8ea42c7..61e7772a 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_out.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_in.png
index 71429ae..74b018a 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_in.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_inout.png
index 5c34554..d3364bc 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_inout.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_out.png
index 44e7072..e65d6ed 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_out.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_0.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_0.png
index 7cd2893..f5b07e6 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_0.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_1.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_1.png
index 23eb1d6..fbb31b8 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_1.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_1_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_1_fully.png
index ad28667..c1f2f97 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_1_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_2.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_2.png
index 048dfd1..8721d5c 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_2.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_2_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_2_fully.png
index 224ae1f..b8feac6 100755
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_2_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_3.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_3.png
index b85859b..6854a2b 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_3.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_3_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_3_fully.png
index d7f3960..efff76c 100755
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_3_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_4.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_4.png
index 54915b9..3a5c7e2 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_4.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_4_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_4_fully.png
index bd44b52..dc1ce8e 100755
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_4_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_4_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/notify_panel_clock_bg_pressed.9.png b/packages/SystemUI/res/drawable-mdpi/notify_panel_clock_bg_pressed.9.png
index 4fc6b46..4fb1cf1 100644
--- a/packages/SystemUI/res/drawable-mdpi/notify_panel_clock_bg_pressed.9.png
+++ b/packages/SystemUI/res/drawable-mdpi/notify_panel_clock_bg_pressed.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_notify_alarm.png b/packages/SystemUI/res/drawable-mdpi/stat_notify_alarm.png
index d846afe..3a50987 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_notify_alarm.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_notify_alarm.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_notify_more.png b/packages/SystemUI/res/drawable-mdpi/stat_notify_more.png
index 9b28252..5bde4e5 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_notify_more.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_notify_more.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_gps_acquiring.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_gps_acquiring.png
index 3a0fce0..c9da7b9 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_gps_acquiring.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_gps_acquiring.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_0.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_0.png
index 8654aa0..35056d3 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_0.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_1.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_1.png
index c10629f..dcfcc00 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_1.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_1_fully.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_1_fully.png
index 753c9f9..e61b6ba 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_1_fully.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_2.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_2.png
index 65a886a..f0f86e5 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_2.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_2_fully.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_2_fully.png
index 6e90ce4..1025e81 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_2_fully.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_3.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_3.png
index cce7d9b..c4cc59f 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_3.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_3_fully.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_3_fully.png
index c4e33bd..4976752 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_3_fully.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_4.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_4.png
index 433a2c5..380a5f4 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_4.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_4_fully.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_4_fully.png
index 81401b2..d97b1de 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_4_fully.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_4_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_flightmode.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_flightmode.png
index a1a9794..174d65c 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_flightmode.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_flightmode.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_in.png
index e429ea1..abbdbc0 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_in.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_inout.png
index e3bcaf9..f1f4c1c 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_inout.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_out.png
index 26db91e..f767994 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_out.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_in.png
index 957c5ba..7c97a01 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_in.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_inout.png
index aec6050..c0665c4 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_inout.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_out.png
index bb8eea0..8746388 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_out.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_0.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_0.png
index 75906a2..150a6c7 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_0.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_1.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_1.png
index 528e4ce..76f86dc 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_1.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_1_fully.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_1_fully.png
index 1eb5aad..1f0dd89 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_1_fully.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_2.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_2.png
index 5f2c230..5e7ae35 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_2.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_2_fully.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_2_fully.png
index 2c27620..b861bc9 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_2_fully.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_3.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_3.png
index 4cb06be..8f16376 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_3.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_3_fully.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_3_fully.png
index fd9c350..67f46d3 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_3_fully.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_4.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_4.png
index e8aed95..165348c 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_4.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_4_fully.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_4_fully.png
index c629387..d53d3bc 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_4_fully.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_4_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_1x.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_1x.png
index 8e039ce..1629575 100644
--- a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_1x.png
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_3g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_3g.png
index 0cb0a08..e87bcec 100644
--- a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_3g.png
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_4g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_4g.png
index c3cd10b..fd44002 100644
--- a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_4g.png
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_e.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_e.png
index 650f67b..e455ad6 100644
--- a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_e.png
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_g.png
index f5b1618..6613585 100644
--- a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_g.png
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_h.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_h.png
index eddc487..7502a54 100644
--- a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_h.png
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_roam.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_roam.png
index 1eb0142..1309176 100644
--- a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_roam.png
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_roam.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_1x.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_1x.png
index 4c8e7c3..810714e 100644
--- a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_1x.png
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_3g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_3g.png
index 657dc04..72176ba 100644
--- a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_3g.png
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_4g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_4g.png
index 359e8f8..82a2bf0 100644
--- a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_4g.png
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_e.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_e.png
index e5b0841..1e6c604 100644
--- a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_e.png
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_g.png
index 4fe8df3..13aee06 100644
--- a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_g.png
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_h.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_h.png
index a7a7beac..76c48a8 100644
--- a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_h.png
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_1x.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_1x.png
index 2cbec7b..73cdabe 100644
--- a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_1x.png
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_3g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_3g.png
index 0efb9c9..b5a39cc 100644
--- a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_3g.png
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_4g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_4g.png
index 2eae1e1..6de880c 100644
--- a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_4g.png
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_e.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_e.png
index 7e82c4c..2dbbfc0 100644
--- a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_e.png
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_g.png
index d37f1e5..a45f011 100644
--- a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_g.png
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_h.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_h.png
index 5f7349e..517a6bb 100644
--- a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_h.png
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_roam.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_roam.png
index 31358ec..5226c1c 100644
--- a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_roam.png
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_roam.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_1x.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_1x.png
index e5a3484..a845648 100644
--- a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_1x.png
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_3g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_3g.png
index 2a3a5dc..1d15587 100644
--- a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_3g.png
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_4g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_4g.png
index 5dbd1ab..52d5736 100644
--- a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_4g.png
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_e.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_e.png
index 51d1f76..79a2a05 100644
--- a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_e.png
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_g.png
index 10d81ca..b032594 100644
--- a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_g.png
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_h.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_h.png
index 1d9bda0..c4abcc9 100644
--- a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_h.png
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_h.png
Binary files differ
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel_title.xml b/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel_title.xml
index 1afb2e3..543f4ed 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel_title.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel_title.xml
@@ -22,7 +22,6 @@
android:layout_height="0dp"
android:orientation="vertical"
android:background="@drawable/notify_panel_clock_bg"
- android:clickable="true"
>
<LinearLayout
android:id="@+id/icons"
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_recent_item.xml b/packages/SystemUI/res/layout-xlarge/status_bar_recent_item.xml
index bfa6c36a..3f172e6 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_recent_item.xml
@@ -38,8 +38,8 @@
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
- android:layout_marginLeft="123dip"
- android:layout_marginTop="16dip"
+ android:layout_marginLeft="131dip"
+ android:layout_marginTop="13dip"
android:maxWidth="@dimen/status_bar_recents_thumbnail_max_width"
android:maxHeight="@dimen/status_bar_recents_thumbnail_max_height"
android:adjustViewBounds="true"
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel.xml
index eda19b7..42940be 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel.xml
@@ -51,7 +51,7 @@
android:stackFromBottom="true"
android:fadingEdge="vertical"
android:scrollbars="none"
- android:fadingEdgeLength="30dip"
+ android:fadingEdgeLength="20dip"
android:listSelector="@drawable/recents_thumbnail_bg_selector"
/>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index ebd48e7..8998674 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -115,4 +115,29 @@
<!-- Label of a toggle switch to disable use of the physical keyboard in favor of the IME. [CHAR LIMIT=25] -->
<string name="status_bar_use_physical_keyboard">Use physical keyboard</string>
+
+ <!-- Prompt for the USB device permission dialog [CHAR LIMIT=80] -->
+ <string name="usb_device_permission_prompt">Allow the application %1$s to access the USB device?</string>
+
+ <!-- Prompt for the USB accessory permission dialog [CHAR LIMIT=80] -->
+ <string name="usb_accessory_permission_prompt">Allow the application %1$s to access the USB accessory?</string>
+
+ <!-- Prompt for the USB device confirm dialog [CHAR LIMIT=80] -->
+ <string name="usb_device_confirm_prompt">Open %1$s when this USB device is connected?</string>
+
+ <!-- Prompt for the USB accessory confirm dialog [CHAR LIMIT=80] -->
+ <string name="usb_accessory_confirm_prompt">Open %1$s when this USB accessory is connected?</string>
+
+ <!-- Prompt for the USB accessory URI dialog [CHAR LIMIT=80] -->
+ <string name="usb_accessory_uri_prompt">Additional information for this device may be found at: %1$s</string>
+
+ <!-- Title for USB accessory dialog. Used when the name of the accessory cannot be determined. [CHAR LIMIT=50] -->
+ <string name="title_usb_accessory">USB accessory</string>
+
+ <!-- View button label for USB dialogs. [CHAR LIMIT=15] -->
+ <string name="label_view">View</string>
+
+ <!-- Ignore button label for USB dialogs. [CHAR LIMIT=15] -->
+ <string name="label_ignore">Ignore</string>
+
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 326cd74..6b9551b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -94,6 +94,7 @@
int mWifiLevel;
String mWifiSsid;
int mWifiIconId = 0;
+ int mWifiActivity = WifiManager.DATA_ACTIVITY_NONE;
// bluetooth
private boolean mBluetoothTethered = false;
@@ -153,9 +154,7 @@
// wifi
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
- HandlerThread handlerThread = new HandlerThread("WifiServiceThread");
- handlerThread.start();
- Handler handler = new WifiHandler(handlerThread.getLooper());
+ Handler handler = new WifiHandler();
mWifiChannel = new AsyncChannel();
Messenger wifiMessenger = mWifiManager.getMessenger();
if (wifiMessenger != null) {
@@ -553,11 +552,6 @@
// ===== Wifi ===================================================================
class WifiHandler extends Handler {
-
- WifiHandler(Looper looper) {
- super(looper);
- }
-
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
@@ -570,17 +564,9 @@
}
break;
case WifiManager.DATA_ACTIVITY_NOTIFICATION:
- int dataActivity = msg.arg1;
- /* TODO: update icons based on data activity */
- switch (dataActivity) {
- case WifiManager.DATA_ACTIVITY_IN:
- break;
- case WifiManager.DATA_ACTIVITY_OUT:
- break;
- case WifiManager.DATA_ACTIVITY_INOUT:
- break;
- case WifiManager.DATA_ACTIVITY_NONE:
- break;
+ if (msg.arg1 != mWifiActivity) {
+ mWifiActivity = msg.arg1;
+ refreshViews();
}
break;
default:
@@ -701,6 +687,19 @@
label = context.getString(R.string.status_bar_settings_signal_meter_wifi_nossid);
} else {
label = mWifiSsid;
+ switch (mWifiActivity) {
+ case WifiManager.DATA_ACTIVITY_IN:
+ dataDirectionOverlayIconId = R.drawable.stat_sys_wifi_in;
+ break;
+ case WifiManager.DATA_ACTIVITY_OUT:
+ dataDirectionOverlayIconId = R.drawable.stat_sys_wifi_out;
+ break;
+ case WifiManager.DATA_ACTIVITY_INOUT:
+ dataDirectionOverlayIconId = R.drawable.stat_sys_wifi_inout;
+ break;
+ case WifiManager.DATA_ACTIVITY_NONE:
+ break;
+ }
}
combinedSignalIconId = mWifiIconId;
dataTypeIconId = 0;
@@ -888,6 +887,9 @@
pw.println(mWifiSsid);
pw.print(" mWifiIconId=");
pw.println(mWifiIconId);
+ pw.print(" mWifiActivity=");
+ pw.println(mWifiActivity);
+
pw.println(" - Bluetooth ----");
pw.print(" mBtReverseTethered=");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPeekPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPeekPanel.java
index 744f667..8b68240 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPeekPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPeekPanel.java
@@ -18,11 +18,15 @@
import android.content.Context;
import android.util.AttributeSet;
+import android.util.Slog;
+import android.view.MotionEvent;
import android.widget.RelativeLayout;
import com.android.systemui.R;
public class NotificationPeekPanel extends RelativeLayout implements StatusBarPanel {
+ TabletStatusBar mBar;
+
public NotificationPeekPanel(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
@@ -39,5 +43,16 @@
return x >= l && x < r && y >= t && y < b;
}
+ public void setBar(TabletStatusBar bar) {
+ mBar = bar;
+ }
+
+ // We don't really want to intercept the touch event, but we *do* want to reset the fade timer
+ // in case the user is interacting with some custom controls or something.
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ mBar.resetNotificationPeekFadeTimer();
+ return false;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
index 737a52b..c5a7df2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
@@ -513,9 +513,7 @@
paint.setFilterBitmap(true);
paint.setAlpha(255);
final int srcWidth = thumbnail.getWidth();
- final int height = thumbnail.getHeight();
- final int srcHeight = srcWidth > height ? height
- : (height - height * srcWidth / height);
+ final int srcHeight = thumbnail.getHeight();
canvas.drawBitmap(thumbnail,
new Rect(0, 0, srcWidth-1, srcHeight-1),
new RectF(GLOW_PADDING,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index 4557105..58c4d5a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -217,6 +217,8 @@
// Notification preview window
mNotificationPeekWindow = (NotificationPeekPanel) View.inflate(context,
R.layout.status_bar_notification_peek, null);
+ mNotificationPeekWindow.setBar(this);
+
mNotificationPeekRow = (ViewGroup) mNotificationPeekWindow.findViewById(R.id.content);
mNotificationPeekWindow.setVisibility(View.GONE);
mNotificationPeekWindow.setOnTouchListener(
@@ -1211,10 +1213,20 @@
}
}
- private class NotificationIconTouchListener implements View.OnTouchListener {
- final static int NOTIFICATION_PEEK_HOLD_THRESH = 200; // ms
- final static int NOTIFICATION_PEEK_FADE_DELAY = 5000; // ms
+ final static int NOTIFICATION_PEEK_HOLD_THRESH = 200; // ms
+ final static int NOTIFICATION_PEEK_FADE_DELAY = 3000; // ms
+ public void resetNotificationPeekFadeTimer() {
+ if (DEBUG) {
+ Slog.d(TAG, "setting peek fade timer for " + NOTIFICATION_PEEK_FADE_DELAY
+ + "ms from now");
+ }
+ mHandler.removeMessages(MSG_CLOSE_NOTIFICATION_PEEK);
+ mHandler.sendEmptyMessageDelayed(MSG_CLOSE_NOTIFICATION_PEEK,
+ NOTIFICATION_PEEK_FADE_DELAY);
+ }
+
+ private class NotificationIconTouchListener implements View.OnTouchListener {
VelocityTracker mVT;
int mPeekIndex;
float mInitialTouchX, mInitialTouchY;
@@ -1303,8 +1315,7 @@
}
if (peeking) {
- mHandler.sendEmptyMessageDelayed(MSG_CLOSE_NOTIFICATION_PEEK,
- NOTIFICATION_PEEK_FADE_DELAY);
+ resetNotificationPeekFadeTimer();
}
mVT.recycle();
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java
new file mode 100644
index 0000000..eefb1c6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java
@@ -0,0 +1,100 @@
+/*
+ * 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 com.android.systemui.usb;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.net.Uri;
+import android.hardware.usb.UsbAccessory;
+import android.hardware.usb.UsbManager;
+import android.os.Bundle;
+import android.util.Log;
+
+import com.android.internal.app.AlertActivity;
+import com.android.internal.app.AlertController;
+
+import com.android.systemui.R;
+
+/**
+ * If the attached USB accessory has a URL associated with it, and that URL is valid,
+ * show this dialog to the user to allow them to optionally visit that URL for more
+ * information or software downloads.
+ * Otherwise (no valid URL) this activity does nothing at all, finishing immediately.
+ */
+public class UsbAccessoryUriActivity extends AlertActivity
+ implements DialogInterface.OnClickListener {
+
+ private static final String TAG = "UsbAccessoryUriActivity";
+
+ private UsbAccessory mAccessory;
+ private Uri mUri;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ Intent intent = getIntent();
+ mAccessory = (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
+ String uriString = intent.getStringExtra("uri");
+ mUri = (uriString == null ? null : Uri.parse(uriString));
+
+ // sanity check before displaying dialog
+ if (mUri == null) {
+ Log.e(TAG, "could not parse Uri " + uriString);
+ finish();
+ return;
+ }
+ String scheme = mUri.getScheme();
+ if (!"http".equals(scheme) && !"https".equals(scheme)) {
+ Log.e(TAG, "Uri not http or https: " + mUri);
+ finish();
+ return;
+ }
+
+ final AlertController.AlertParams ap = mAlertParams;
+ ap.mTitle = mAccessory.getDescription();
+ if (ap.mTitle == null || ap.mTitle.length() == 0) {
+ ap.mTitle = getString(R.string.title_usb_accessory);
+ }
+ ap.mMessage = getString(R.string.usb_accessory_uri_prompt, mUri);
+ ap.mPositiveButtonText = getString(R.string.label_view);
+ ap.mNegativeButtonText = getString(R.string.label_ignore);
+ ap.mPositiveButtonListener = this;
+ ap.mNegativeButtonListener = this;
+
+ setupAlert();
+ }
+
+ public void onClick(DialogInterface dialog, int which) {
+ if (which == AlertDialog.BUTTON_POSITIVE) {
+ // launch the browser
+ Intent intent = new Intent(Intent.ACTION_VIEW, mUri);
+ intent.addCategory(Intent.CATEGORY_BROWSABLE);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ try {
+ startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ Log.e(TAG, "startActivity failed for " + mUri);
+ }
+ }
+ finish();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbConfirmActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbConfirmActivity.java
new file mode 100644
index 0000000..4e6f81f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbConfirmActivity.java
@@ -0,0 +1,160 @@
+/*
+ * 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 com.android.systemui.usb;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.hardware.usb.IUsbManager;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbAccessory;
+import android.hardware.usb.UsbManager;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.TextView;
+
+import com.android.internal.app.AlertActivity;
+import com.android.internal.app.AlertController;
+
+import com.android.systemui.R;
+
+public class UsbConfirmActivity extends AlertActivity
+ implements DialogInterface.OnClickListener, CheckBox.OnCheckedChangeListener {
+
+ private static final String TAG = "UsbConfirmActivity";
+
+ private CheckBox mAlwaysUse;
+ private TextView mClearDefaultHint;
+ private UsbDevice mDevice;
+ private UsbAccessory mAccessory;
+ private ResolveInfo mResolveInfo;
+ private boolean mPermissionGranted;
+ private UsbDisconnectedReceiver mDisconnectedReceiver;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ Intent intent = getIntent();
+ mDevice = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
+ mAccessory = (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
+ mResolveInfo = (ResolveInfo)intent.getParcelableExtra("rinfo");
+
+ PackageManager packageManager = getPackageManager();
+ String appName = mResolveInfo.loadLabel(packageManager).toString();
+
+ final AlertController.AlertParams ap = mAlertParams;
+ ap.mIcon = mResolveInfo.loadIcon(packageManager);
+ ap.mTitle = appName;
+ if (mDevice == null) {
+ ap.mMessage = getString(R.string.usb_accessory_confirm_prompt, appName);
+ mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mAccessory);
+ } else {
+ ap.mMessage = getString(R.string.usb_device_confirm_prompt, appName);
+ mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mDevice);
+ }
+ ap.mPositiveButtonText = getString(com.android.internal.R.string.ok);
+ ap.mNegativeButtonText = getString(com.android.internal.R.string.cancel);
+ ap.mPositiveButtonListener = this;
+ ap.mNegativeButtonListener = this;
+
+ // add "always use" checkbox
+ LayoutInflater inflater = (LayoutInflater)getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ ap.mView = inflater.inflate(com.android.internal.R.layout.always_use_checkbox, null);
+ mAlwaysUse = (CheckBox)ap.mView.findViewById(com.android.internal.R.id.alwaysUse);
+ mAlwaysUse.setText(com.android.internal.R.string.alwaysUse);
+ mAlwaysUse.setOnCheckedChangeListener(this);
+ mClearDefaultHint = (TextView)ap.mView.findViewById(
+ com.android.internal.R.id.clearDefaultHint);
+ mClearDefaultHint.setVisibility(View.GONE);
+
+ setupAlert();
+
+ }
+
+ public void onClick(DialogInterface dialog, int which) {
+ if (which == AlertDialog.BUTTON_POSITIVE) {
+ try {
+ IBinder b = ServiceManager.getService(USB_SERVICE);
+ IUsbManager service = IUsbManager.Stub.asInterface(b);
+ int uid = mResolveInfo.activityInfo.applicationInfo.uid;
+ boolean alwaysUse = mAlwaysUse.isChecked();
+ Intent intent = null;
+
+ if (mDevice != null) {
+ intent = new Intent(UsbManager.ACTION_USB_DEVICE_ATTACHED);
+ intent.putExtra(UsbManager.EXTRA_DEVICE, mDevice);
+
+ // grant permission for the device
+ service.grantDevicePermission(mDevice, uid);
+ // set or clear default setting
+ if (alwaysUse) {
+ service.setDevicePackage(mDevice, mResolveInfo.activityInfo.packageName);
+ } else {
+ service.setDevicePackage(mDevice, null);
+ }
+ } else if (mAccessory != null) {
+ intent = new Intent(UsbManager.ACTION_USB_ACCESSORY_ATTACHED);
+ intent.putExtra(UsbManager.EXTRA_ACCESSORY, mAccessory);
+
+ // grant permission for the accessory
+ service.grantAccessoryPermission(mAccessory, uid);
+ // set or clear default setting
+ if (alwaysUse) {
+ service.setAccessoryPackage(mAccessory,
+ mResolveInfo.activityInfo.packageName);
+ } else {
+ service.setAccessoryPackage(mAccessory, null);
+ }
+ }
+
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.setComponent(
+ new ComponentName(mResolveInfo.activityInfo.packageName,
+ mResolveInfo.activityInfo.name));
+ startActivity(intent);
+ } catch (Exception e) {
+ Log.e(TAG, "Unable to start activity", e);
+ }
+ }
+ finish();
+ }
+
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (mClearDefaultHint == null) return;
+
+ if(isChecked) {
+ mClearDefaultHint.setVisibility(View.VISIBLE);
+ } else {
+ mClearDefaultHint.setVisibility(View.GONE);
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDisconnectedReceiver.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDisconnectedReceiver.java
new file mode 100644
index 0000000..1edebbb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDisconnectedReceiver.java
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ * 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 com.android.systemui.usb;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.hardware.usb.UsbAccessory;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbManager;
+
+// This class is used to close UsbPermissionsActivity and UsbResolverActivity
+// if their device/accessory is disconnected while the dialog is still open
+class UsbDisconnectedReceiver extends BroadcastReceiver {
+ private final Activity mActivity;
+ private UsbDevice mDevice;
+ private UsbAccessory mAccessory;
+
+ public UsbDisconnectedReceiver(Activity activity, UsbDevice device) {
+ mActivity = activity;
+ mDevice = device;
+
+ IntentFilter filter = new IntentFilter(UsbManager.ACTION_USB_DEVICE_DETACHED);
+ activity.registerReceiver(this, filter);
+ }
+
+ public UsbDisconnectedReceiver(Activity activity, UsbAccessory accessory) {
+ mActivity = activity;
+ mAccessory = accessory;
+
+ IntentFilter filter = new IntentFilter(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
+ activity.registerReceiver(this, filter);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
+ UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
+ if (device != null && device.equals(mDevice)) {
+ mActivity.finish();
+ }
+ } else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {
+ UsbAccessory accessory =
+ (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
+ if (accessory != null && accessory.equals(mAccessory)) {
+ mActivity.finish();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java
new file mode 100644
index 0000000..27cce6d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java
@@ -0,0 +1,170 @@
+/*
+ * 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 com.android.systemui.usb;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.hardware.usb.IUsbManager;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbAccessory;
+import android.hardware.usb.UsbManager;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.TextView;
+
+import com.android.internal.app.AlertActivity;
+import com.android.internal.app.AlertController;
+
+import com.android.systemui.R;
+
+public class UsbPermissionActivity extends AlertActivity
+ implements DialogInterface.OnClickListener, CheckBox.OnCheckedChangeListener {
+
+ private static final String TAG = "UsbPermissionActivity";
+
+ private CheckBox mAlwaysUse;
+ private TextView mClearDefaultHint;
+ private UsbDevice mDevice;
+ private UsbAccessory mAccessory;
+ private PendingIntent mPendingIntent;
+ private String mPackageName;
+ private int mUid;
+ private boolean mPermissionGranted;
+ private UsbDisconnectedReceiver mDisconnectedReceiver;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ Intent intent = getIntent();
+ mDevice = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
+ mAccessory = (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
+ mPendingIntent = (PendingIntent)intent.getParcelableExtra(Intent.EXTRA_INTENT);
+ mUid = intent.getIntExtra("uid", 0);
+ mPackageName = intent.getStringExtra("package");
+
+ PackageManager packageManager = getPackageManager();
+ ApplicationInfo aInfo;
+ try {
+ aInfo = packageManager.getApplicationInfo(mPackageName, 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(TAG, "unable to look up package name", e);
+ finish();
+ return;
+ }
+ String appName = aInfo.loadLabel(packageManager).toString();
+
+ final AlertController.AlertParams ap = mAlertParams;
+ ap.mIcon = aInfo.loadIcon(packageManager);
+ ap.mTitle = appName;
+ if (mDevice == null) {
+ ap.mMessage = getString(R.string.usb_accessory_permission_prompt, appName);
+ mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mAccessory);
+ } else {
+ ap.mMessage = getString(R.string.usb_device_permission_prompt, appName);
+ mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mDevice);
+ }
+ ap.mPositiveButtonText = getString(com.android.internal.R.string.ok);
+ ap.mNegativeButtonText = getString(com.android.internal.R.string.cancel);
+ ap.mPositiveButtonListener = this;
+ ap.mNegativeButtonListener = this;
+
+ // add "always use" checkbox
+ LayoutInflater inflater = (LayoutInflater)getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ ap.mView = inflater.inflate(com.android.internal.R.layout.always_use_checkbox, null);
+ mAlwaysUse = (CheckBox)ap.mView.findViewById(com.android.internal.R.id.alwaysUse);
+ mAlwaysUse.setText(com.android.internal.R.string.alwaysUse);
+ mAlwaysUse.setOnCheckedChangeListener(this);
+ mClearDefaultHint = (TextView)ap.mView.findViewById(
+ com.android.internal.R.id.clearDefaultHint);
+ mClearDefaultHint.setVisibility(View.GONE);
+
+ setupAlert();
+
+ }
+
+ @Override
+ public void onDestroy() {
+ IBinder b = ServiceManager.getService(USB_SERVICE);
+ IUsbManager service = IUsbManager.Stub.asInterface(b);
+
+ // send response via pending intent
+ Intent intent = new Intent();
+ try {
+ if (mDevice != null) {
+ intent.putExtra(UsbManager.EXTRA_DEVICE, mDevice);
+ if (mPermissionGranted) {
+ service.grantDevicePermission(mDevice, mUid);
+ if (mAlwaysUse.isChecked()) {
+ service.setDevicePackage(mDevice, mPackageName);
+ }
+ }
+ }
+ if (mAccessory != null) {
+ intent.putExtra(UsbManager.EXTRA_ACCESSORY, mAccessory);
+ if (mPermissionGranted) {
+ service.grantAccessoryPermission(mAccessory, mUid);
+ if (mAlwaysUse.isChecked()) {
+ service.setAccessoryPackage(mAccessory, mPackageName);
+ }
+ }
+ }
+ intent.putExtra(UsbManager.EXTRA_PERMISSION_GRANTED, mPermissionGranted);
+ mPendingIntent.send(this, 0, intent);
+ } catch (PendingIntent.CanceledException e) {
+ Log.w(TAG, "PendingIntent was cancelled");
+ } catch (RemoteException e) {
+ Log.e(TAG, "IUsbService connection failed", e);
+ }
+
+ if (mDisconnectedReceiver != null) {
+ unregisterReceiver(mDisconnectedReceiver);
+ }
+ super.onDestroy();
+ }
+
+ public void onClick(DialogInterface dialog, int which) {
+ if (which == AlertDialog.BUTTON_POSITIVE) {
+ mPermissionGranted = true;
+ }
+ finish();
+ }
+
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (mClearDefaultHint == null) return;
+
+ if(isChecked) {
+ mClearDefaultHint.setVisibility(View.VISIBLE);
+ } else {
+ mClearDefaultHint.setVisibility(View.GONE);
+ }
+ }
+}
diff --git a/services/java/com/android/server/usb/UsbResolverActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java
similarity index 66%
rename from services/java/com/android/server/usb/UsbResolverActivity.java
rename to packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java
index e8a09a5..7c63820 100644
--- a/services/java/com/android/server/usb/UsbResolverActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server.usb;
+package com.android.systemui.usb;
import com.android.internal.app.ResolverActivity;
@@ -39,6 +39,10 @@
public static final String TAG = "UsbResolverActivity";
public static final String EXTRA_RESOLVE_INFOS = "rlist";
+ private UsbDevice mDevice;
+ private UsbAccessory mAccessory;
+ private UsbDisconnectedReceiver mDisconnectedReceiver;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
Intent intent = getIntent();
@@ -50,14 +54,30 @@
}
Intent target = (Intent)targetParcelable;
ArrayList<ResolveInfo> rList = intent.getParcelableArrayListExtra(EXTRA_RESOLVE_INFOS);
- Log.d(TAG, "rList.size() " + rList.size());
CharSequence title = getResources().getText(com.android.internal.R.string.chooseUsbActivity);
super.onCreate(savedInstanceState, target, title, null, rList,
- true, /* Set alwaysUseOption to true to enable "always use this app" checkbox. */
- true /* Set alwaysChoose to display activity when only one choice is available.
- This is necessary because this activity is needed for the user to allow
- the application permission to access the device */
- );
+ true /* Set alwaysUseOption to true to enable "always use this app" checkbox. */ );
+
+ mDevice = (UsbDevice)target.getParcelableExtra(UsbManager.EXTRA_DEVICE);
+ if (mDevice != null) {
+ mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mDevice);
+ } else {
+ mAccessory = (UsbAccessory)target.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
+ if (mAccessory == null) {
+ Log.e(TAG, "no device or accessory");
+ finish();
+ return;
+ }
+ mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mAccessory);
+ }
+ }
+
+ @Override
+ protected void onDestroy() {
+ if (mDisconnectedReceiver != null) {
+ unregisterReceiver(mDisconnectedReceiver);
+ }
+ super.onDestroy();
}
protected void onIntentSelected(ResolveInfo ri, Intent intent, boolean alwaysCheck) {
@@ -65,28 +85,24 @@
IBinder b = ServiceManager.getService(USB_SERVICE);
IUsbManager service = IUsbManager.Stub.asInterface(b);
int uid = ri.activityInfo.applicationInfo.uid;
- String action = intent.getAction();
- if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
- UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
+ if (mDevice != null) {
// grant permission for the device
- service.grantDevicePermission(device, uid);
+ service.grantDevicePermission(mDevice, uid);
// set or clear default setting
if (alwaysCheck) {
- service.setDevicePackage(device, ri.activityInfo.packageName);
+ service.setDevicePackage(mDevice, ri.activityInfo.packageName);
} else {
- service.setDevicePackage(device, null);
+ service.setDevicePackage(mDevice, null);
}
- } else if (UsbManager.ACTION_USB_ACCESSORY_ATTACHED.equals(action)) {
- UsbAccessory accessory = (UsbAccessory)intent.getParcelableExtra(
- UsbManager.EXTRA_ACCESSORY);
+ } else if (mAccessory != null) {
// grant permission for the accessory
- service.grantAccessoryPermission(accessory, uid);
+ service.grantAccessoryPermission(mAccessory, uid);
// set or clear default setting
if (alwaysCheck) {
- service.setAccessoryPackage(accessory, ri.activityInfo.packageName);
+ service.setAccessoryPackage(mAccessory, ri.activityInfo.packageName);
} else {
- service.setAccessoryPackage(accessory, null);
+ service.setAccessoryPackage(mAccessory, null);
}
}
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
index 8d70a7b..ae23df6 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
@@ -103,6 +103,8 @@
int flags = WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN
| WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER
| WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING
+ | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
+ | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED_SYSTEM
/*| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR*/ ;
if (!mNeedsInput) {
@@ -142,7 +144,7 @@
mKeyguardView.onScreenTurnedOn();
}
}
-
+ mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
mKeyguardHost.setVisibility(View.VISIBLE);
mKeyguardView.requestFocus();
}
diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java
index 2bc57b5..a9d5ce4 100644
--- a/policy/src/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/LockScreen.java
@@ -232,6 +232,8 @@
/** {@inheritDoc} */
public void onGrabbedStateChange(View v, int grabbedState) {
+ if (DBG) Log.v(TAG, "*** LockScreen accel is "
+ + (mEnergyWave.isHardwareAccelerated() ? "on":"off"));
// Don't poke the wake lock when returning to a state where the handle is
// not grabbed since that can happen when the system (instead of the user)
// cancels the grab.
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index ec89db3..64857ed 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -2187,7 +2187,7 @@
super.onDetachedFromWindow();
final Callback cb = getCallback();
- if (cb != null && !isDestroyed() && mFeatureId < 0) {
+ if (cb != null && mFeatureId < 0) {
cb.onDetachedFromWindow();
}
diff --git a/services/input/EventHub.cpp b/services/input/EventHub.cpp
index d5f78a9..e2da740 100644
--- a/services/input/EventHub.cpp
+++ b/services/input/EventHub.cpp
@@ -352,14 +352,13 @@
return NAME_NOT_FOUND;
}
-status_t EventHub::mapAxis(int32_t deviceId, int scancode,
- int32_t* outAxis) const
+status_t EventHub::mapAxis(int32_t deviceId, int scancode, AxisInfo* outAxisInfo) const
{
AutoMutex _l(mLock);
Device* device = getDeviceLocked(deviceId);
if (device && device->keyMap.haveKeyLayout()) {
- status_t err = device->keyMap.keyLayoutMap->mapAxis(scancode, outAxis);
+ status_t err = device->keyMap.keyLayoutMap->mapAxis(scancode, outAxisInfo);
if (err == NO_ERROR) {
return NO_ERROR;
}
@@ -369,14 +368,13 @@
device = getDeviceLocked(mBuiltInKeyboardId);
if (device && device->keyMap.haveKeyLayout()) {
- status_t err = device->keyMap.keyLayoutMap->mapAxis(scancode, outAxis);
+ status_t err = device->keyMap.keyLayoutMap->mapAxis(scancode, outAxisInfo);
if (err == NO_ERROR) {
return NO_ERROR;
}
}
}
- *outAxis = -1;
return NAME_NOT_FOUND;
}
diff --git a/services/input/EventHub.h b/services/input/EventHub.h
index 99be802..7053a94 100644
--- a/services/input/EventHub.h
+++ b/services/input/EventHub.h
@@ -174,7 +174,7 @@
int32_t* outKeycode, uint32_t* outFlags) const = 0;
virtual status_t mapAxis(int32_t deviceId, int scancode,
- int32_t* outAxis) const = 0;
+ AxisInfo* outAxisInfo) const = 0;
// exclude a particular device from opening
// this can be used to ignore input devices for sensors
@@ -233,7 +233,7 @@
int32_t* outKeycode, uint32_t* outFlags) const;
virtual status_t mapAxis(int32_t deviceId, int scancode,
- int32_t* outAxis) const;
+ AxisInfo* outAxisInfo) const;
virtual void addExcludedDevice(const char* deviceName);
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index e614e81..19295e6d 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -2245,6 +2245,21 @@
policyFlags |= POLICY_FLAG_VIRTUAL;
flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
}
+ if (policyFlags & POLICY_FLAG_ALT) {
+ metaState |= AMETA_ALT_ON | AMETA_ALT_LEFT_ON;
+ }
+ if (policyFlags & POLICY_FLAG_ALT_GR) {
+ metaState |= AMETA_ALT_ON | AMETA_ALT_RIGHT_ON;
+ }
+ if (policyFlags & POLICY_FLAG_SHIFT) {
+ metaState |= AMETA_SHIFT_ON | AMETA_SHIFT_LEFT_ON;
+ }
+ if (policyFlags & POLICY_FLAG_CAPS_LOCK) {
+ metaState |= AMETA_CAPS_LOCK_ON;
+ }
+ if (policyFlags & POLICY_FLAG_FUNCTION) {
+ metaState |= AMETA_FUNCTION_ON;
+ }
policyFlags |= POLICY_FLAG_TRUSTED;
@@ -2328,17 +2343,17 @@
}
MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
- if (motionEntry->deviceId != deviceId) {
- // Keep looking for this device.
+ if (motionEntry->deviceId != deviceId
+ || motionEntry->source != source) {
+ // Keep looking for this device and source.
continue;
}
if (motionEntry->action != action
- || motionEntry->source != source
|| motionEntry->pointerCount != pointerCount
|| motionEntry->isInjected()) {
- // Last motion event in the queue for this device is not compatible for
- // appending new samples. Stop here.
+ // Last motion event in the queue for this device and source is
+ // not compatible for appending new samples. Stop here.
goto NoBatchingOrStreaming;
}
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index 084264b..3029028 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -33,6 +33,7 @@
// Log debug messages about pointer assignment calculations.
#define DEBUG_POINTER_ASSIGNMENT 0
+
#include "InputReader.h"
#include <cutils/log.h>
@@ -140,6 +141,48 @@
return (sources & sourceMask & ~ AINPUT_SOURCE_CLASS_MASK) != 0;
}
+static uint32_t getButtonStateForScanCode(int32_t scanCode) {
+ // Currently all buttons are mapped to the primary button.
+ switch (scanCode) {
+ case BTN_LEFT:
+ case BTN_RIGHT:
+ case BTN_MIDDLE:
+ case BTN_SIDE:
+ case BTN_EXTRA:
+ case BTN_FORWARD:
+ case BTN_BACK:
+ case BTN_TASK:
+ return BUTTON_STATE_PRIMARY;
+ default:
+ return 0;
+ }
+}
+
+// Returns true if the pointer should be reported as being down given the specified
+// button states.
+static bool isPointerDown(uint32_t buttonState) {
+ return buttonState & BUTTON_STATE_PRIMARY;
+}
+
+static int32_t calculateEdgeFlagsUsingPointerBounds(
+ const sp<PointerControllerInterface>& pointerController, float x, float y) {
+ int32_t edgeFlags = 0;
+ float minX, minY, maxX, maxY;
+ if (pointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
+ if (x <= minX) {
+ edgeFlags |= AMOTION_EVENT_EDGE_FLAG_LEFT;
+ } else if (x >= maxX) {
+ edgeFlags |= AMOTION_EVENT_EDGE_FLAG_RIGHT;
+ }
+ if (y <= minY) {
+ edgeFlags |= AMOTION_EVENT_EDGE_FLAG_TOP;
+ } else if (y >= maxY) {
+ edgeFlags |= AMOTION_EVENT_EDGE_FLAG_BOTTOM;
+ }
+ }
+ return edgeFlags;
+}
+
// --- InputReader ---
@@ -270,23 +313,23 @@
}
// Keyboard-like devices.
- uint32_t keyboardSources = 0;
+ uint32_t keyboardSource = 0;
int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC;
if (classes & INPUT_DEVICE_CLASS_KEYBOARD) {
- keyboardSources |= AINPUT_SOURCE_KEYBOARD;
+ keyboardSource |= AINPUT_SOURCE_KEYBOARD;
}
if (classes & INPUT_DEVICE_CLASS_ALPHAKEY) {
keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC;
}
if (classes & INPUT_DEVICE_CLASS_DPAD) {
- keyboardSources |= AINPUT_SOURCE_DPAD;
+ keyboardSource |= AINPUT_SOURCE_DPAD;
}
if (classes & INPUT_DEVICE_CLASS_GAMEPAD) {
- keyboardSources |= AINPUT_SOURCE_GAMEPAD;
+ keyboardSource |= AINPUT_SOURCE_GAMEPAD;
}
- if (keyboardSources != 0) {
- device->addMapper(new KeyboardInputMapper(device, keyboardSources, keyboardType));
+ if (keyboardSource != 0) {
+ device->addMapper(new KeyboardInputMapper(device, keyboardSource, keyboardType));
}
// Cursor-like devices.
@@ -617,22 +660,22 @@
dump.appendFormat(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources());
dump.appendFormat(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType());
- const KeyedVector<int32_t, InputDeviceInfo::MotionRange> ranges = deviceInfo.getMotionRanges();
+ const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
if (!ranges.isEmpty()) {
dump.append(INDENT2 "Motion Ranges:\n");
for (size_t i = 0; i < ranges.size(); i++) {
- int32_t axis = ranges.keyAt(i);
- const char* label = getAxisLabel(axis);
+ const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
+ const char* label = getAxisLabel(range.axis);
char name[32];
if (label) {
strncpy(name, label, sizeof(name));
name[sizeof(name) - 1] = '\0';
} else {
- snprintf(name, sizeof(name), "%d", axis);
+ snprintf(name, sizeof(name), "%d", range.axis);
}
- const InputDeviceInfo::MotionRange& range = ranges.valueAt(i);
- dump.appendFormat(INDENT3 "%s: min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f\n",
- name, range.min, range.max, range.flat, range.fuzz);
+ dump.appendFormat(INDENT3 "%s: source=0x%08x, "
+ "min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f\n",
+ name, range.source, range.min, range.max, range.flat, range.fuzz);
}
}
@@ -837,8 +880,8 @@
// --- KeyboardInputMapper ---
KeyboardInputMapper::KeyboardInputMapper(InputDevice* device,
- uint32_t sources, int32_t keyboardType) :
- InputMapper(device), mSources(sources),
+ uint32_t source, int32_t keyboardType) :
+ InputMapper(device), mSource(source),
mKeyboardType(keyboardType) {
initializeLocked();
}
@@ -852,7 +895,7 @@
}
uint32_t KeyboardInputMapper::getSources() {
- return mSources;
+ return mSource;
}
void KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
@@ -1036,10 +1079,7 @@
getContext()->fadePointer();
}
- if (policyFlags & POLICY_FLAG_FUNCTION) {
- newMetaState |= AMETA_FUNCTION_ON;
- }
- getDispatcher()->notifyKey(when, getDeviceId(), mSources, policyFlags,
+ getDispatcher()->notifyKey(when, getDeviceId(), mSource, policyFlags,
down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
}
@@ -1119,7 +1159,7 @@
}
uint32_t CursorInputMapper::getSources() {
- return mSources;
+ return mSource;
}
void CursorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
@@ -1128,20 +1168,20 @@
if (mParameters.mode == Parameters::MODE_POINTER) {
float minX, minY, maxX, maxY;
if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
- info->addMotionRange(AMOTION_EVENT_AXIS_X, minX, maxX, 0.0f, 0.0f);
- info->addMotionRange(AMOTION_EVENT_AXIS_Y, minY, maxY, 0.0f, 0.0f);
+ info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, minX, maxX, 0.0f, 0.0f);
+ info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, minY, maxY, 0.0f, 0.0f);
}
} else {
- info->addMotionRange(AMOTION_EVENT_AXIS_X, -1.0f, 1.0f, 0.0f, mXScale);
- info->addMotionRange(AMOTION_EVENT_AXIS_Y, -1.0f, 1.0f, 0.0f, mYScale);
+ info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, -1.0f, 1.0f, 0.0f, mXScale);
+ info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, -1.0f, 1.0f, 0.0f, mYScale);
}
- info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, 0.0f, 1.0f, 0.0f, 0.0f);
+ info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, mSource, 0.0f, 1.0f, 0.0f, 0.0f);
if (mHaveVWheel) {
- info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, -1.0f, 1.0f, 0.0f, 0.0f);
+ info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f);
}
if (mHaveHWheel) {
- info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, -1.0f, 1.0f, 0.0f, 0.0f);
+ info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f);
}
}
@@ -1158,7 +1198,8 @@
dump.appendFormat(INDENT3 "HaveHWheel: %s\n", toString(mHaveHWheel));
dump.appendFormat(INDENT3 "VWheelScale: %0.3f\n", mVWheelScale);
dump.appendFormat(INDENT3 "HWheelScale: %0.3f\n", mHWheelScale);
- dump.appendFormat(INDENT3 "Down: %s\n", toString(mLocked.down));
+ dump.appendFormat(INDENT3 "ButtonState: 0x%08x\n", mLocked.buttonState);
+ dump.appendFormat(INDENT3 "Down: %s\n", toString(isPointerDown(mLocked.buttonState)));
dump.appendFormat(INDENT3 "DownTime: %lld\n", mLocked.downTime);
} // release lock
}
@@ -1172,7 +1213,7 @@
// Configure device mode.
switch (mParameters.mode) {
case Parameters::MODE_POINTER:
- mSources = AINPUT_SOURCE_MOUSE;
+ mSource = AINPUT_SOURCE_MOUSE;
mXPrecision = 1.0f;
mYPrecision = 1.0f;
mXScale = 1.0f;
@@ -1180,7 +1221,7 @@
mPointerController = getPolicy()->obtainPointerController(getDeviceId());
break;
case Parameters::MODE_NAVIGATION:
- mSources = AINPUT_SOURCE_TRACKBALL;
+ mSource = AINPUT_SOURCE_TRACKBALL;
mXPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
mYPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
@@ -1237,16 +1278,18 @@
void CursorInputMapper::initializeLocked() {
mAccumulator.clear();
- mLocked.down = false;
+ mLocked.buttonState = 0;
mLocked.downTime = 0;
}
void CursorInputMapper::reset() {
for (;;) {
+ uint32_t buttonState;
{ // acquire lock
AutoMutex _l(mLock);
- if (! mLocked.down) {
+ buttonState = mLocked.buttonState;
+ if (!buttonState) {
initializeLocked();
break; // done
}
@@ -1254,8 +1297,10 @@
// Synthesize button up event on reset.
nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
- mAccumulator.fields = Accumulator::FIELD_BTN_MOUSE;
- mAccumulator.btnMouse = false;
+ mAccumulator.clear();
+ mAccumulator.buttonDown = 0;
+ mAccumulator.buttonUp = buttonState;
+ mAccumulator.fields = Accumulator::FIELD_BUTTONS;
sync(when);
}
@@ -1264,24 +1309,25 @@
void CursorInputMapper::process(const RawEvent* rawEvent) {
switch (rawEvent->type) {
- case EV_KEY:
- switch (rawEvent->scanCode) {
- case BTN_LEFT:
- case BTN_RIGHT:
- case BTN_MIDDLE:
- case BTN_SIDE:
- case BTN_EXTRA:
- case BTN_FORWARD:
- case BTN_BACK:
- case BTN_TASK:
- mAccumulator.fields |= Accumulator::FIELD_BTN_MOUSE;
- mAccumulator.btnMouse = rawEvent->value != 0;
+ case EV_KEY: {
+ uint32_t buttonState = getButtonStateForScanCode(rawEvent->scanCode);
+ if (buttonState) {
+ if (rawEvent->value) {
+ mAccumulator.buttonDown = buttonState;
+ mAccumulator.buttonUp = 0;
+ } else {
+ mAccumulator.buttonDown = 0;
+ mAccumulator.buttonUp = buttonState;
+ }
+ mAccumulator.fields |= Accumulator::FIELD_BUTTONS;
+
// Sync now since BTN_MOUSE is not necessarily followed by SYN_REPORT and
// we need to ensure that we report the up/down promptly.
sync(rawEvent->when);
break;
}
break;
+ }
case EV_REL:
switch (rawEvent->scanCode) {
@@ -1328,23 +1374,26 @@
{ // acquire lock
AutoMutex _l(mLock);
- bool downChanged = fields & Accumulator::FIELD_BTN_MOUSE;
+ bool down, downChanged;
+ bool wasDown = isPointerDown(mLocked.buttonState);
+ bool buttonsChanged = fields & Accumulator::FIELD_BUTTONS;
+ if (buttonsChanged) {
+ mLocked.buttonState = (mLocked.buttonState | mAccumulator.buttonDown)
+ & ~mAccumulator.buttonUp;
- if (downChanged) {
- if (mAccumulator.btnMouse) {
- if (!mLocked.down) {
- mLocked.down = true;
- mLocked.downTime = when;
- } else {
- downChanged = false;
- }
+ down = isPointerDown(mLocked.buttonState);
+
+ if (!wasDown && down) {
+ mLocked.downTime = when;
+ downChanged = true;
+ } else if (wasDown && !down) {
+ downChanged = true;
} else {
- if (mLocked.down) {
- mLocked.down = false;
- } else {
- downChanged = false;
- }
+ downChanged = false;
}
+ } else {
+ down = wasDown;
+ downChanged = false;
}
downTime = mLocked.downTime;
@@ -1352,8 +1401,8 @@
float deltaY = fields & Accumulator::FIELD_REL_Y ? mAccumulator.relY * mYScale : 0.0f;
if (downChanged) {
- motionEventAction = mLocked.down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
- } else if (mLocked.down || mPointerController == NULL) {
+ motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
+ } else if (down || mPointerController == NULL) {
motionEventAction = AMOTION_EVENT_ACTION_MOVE;
} else {
motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE;
@@ -1396,35 +1445,25 @@
if (mPointerController != NULL) {
mPointerController->move(deltaX, deltaY);
- if (downChanged) {
- mPointerController->setButtonState(mLocked.down ? POINTER_BUTTON_1 : 0);
+ if (buttonsChanged) {
+ mPointerController->setButtonState(mLocked.buttonState);
}
+
float x, y;
mPointerController->getPosition(&x, &y);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
if (motionEventAction == AMOTION_EVENT_ACTION_DOWN) {
- float minX, minY, maxX, maxY;
- if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
- if (x <= minX) {
- motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_LEFT;
- } else if (x >= maxX) {
- motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_RIGHT;
- }
- if (y <= minY) {
- motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_TOP;
- } else if (y >= maxY) {
- motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_BOTTOM;
- }
- }
+ motionEventEdgeFlags = calculateEdgeFlagsUsingPointerBounds(
+ mPointerController, x, y);
}
} else {
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
}
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, mLocked.down ? 1.0f : 0.0f);
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f);
if (mHaveVWheel && (fields & Accumulator::FIELD_REL_WHEEL)) {
vscroll = mAccumulator.relWheel;
@@ -1452,7 +1491,7 @@
int32_t metaState = mContext->getGlobalMetaState();
int32_t pointerId = 0;
- getDispatcher()->notifyMotion(when, getDeviceId(), mSources, policyFlags,
+ getDispatcher()->notifyMotion(when, getDeviceId(), mSource, policyFlags,
motionEventAction, 0, metaState, motionEventEdgeFlags,
1, &pointerId, &pointerCoords, mXPrecision, mYPrecision, downTime);
@@ -1462,7 +1501,7 @@
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
- getDispatcher()->notifyMotion(when, getDeviceId(), mSources, policyFlags,
+ getDispatcher()->notifyMotion(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_SCROLL, 0, metaState, AMOTION_EVENT_EDGE_FLAG_NONE,
1, &pointerId, &pointerCoords, mXPrecision, mYPrecision, downTime);
}
@@ -1479,7 +1518,9 @@
void CursorInputMapper::fadePointer() {
{ // acquire lock
AutoMutex _l(mLock);
- mPointerController->fade();
+ if (mPointerController != NULL) {
+ mPointerController->fade();
+ }
} // release lock
}
@@ -1499,7 +1540,7 @@
}
uint32_t TouchInputMapper::getSources() {
- return mSources;
+ return mTouchSource;
}
void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
@@ -1510,38 +1551,33 @@
// Ensure surface information is up to date so that orientation changes are
// noticed immediately.
- configureSurfaceLocked();
+ if (!configureSurfaceLocked()) {
+ return;
+ }
- info->addMotionRange(AMOTION_EVENT_AXIS_X, mLocked.orientedRanges.x);
- info->addMotionRange(AMOTION_EVENT_AXIS_Y, mLocked.orientedRanges.y);
+ info->addMotionRange(mLocked.orientedRanges.x);
+ info->addMotionRange(mLocked.orientedRanges.y);
if (mLocked.orientedRanges.havePressure) {
- info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE,
- mLocked.orientedRanges.pressure);
+ info->addMotionRange(mLocked.orientedRanges.pressure);
}
if (mLocked.orientedRanges.haveSize) {
- info->addMotionRange(AMOTION_EVENT_AXIS_SIZE,
- mLocked.orientedRanges.size);
+ info->addMotionRange(mLocked.orientedRanges.size);
}
if (mLocked.orientedRanges.haveTouchSize) {
- info->addMotionRange(AMOTION_EVENT_AXIS_TOUCH_MAJOR,
- mLocked.orientedRanges.touchMajor);
- info->addMotionRange(AMOTION_EVENT_AXIS_TOUCH_MINOR,
- mLocked.orientedRanges.touchMinor);
+ info->addMotionRange(mLocked.orientedRanges.touchMajor);
+ info->addMotionRange(mLocked.orientedRanges.touchMinor);
}
if (mLocked.orientedRanges.haveToolSize) {
- info->addMotionRange(AMOTION_EVENT_AXIS_TOOL_MAJOR,
- mLocked.orientedRanges.toolMajor);
- info->addMotionRange(AMOTION_EVENT_AXIS_TOOL_MINOR,
- mLocked.orientedRanges.toolMinor);
+ info->addMotionRange(mLocked.orientedRanges.toolMajor);
+ info->addMotionRange(mLocked.orientedRanges.toolMinor);
}
if (mLocked.orientedRanges.haveOrientation) {
- info->addMotionRange(AMOTION_EVENT_AXIS_ORIENTATION,
- mLocked.orientedRanges.orientation);
+ info->addMotionRange(mLocked.orientedRanges.orientation);
}
} // release lock
}
@@ -1555,6 +1591,7 @@
dumpRawAxes(dump);
dumpCalibration(dump);
dumpSurfaceLocked(dump);
+
dump.appendFormat(INDENT3 "Translation and Scaling Factors:\n");
dump.appendFormat(INDENT4 "XScale: %0.3f\n", mLocked.xScale);
dump.appendFormat(INDENT4 "YScale: %0.3f\n", mLocked.yScale);
@@ -1567,7 +1604,10 @@
dump.appendFormat(INDENT4 "ToolSizeAreaBias: %0.3f\n", mLocked.toolSizeAreaBias);
dump.appendFormat(INDENT4 "PressureScale: %0.3f\n", mLocked.pressureScale);
dump.appendFormat(INDENT4 "SizeScale: %0.3f\n", mLocked.sizeScale);
- dump.appendFormat(INDENT4 "OrientationSCale: %0.3f\n", mLocked.orientationScale);
+ dump.appendFormat(INDENT4 "OrientationScale: %0.3f\n", mLocked.orientationScale);
+
+ dump.appendFormat(INDENT3 "Last Touch:\n");
+ dump.appendFormat(INDENT4 "Pointer Count: %d\n", mLastTouch.pointerCount);
} // release lock
}
@@ -1601,10 +1641,10 @@
// Configure sources.
switch (mParameters.deviceType) {
case Parameters::DEVICE_TYPE_TOUCH_SCREEN:
- mSources = AINPUT_SOURCE_TOUCHSCREEN;
+ mTouchSource = AINPUT_SOURCE_TOUCHSCREEN;
break;
case Parameters::DEVICE_TYPE_TOUCH_PAD:
- mSources = AINPUT_SOURCE_TOUCHPAD;
+ mTouchSource = AINPUT_SOURCE_TOUCHPAD;
break;
default:
assert(false);
@@ -1637,17 +1677,20 @@
deviceTypeString)) {
if (deviceTypeString == "touchScreen") {
mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
- } else if (deviceTypeString != "touchPad") {
+ } else if (deviceTypeString == "touchPad") {
+ mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;
+ } else {
LOGW("Invalid value for touch.deviceType: '%s'", deviceTypeString.string());
}
}
- bool isTouchScreen = mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN;
- mParameters.orientationAware = isTouchScreen;
+ mParameters.orientationAware = mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN;
getDevice()->getConfiguration().tryGetProperty(String8("touch.orientationAware"),
mParameters.orientationAware);
- mParameters.associatedDisplayId = mParameters.orientationAware || isTouchScreen ? 0 : -1;
+ mParameters.associatedDisplayId = mParameters.orientationAware
+ || mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
+ ? 0 : -1;
}
void TouchInputMapper::dumpParameters(String8& dump) {
@@ -1714,15 +1757,23 @@
int32_t height = mRawAxes.y.maxValue - mRawAxes.y.minValue + 1;
if (mParameters.associatedDisplayId >= 0) {
- bool wantSize = mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN;
- bool wantOrientation = mParameters.orientationAware;
-
// Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
if (! getPolicy()->getDisplayInfo(mParameters.associatedDisplayId,
- wantSize ? &width : NULL, wantSize ? &height : NULL,
- wantOrientation ? &orientation : NULL)) {
+ &mLocked.associatedDisplayWidth, &mLocked.associatedDisplayHeight,
+ &mLocked.associatedDisplayOrientation)) {
return false;
}
+
+ // A touch screen inherits the dimensions of the display.
+ if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN) {
+ width = mLocked.associatedDisplayWidth;
+ height = mLocked.associatedDisplayHeight;
+ }
+
+ // The device inherits the orientation of the display if it is orientation aware.
+ if (mParameters.orientationAware) {
+ orientation = mLocked.associatedDisplayOrientation;
+ }
}
bool orientationChanged = mLocked.surfaceOrientation != orientation;
@@ -1732,7 +1783,7 @@
bool sizeChanged = mLocked.surfaceWidth != width || mLocked.surfaceHeight != height;
if (sizeChanged) {
- LOGI("Device reconfigured: id=%d, name='%s', display size is now %dx%d",
+ LOGI("Device reconfigured: id=%d, name='%s', surface size is now %dx%d",
getDeviceId(), getDeviceName().string(), width, height);
mLocked.surfaceWidth = width;
@@ -1744,6 +1795,11 @@
mLocked.xPrecision = 1.0f / mLocked.xScale;
mLocked.yPrecision = 1.0f / mLocked.yScale;
+ mLocked.orientedRanges.x.axis = AMOTION_EVENT_AXIS_X;
+ mLocked.orientedRanges.x.source = mTouchSource;
+ mLocked.orientedRanges.y.axis = AMOTION_EVENT_AXIS_Y;
+ mLocked.orientedRanges.y.source = mTouchSource;
+
configureVirtualKeysLocked();
// Scale factor for terms that are not oriented in a particular axis.
@@ -1757,11 +1813,16 @@
// TouchMajor and TouchMinor factors.
if (mCalibration.touchSizeCalibration != Calibration::TOUCH_SIZE_CALIBRATION_NONE) {
mLocked.orientedRanges.haveTouchSize = true;
+
+ mLocked.orientedRanges.touchMajor.axis = AMOTION_EVENT_AXIS_TOUCH_MAJOR;
+ mLocked.orientedRanges.touchMajor.source = mTouchSource;
mLocked.orientedRanges.touchMajor.min = 0;
mLocked.orientedRanges.touchMajor.max = diagonalSize;
mLocked.orientedRanges.touchMajor.flat = 0;
mLocked.orientedRanges.touchMajor.fuzz = 0;
+
mLocked.orientedRanges.touchMinor = mLocked.orientedRanges.touchMajor;
+ mLocked.orientedRanges.touchMinor.axis = AMOTION_EVENT_AXIS_TOUCH_MINOR;
}
// ToolMajor and ToolMinor factors.
@@ -1805,11 +1866,16 @@
}
mLocked.orientedRanges.haveToolSize = true;
+
+ mLocked.orientedRanges.toolMajor.axis = AMOTION_EVENT_AXIS_TOOL_MAJOR;
+ mLocked.orientedRanges.toolMajor.source = mTouchSource;
mLocked.orientedRanges.toolMajor.min = 0;
mLocked.orientedRanges.toolMajor.max = diagonalSize;
mLocked.orientedRanges.toolMajor.flat = 0;
mLocked.orientedRanges.toolMajor.fuzz = 0;
+
mLocked.orientedRanges.toolMinor = mLocked.orientedRanges.toolMajor;
+ mLocked.orientedRanges.toolMinor.axis = AMOTION_EVENT_AXIS_TOOL_MINOR;
}
// Pressure factors.
@@ -1838,6 +1904,9 @@
}
mLocked.orientedRanges.havePressure = true;
+
+ mLocked.orientedRanges.pressure.axis = AMOTION_EVENT_AXIS_PRESSURE;
+ mLocked.orientedRanges.pressure.source = mTouchSource;
mLocked.orientedRanges.pressure.min = 0;
mLocked.orientedRanges.pressure.max = 1.0;
mLocked.orientedRanges.pressure.flat = 0;
@@ -1854,6 +1923,9 @@
}
mLocked.orientedRanges.haveSize = true;
+
+ mLocked.orientedRanges.size.axis = AMOTION_EVENT_AXIS_SIZE;
+ mLocked.orientedRanges.size.source = mTouchSource;
mLocked.orientedRanges.size.min = 0;
mLocked.orientedRanges.size.max = 1.0;
mLocked.orientedRanges.size.flat = 0;
@@ -1870,6 +1942,8 @@
}
}
+ mLocked.orientedRanges.orientation.axis = AMOTION_EVENT_AXIS_ORIENTATION;
+ mLocked.orientedRanges.orientation.source = mTouchSource;
mLocked.orientedRanges.orientation.min = - M_PI_2;
mLocked.orientedRanges.orientation.max = M_PI_2;
mLocked.orientedRanges.orientation.flat = 0;
@@ -2384,8 +2458,10 @@
uint32_t policyFlags = 0;
if (mLastTouch.pointerCount == 0 && mCurrentTouch.pointerCount != 0) {
- // Hide the pointer on an initial down.
- getContext()->fadePointer();
+ if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN) {
+ // If this is a touch screen, hide the pointer on an initial down.
+ getContext()->fadePointer();
+ }
// Initial downs on external touch devices should wake the device.
// We don't do this for internal touch screens to prevent them from waking
@@ -2399,7 +2475,7 @@
// Process touches and virtual keys.
TouchResult touchResult = consumeOffScreenTouches(when, policyFlags);
if (touchResult == DISPATCH_TOUCH) {
- detectGestures(when);
+ suppressSwipeOntoVirtualKeys(when);
dispatchTouches(when, policyFlags);
}
@@ -2526,7 +2602,7 @@
return touchResult;
}
-void TouchInputMapper::detectGestures(nsecs_t when) {
+void TouchInputMapper::suppressSwipeOntoVirtualKeys(nsecs_t when) {
// Disable all virtual key touches that happen within a short time interval of the
// most recent touch. The idea is to filter out stray virtual key presses when
// interacting with the touch screen.
@@ -2651,7 +2727,7 @@
AutoMutex _l(mLock);
// Walk through the the active pointers and map touch screen coordinates (TouchData) into
- // display coordinates (PointerCoords) and adjust for display orientation.
+ // display or surface coordinates (PointerCoords) and adjust for display orientation.
for (uint32_t outIndex = 0; ! idBits.isEmpty(); outIndex++) {
uint32_t id = idBits.firstMarkedBit();
idBits.clearBit(id);
@@ -2872,7 +2948,7 @@
yPrecision = mLocked.orientedYPrecision;
} // release lock
- getDispatcher()->notifyMotion(when, getDeviceId(), mSources, policyFlags,
+ getDispatcher()->notifyMotion(when, getDeviceId(), mTouchSource, policyFlags,
motionEventAction, 0, getContext()->getGlobalMetaState(), motionEventEdgeFlags,
pointerCount, pointerIds, pointerCoords,
xPrecision, yPrecision, mDownTime);
@@ -3863,7 +3939,12 @@
for (size_t i = 0; i < mAxes.size(); i++) {
const Axis& axis = mAxes.valueAt(i);
- info->addMotionRange(axis.axis, axis.min, axis.max, axis.flat, axis.fuzz);
+ info->addMotionRange(axis.axisInfo.axis, AINPUT_SOURCE_JOYSTICK,
+ axis.min, axis.max, axis.flat, axis.fuzz);
+ if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
+ info->addMotionRange(axis.axisInfo.highAxis, AINPUT_SOURCE_JOYSTICK,
+ axis.min, axis.max, axis.flat, axis.fuzz);
+ }
}
}
@@ -3874,18 +3955,29 @@
size_t numAxes = mAxes.size();
for (size_t i = 0; i < numAxes; i++) {
const Axis& axis = mAxes.valueAt(i);
- const char* label = getAxisLabel(axis.axis);
- char name[32];
+ const char* label = getAxisLabel(axis.axisInfo.axis);
if (label) {
- strncpy(name, label, sizeof(name));
- name[sizeof(name) - 1] = '\0';
+ dump.appendFormat(INDENT4 "%s", label);
} else {
- snprintf(name, sizeof(name), "%d", axis.axis);
+ dump.appendFormat(INDENT4 "%d", axis.axisInfo.axis);
}
- dump.appendFormat(INDENT4 "%s: min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f, "
- "scale=%0.3f, offset=%0.3f\n",
- name, axis.min, axis.max, axis.flat, axis.fuzz,
- axis.scale, axis.offset);
+ if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
+ label = getAxisLabel(axis.axisInfo.highAxis);
+ if (label) {
+ dump.appendFormat(" / %s (split at %d)", label, axis.axisInfo.splitValue);
+ } else {
+ dump.appendFormat(" / %d (split at %d)", axis.axisInfo.highAxis,
+ axis.axisInfo.splitValue);
+ }
+ } else if (axis.axisInfo.mode == AxisInfo::MODE_INVERT) {
+ dump.append(" (invert)");
+ }
+
+ dump.appendFormat(": min=%0.5f, max=%0.5f, flat=%0.5f, fuzz=%0.5f\n",
+ axis.min, axis.max, axis.flat, axis.fuzz);
+ dump.appendFormat(INDENT4 " scale=%0.5f, offset=%0.5f, "
+ "highScale=%0.5f, highOffset=%0.5f\n",
+ axis.scale, axis.offset, axis.highScale, axis.highOffset);
dump.appendFormat(INDENT4 " rawAxis=%d, rawMin=%d, rawMax=%d, rawFlat=%d, rawFuzz=%d\n",
mAxes.keyAt(i), axis.rawAxisInfo.minValue, axis.rawAxisInfo.maxValue,
axis.rawAxisInfo.flat, axis.rawAxisInfo.fuzz);
@@ -3900,25 +3992,38 @@
RawAbsoluteAxisInfo rawAxisInfo;
getEventHub()->getAbsoluteAxisInfo(getDeviceId(), abs, &rawAxisInfo);
if (rawAxisInfo.valid) {
- int32_t axisId;
- bool explicitlyMapped = !getEventHub()->mapAxis(getDeviceId(), abs, &axisId);
+ // Map axis.
+ AxisInfo axisInfo;
+ bool explicitlyMapped = !getEventHub()->mapAxis(getDeviceId(), abs, &axisInfo);
if (!explicitlyMapped) {
// Axis is not explicitly mapped, will choose a generic axis later.
- axisId = -1;
+ axisInfo.mode = AxisInfo::MODE_NORMAL;
+ axisInfo.axis = -1;
}
+ // Apply flat override.
+ int32_t rawFlat = axisInfo.flatOverride < 0
+ ? rawAxisInfo.flat : axisInfo.flatOverride;
+
+ // Calculate scaling factors and limits.
Axis axis;
- if (isCenteredAxis(axisId)) {
+ if (axisInfo.mode == AxisInfo::MODE_SPLIT) {
+ float scale = 1.0f / (axisInfo.splitValue - rawAxisInfo.minValue);
+ float highScale = 1.0f / (rawAxisInfo.maxValue - axisInfo.splitValue);
+ axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
+ scale, 0.0f, highScale, 0.0f,
+ 0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale);
+ } else if (isCenteredAxis(axisInfo.axis)) {
float scale = 2.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
float offset = avg(rawAxisInfo.minValue, rawAxisInfo.maxValue) * -scale;
- axis.initialize(rawAxisInfo, axisId, explicitlyMapped,
- scale, offset, -1.0f, 1.0f,
- rawAxisInfo.flat * scale, rawAxisInfo.fuzz * scale);
+ axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
+ scale, offset, scale, offset,
+ -1.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale);
} else {
float scale = 1.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
- axis.initialize(rawAxisInfo, axisId, explicitlyMapped,
- scale, 0.0f, 0.0f, 1.0f,
- rawAxisInfo.flat * scale, rawAxisInfo.fuzz * scale);
+ axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
+ scale, 0.0f, scale, 0.0f,
+ 0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale);
}
// To eliminate noise while the joystick is at rest, filter out small variations
@@ -3943,14 +4048,14 @@
size_t numAxes = mAxes.size();
for (size_t i = 0; i < numAxes; i++) {
Axis& axis = mAxes.editValueAt(i);
- if (axis.axis < 0) {
+ if (axis.axisInfo.axis < 0) {
while (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16
&& haveAxis(nextGenericAxisId)) {
nextGenericAxisId += 1;
}
if (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16) {
- axis.axis = nextGenericAxisId;
+ axis.axisInfo.axis = nextGenericAxisId;
nextGenericAxisId += 1;
} else {
LOGI("Ignoring joystick '%s' axis %d because all of the generic axis ids "
@@ -3963,10 +4068,13 @@
}
}
-bool JoystickInputMapper::haveAxis(int32_t axis) {
+bool JoystickInputMapper::haveAxis(int32_t axisId) {
size_t numAxes = mAxes.size();
for (size_t i = 0; i < numAxes; i++) {
- if (mAxes.valueAt(i).axis == axis) {
+ const Axis& axis = mAxes.valueAt(i);
+ if (axis.axisInfo.axis == axisId
+ || (axis.axisInfo.mode == AxisInfo::MODE_SPLIT
+ && axis.axisInfo.highAxis == axisId)) {
return true;
}
}
@@ -3996,6 +4104,8 @@
case AMOTION_EVENT_AXIS_HAT_X:
case AMOTION_EVENT_AXIS_HAT_Y:
case AMOTION_EVENT_AXIS_ORIENTATION:
+ case AMOTION_EVENT_AXIS_RUDDER:
+ case AMOTION_EVENT_AXIS_WHEEL:
return true;
default:
return false;
@@ -4009,7 +4119,7 @@
size_t numAxes = mAxes.size();
for (size_t i = 0; i < numAxes; i++) {
Axis& axis = mAxes.editValueAt(i);
- axis.newValue = 0;
+ axis.resetValue();
}
sync(when, true /*force*/);
@@ -4023,10 +4133,34 @@
ssize_t index = mAxes.indexOfKey(rawEvent->scanCode);
if (index >= 0) {
Axis& axis = mAxes.editValueAt(index);
- float newValue = rawEvent->value * axis.scale + axis.offset;
- if (newValue != axis.newValue) {
- axis.newValue = newValue;
+ float newValue, highNewValue;
+ switch (axis.axisInfo.mode) {
+ case AxisInfo::MODE_INVERT:
+ newValue = (axis.rawAxisInfo.maxValue - rawEvent->value)
+ * axis.scale + axis.offset;
+ highNewValue = 0.0f;
+ break;
+ case AxisInfo::MODE_SPLIT:
+ if (rawEvent->value < axis.axisInfo.splitValue) {
+ newValue = (axis.axisInfo.splitValue - rawEvent->value)
+ * axis.scale + axis.offset;
+ highNewValue = 0.0f;
+ } else if (rawEvent->value > axis.axisInfo.splitValue) {
+ newValue = 0.0f;
+ highNewValue = (rawEvent->value - axis.axisInfo.splitValue)
+ * axis.highScale + axis.highOffset;
+ } else {
+ newValue = 0.0f;
+ highNewValue = 0.0f;
+ }
+ break;
+ default:
+ newValue = rawEvent->value * axis.scale + axis.offset;
+ highNewValue = 0.0f;
+ break;
}
+ axis.newValue = newValue;
+ axis.highNewValue = highNewValue;
}
break;
}
@@ -4042,7 +4176,7 @@
}
void JoystickInputMapper::sync(nsecs_t when, bool force) {
- if (!force && !haveAxesChangedSignificantly()) {
+ if (!filterAxes(force)) {
return;
}
@@ -4053,9 +4187,11 @@
size_t numAxes = mAxes.size();
for (size_t i = 0; i < numAxes; i++) {
- Axis& axis = mAxes.editValueAt(i);
- pointerCoords.setAxisValue(axis.axis, axis.newValue);
- axis.oldValue = axis.newValue;
+ const Axis& axis = mAxes.valueAt(i);
+ pointerCoords.setAxisValue(axis.axisInfo.axis, axis.currentValue);
+ if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
+ pointerCoords.setAxisValue(axis.axisInfo.highAxis, axis.highCurrentValue);
+ }
}
// Moving a joystick axis should not wake the devide because joysticks can
@@ -4070,12 +4206,49 @@
1, &pointerId, &pointerCoords, 0, 0, 0);
}
-bool JoystickInputMapper::haveAxesChangedSignificantly() {
+bool JoystickInputMapper::filterAxes(bool force) {
+ bool atLeastOneSignificantChange = force;
size_t numAxes = mAxes.size();
for (size_t i = 0; i < numAxes; i++) {
- const Axis& axis = mAxes.valueAt(i);
- if (axis.newValue != axis.oldValue
- && fabs(axis.newValue - axis.oldValue) > axis.filter) {
+ Axis& axis = mAxes.editValueAt(i);
+ if (force || hasValueChangedSignificantly(axis.filter,
+ axis.newValue, axis.currentValue, axis.min, axis.max)) {
+ axis.currentValue = axis.newValue;
+ atLeastOneSignificantChange = true;
+ }
+ if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
+ if (force || hasValueChangedSignificantly(axis.filter,
+ axis.highNewValue, axis.highCurrentValue, axis.min, axis.max)) {
+ axis.highCurrentValue = axis.highNewValue;
+ atLeastOneSignificantChange = true;
+ }
+ }
+ }
+ return atLeastOneSignificantChange;
+}
+
+bool JoystickInputMapper::hasValueChangedSignificantly(
+ float filter, float newValue, float currentValue, float min, float max) {
+ if (newValue != currentValue) {
+ // Filter out small changes in value unless the value is converging on the axis
+ // bounds or center point. This is intended to reduce the amount of information
+ // sent to applications by particularly noisy joysticks (such as PS3).
+ if (fabs(newValue - currentValue) > filter
+ || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, min)
+ || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, max)
+ || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, 0)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool JoystickInputMapper::hasMovedNearerToValueWithinFilteredRange(
+ float filter, float newValue, float currentValue, float thresholdValue) {
+ float newDistance = fabs(newValue - thresholdValue);
+ if (newDistance < filter) {
+ float oldDistance = fabs(currentValue - thresholdValue);
+ if (newDistance < oldDistance) {
return true;
}
}
diff --git a/services/input/InputReader.h b/services/input/InputReader.h
index 9b79690..68002ca 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -389,7 +389,7 @@
class KeyboardInputMapper : public InputMapper {
public:
- KeyboardInputMapper(InputDevice* device, uint32_t sources, int32_t keyboardType);
+ KeyboardInputMapper(InputDevice* device, uint32_t source, int32_t keyboardType);
virtual ~KeyboardInputMapper();
virtual uint32_t getSources();
@@ -414,7 +414,7 @@
int32_t scanCode;
};
- uint32_t mSources;
+ uint32_t mSource;
int32_t mKeyboardType;
// Immutable configuration parameters.
@@ -493,7 +493,7 @@
struct Accumulator {
enum {
- FIELD_BTN_MOUSE = 1,
+ FIELD_BUTTONS = 1,
FIELD_REL_X = 2,
FIELD_REL_Y = 4,
FIELD_REL_WHEEL = 8,
@@ -502,7 +502,9 @@
uint32_t fields;
- bool btnMouse;
+ uint32_t buttonDown;
+ uint32_t buttonUp;
+
int32_t relX;
int32_t relY;
int32_t relWheel;
@@ -513,7 +515,7 @@
}
} mAccumulator;
- int32_t mSources;
+ int32_t mSource;
float mXScale;
float mYScale;
float mXPrecision;
@@ -527,7 +529,7 @@
sp<PointerControllerInterface> mPointerController;
struct LockedState {
- bool down;
+ uint32_t buttonState;
nsecs_t downTime;
} mLocked;
@@ -629,7 +631,7 @@
};
// Input sources supported by the device.
- int32_t mSources;
+ uint32_t mTouchSource; // sources when reporting touch data
// Immutable configuration parameters.
struct Parameters {
@@ -745,6 +747,10 @@
int32_t surfaceOrientation;
int32_t surfaceWidth, surfaceHeight;
+ // The associated display orientation and width and height set by configureSurfaceLocked().
+ int32_t associatedDisplayOrientation;
+ int32_t associatedDisplayWidth, associatedDisplayHeight;
+
// Translation and scaling factors, orientation-independent.
float xScale;
float xPrecision;
@@ -870,7 +876,7 @@
void dispatchTouch(nsecs_t when, uint32_t policyFlags, TouchData* touch,
BitSet32 idBits, uint32_t changedId, uint32_t pointerCount,
int32_t motionEventAction);
- void detectGestures(nsecs_t when);
+ void suppressSwipeOntoVirtualKeys(nsecs_t when);
bool isPointInsideSurfaceLocked(int32_t x, int32_t y);
const VirtualKey* findVirtualKeyHitLocked(int32_t x, int32_t y);
@@ -900,7 +906,7 @@
FIELD_ABS_X = 2,
FIELD_ABS_Y = 4,
FIELD_ABS_PRESSURE = 8,
- FIELD_ABS_TOOL_WIDTH = 16
+ FIELD_ABS_TOOL_WIDTH = 16,
};
uint32_t fields;
@@ -999,38 +1005,50 @@
private:
struct Axis {
RawAbsoluteAxisInfo rawAxisInfo;
+ AxisInfo axisInfo;
- int32_t axis; // axis id
bool explicitlyMapped; // true if the axis was explicitly assigned an axis id
float scale; // scale factor from raw to normalized values
float offset; // offset to add after scaling for normalization
+ float highScale; // scale factor from raw to normalized values of high split
+ float highOffset; // offset to add after scaling for normalization of high split
float min; // normalized inclusive minimum
float max; // normalized inclusive maximum
float flat; // normalized flat region size
float fuzz; // normalized error tolerance
- float oldValue; // previous value
- float newValue; // most recent value
-
float filter; // filter out small variations of this size
+ float currentValue; // current value
+ float newValue; // most recent value
+ float highCurrentValue; // current value of high split
+ float highNewValue; // most recent value of high split
- void initialize(const RawAbsoluteAxisInfo& rawAxisInfo,
- int32_t axis, bool explicitlyMapped, float scale, float offset,
+ void initialize(const RawAbsoluteAxisInfo& rawAxisInfo, const AxisInfo& axisInfo,
+ bool explicitlyMapped, float scale, float offset,
+ float highScale, float highOffset,
float min, float max, float flat, float fuzz) {
this->rawAxisInfo = rawAxisInfo;
- this->axis = axis;
+ this->axisInfo = axisInfo;
this->explicitlyMapped = explicitlyMapped;
this->scale = scale;
this->offset = offset;
+ this->highScale = highScale;
+ this->highOffset = highOffset;
this->min = min;
this->max = max;
this->flat = flat;
this->fuzz = fuzz;
this->filter = 0;
- this->oldValue = 0;
+ resetValue();
+ }
+
+ void resetValue() {
+ this->currentValue = 0;
this->newValue = 0;
+ this->highCurrentValue = 0;
+ this->highNewValue = 0;
}
};
@@ -1039,9 +1057,14 @@
void sync(nsecs_t when, bool force);
- bool haveAxis(int32_t axis);
+ bool haveAxis(int32_t axisId);
void pruneAxes(bool ignoreExplicitlyMappedAxes);
- bool haveAxesChangedSignificantly();
+ bool filterAxes(bool force);
+
+ static bool hasValueChangedSignificantly(float filter,
+ float newValue, float currentValue, float min, float max);
+ static bool hasMovedNearerToValueWithinFilteredRange(float filter,
+ float newValue, float currentValue, float thresholdValue);
static bool isCenteredAxis(int32_t axis);
};
diff --git a/services/input/PointerController.h b/services/input/PointerController.h
index e28dd7d..e1dab5c 100644
--- a/services/input/PointerController.h
+++ b/services/input/PointerController.h
@@ -31,10 +31,6 @@
namespace android {
-enum {
- POINTER_BUTTON_1 = 1 << 0,
-};
-
/**
* Interface for tracking a single (mouse) pointer.
*
diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp
index 1180b83..67a2e21 100644
--- a/services/input/tests/InputReader_test.cpp
+++ b/services/input/tests/InputReader_test.cpp
@@ -405,7 +405,8 @@
String8 name;
uint32_t classes;
PropertyMap configuration;
- KeyedVector<int, RawAbsoluteAxisInfo> axes;
+ KeyedVector<int, RawAbsoluteAxisInfo> absoluteAxes;
+ KeyedVector<int, bool> relativeAxes;
KeyedVector<int32_t, int32_t> keyCodeStates;
KeyedVector<int32_t, int32_t> scanCodeStates;
KeyedVector<int32_t, int32_t> switchStates;
@@ -460,7 +461,7 @@
device->configuration.addAll(configuration);
}
- void addAxis(int32_t deviceId, int axis,
+ void addAbsoluteAxis(int32_t deviceId, int axis,
int32_t minValue, int32_t maxValue, int flat, int fuzz) {
Device* device = getDevice(deviceId);
@@ -470,7 +471,12 @@
info.maxValue = maxValue;
info.flat = flat;
info.fuzz = fuzz;
- device->axes.add(axis, info);
+ device->absoluteAxes.add(axis, info);
+ }
+
+ void addRelativeAxis(int32_t deviceId, int32_t axis) {
+ Device* device = getDevice(deviceId);
+ device->relativeAxes.add(axis, true);
}
void setKeyCodeState(int32_t deviceId, int32_t keyCode, int32_t state) {
@@ -560,9 +566,9 @@
RawAbsoluteAxisInfo* outAxisInfo) const {
Device* device = getDevice(deviceId);
if (device) {
- ssize_t index = device->axes.indexOfKey(axis);
+ ssize_t index = device->absoluteAxes.indexOfKey(axis);
if (index >= 0) {
- *outAxisInfo = device->axes.valueAt(index);
+ *outAxisInfo = device->absoluteAxes.valueAt(index);
return OK;
}
}
@@ -570,6 +576,10 @@
}
virtual bool hasRelativeAxis(int32_t deviceId, int axis) const {
+ Device* device = getDevice(deviceId);
+ if (device) {
+ return device->relativeAxes.indexOfKey(axis) >= 0;
+ }
return false;
}
@@ -592,7 +602,7 @@
}
virtual status_t mapAxis(int32_t deviceId, int scancode,
- int32_t* outAxis) const {
+ AxisInfo* outAxisInfo) const {
return NAME_NOT_FOUND;
}
@@ -1487,13 +1497,15 @@
}
static void assertMotionRange(const InputDeviceInfo& info,
- int32_t rangeType, float min, float max, float flat, float fuzz) {
- const InputDeviceInfo::MotionRange* range = info.getMotionRange(rangeType);
- ASSERT_TRUE(range != NULL) << "Range: " << rangeType;
- ASSERT_NEAR(min, range->min, EPSILON) << "Range: " << rangeType;
- ASSERT_NEAR(max, range->max, EPSILON) << "Range: " << rangeType;
- ASSERT_NEAR(flat, range->flat, EPSILON) << "Range: " << rangeType;
- ASSERT_NEAR(fuzz, range->fuzz, EPSILON) << "Range: " << rangeType;
+ int32_t axis, uint32_t source, float min, float max, float flat, float fuzz) {
+ const InputDeviceInfo::MotionRange* range = info.getMotionRange(axis, source);
+ ASSERT_TRUE(range != NULL) << "Axis: " << axis << " Source: " << source;
+ ASSERT_EQ(axis, range->axis) << "Axis: " << axis << " Source: " << source;
+ ASSERT_EQ(source, range->source) << "Axis: " << axis << " Source: " << source;
+ ASSERT_NEAR(min, range->min, EPSILON) << "Axis: " << axis << " Source: " << source;
+ ASSERT_NEAR(max, range->max, EPSILON) << "Axis: " << axis << " Source: " << source;
+ ASSERT_NEAR(flat, range->flat, EPSILON) << "Axis: " << axis << " Source: " << source;
+ ASSERT_NEAR(fuzz, range->fuzz, EPSILON) << "Axis: " << axis << " Source: " << source;
}
static void assertPointerCoords(const PointerCoords& coords,
@@ -2001,10 +2013,10 @@
mapper->populateDeviceInfo(&info);
// Initially there may not be a valid motion range.
- ASSERT_EQ(NULL, info.getMotionRange(AINPUT_MOTION_RANGE_X));
- ASSERT_EQ(NULL, info.getMotionRange(AINPUT_MOTION_RANGE_Y));
- ASSERT_NO_FATAL_FAILURE(assertMotionRange(info, AINPUT_MOTION_RANGE_PRESSURE,
- 0.0f, 1.0f, 0.0f, 0.0f));
+ ASSERT_EQ(NULL, info.getMotionRange(AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_MOUSE));
+ ASSERT_EQ(NULL, info.getMotionRange(AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_MOUSE));
+ ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
+ AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_MOUSE, 0.0f, 1.0f, 0.0f, 0.0f));
// When the bounds are set, then there should be a valid motion range.
mFakePointerController->setBounds(1, 2, 800 - 1, 480 - 1);
@@ -2012,11 +2024,14 @@
InputDeviceInfo info2;
mapper->populateDeviceInfo(&info2);
- ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2, AINPUT_MOTION_RANGE_X,
+ ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
+ AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_MOUSE,
1, 800 - 1, 0.0f, 0.0f));
- ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2, AINPUT_MOTION_RANGE_Y,
+ ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
+ AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_MOUSE,
2, 480 - 1, 0.0f, 0.0f));
- ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2, AINPUT_MOTION_RANGE_PRESSURE,
+ ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
+ AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_MOUSE,
0.0f, 1.0f, 0.0f, 0.0f));
}
@@ -2028,11 +2043,14 @@
InputDeviceInfo info;
mapper->populateDeviceInfo(&info);
- ASSERT_NO_FATAL_FAILURE(assertMotionRange(info, AINPUT_MOTION_RANGE_X,
+ ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
+ AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_TRACKBALL,
-1.0f, 1.0f, 0.0f, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD));
- ASSERT_NO_FATAL_FAILURE(assertMotionRange(info, AINPUT_MOTION_RANGE_Y,
+ ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
+ AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_TRACKBALL,
-1.0f, 1.0f, 0.0f, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD));
- ASSERT_NO_FATAL_FAILURE(assertMotionRange(info, AINPUT_MOTION_RANGE_PRESSURE,
+ ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
+ AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_TRACKBALL,
0.0f, 1.0f, 0.0f, 0.0f));
}
@@ -2385,14 +2403,18 @@
void SingleTouchInputMapperTest::prepareAxes(int axes) {
if (axes & POSITION) {
- mFakeEventHub->addAxis(DEVICE_ID, ABS_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
- mFakeEventHub->addAxis(DEVICE_ID, ABS_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_X,
+ RAW_X_MIN, RAW_X_MAX, 0, 0);
+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_Y,
+ RAW_Y_MIN, RAW_Y_MAX, 0, 0);
}
if (axes & PRESSURE) {
- mFakeEventHub->addAxis(DEVICE_ID, ABS_PRESSURE, RAW_PRESSURE_MIN, RAW_PRESSURE_MAX, 0, 0);
+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_PRESSURE,
+ RAW_PRESSURE_MIN, RAW_PRESSURE_MAX, 0, 0);
}
if (axes & TOOL) {
- mFakeEventHub->addAxis(DEVICE_ID, ABS_TOOL_WIDTH, RAW_TOOL_MIN, RAW_TOOL_MAX, 0, 0);
+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_TOOL_WIDTH,
+ RAW_TOOL_MIN, RAW_TOOL_MAX, 0, 0);
}
}
@@ -3040,33 +3062,37 @@
void MultiTouchInputMapperTest::prepareAxes(int axes) {
if (axes & POSITION) {
- mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
- mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_POSITION_X,
+ RAW_X_MIN, RAW_X_MAX, 0, 0);
+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_POSITION_Y,
+ RAW_Y_MIN, RAW_Y_MAX, 0, 0);
}
if (axes & TOUCH) {
- mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_TOUCH_MAJOR, RAW_TOUCH_MIN, RAW_TOUCH_MAX, 0, 0);
+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TOUCH_MAJOR,
+ RAW_TOUCH_MIN, RAW_TOUCH_MAX, 0, 0);
if (axes & MINOR) {
- mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_TOUCH_MINOR,
+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TOUCH_MINOR,
RAW_TOUCH_MIN, RAW_TOUCH_MAX, 0, 0);
}
}
if (axes & TOOL) {
- mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_WIDTH_MAJOR, RAW_TOOL_MIN, RAW_TOOL_MAX, 0, 0);
+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_WIDTH_MAJOR,
+ RAW_TOOL_MIN, RAW_TOOL_MAX, 0, 0);
if (axes & MINOR) {
- mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_WIDTH_MINOR,
+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_WIDTH_MINOR,
RAW_TOOL_MAX, RAW_TOOL_MAX, 0, 0);
}
}
if (axes & ORIENTATION) {
- mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_ORIENTATION,
+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_ORIENTATION,
RAW_ORIENTATION_MIN, RAW_ORIENTATION_MAX, 0, 0);
}
if (axes & PRESSURE) {
- mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_PRESSURE,
+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_PRESSURE,
RAW_PRESSURE_MIN, RAW_PRESSURE_MAX, 0, 0);
}
if (axes & ID) {
- mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_TRACKING_ID,
+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TRACKING_ID,
RAW_ID_MIN, RAW_ID_MAX, 0, 0);
}
}
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index b7d0a8f..1ab22c0 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -24,6 +24,7 @@
import android.database.ContentObserver;
import android.net.ConnectivityManager;
import android.net.DummyDataStateTracker;
+import android.net.EthernetDataTracker;
import android.net.IConnectivityManager;
import android.net.LinkProperties;
import android.net.MobileDataStateTracker;
@@ -420,6 +421,10 @@
mNetTrackers[netType] = BluetoothTetheringDataTracker.getInstance();
mNetTrackers[netType].startMonitoring(context, mHandler);
break;
+ case ConnectivityManager.TYPE_ETHERNET:
+ mNetTrackers[netType] = EthernetDataTracker.getInstance();
+ mNetTrackers[netType].startMonitoring(context, mHandler);
+ break;
default:
loge("Trying to create a DataStateTracker for an unknown radio type " +
mNetAttributes[netType].mRadio);
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index adc49ae..d48cf5a 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -62,6 +62,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicBoolean;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -99,9 +100,6 @@
/* Chipset supports background scan */
private final boolean mBackgroundScanSupported;
- // true if the user enabled Wifi while in airplane mode
- private AtomicBoolean mAirplaneModeOverwridden = new AtomicBoolean(false);
-
private final LockList mLocks = new LockList();
// some wifi lock statistics
private int mFullHighPerfLocksAcquired;
@@ -144,6 +142,14 @@
private static final String ACTION_DEVICE_IDLE =
"com.android.server.WifiManager.action.DEVICE_IDLE";
+ private static final int WIFI_DISABLED = 0;
+ private static final int WIFI_ENABLED = 1;
+ /* Wifi enabled while in airplane mode */
+ private static final int WIFI_ENABLED_AIRPLANE_OVERRIDE = 2;
+
+ private AtomicInteger mWifiState = new AtomicInteger(WIFI_DISABLED);
+ private AtomicBoolean mAirplaneModeOn = new AtomicBoolean(false);
+
private boolean mIsReceiverRegistered = false;
@@ -229,6 +235,15 @@
}
break;
}
+ case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
+ if (msg.arg1 == AsyncChannel.STATUS_SEND_UNSUCCESSFUL) {
+ Slog.d(TAG, "Send failed, client connection lost");
+ } else {
+ Slog.d(TAG, "Client connection lost with reason: " + msg.arg1);
+ }
+ mClients.remove((AsyncChannel) msg.obj);
+ break;
+ }
case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: {
AsyncChannel ac = new AsyncChannel();
ac.connect(mContext, this, msg.replyTo);
@@ -338,11 +353,11 @@
new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- // clear our flag indicating the user has overwridden airplane mode
- mAirplaneModeOverwridden.set(false);
- // on airplane disable, restore Wifi if the saved state indicates so
- if (!isAirplaneModeOn() && testAndClearWifiSavedState()) {
- persistWifiEnabled(true);
+ mAirplaneModeOn.set(isAirplaneModeOn());
+ /* On airplane mode disable, restore wifi state if necessary */
+ if (!mAirplaneModeOn.get() && (testAndClearWifiSavedState() ||
+ mWifiState.get() == WIFI_ENABLED_AIRPLANE_OVERRIDE)) {
+ persistWifiEnabled(true);
}
updateWifiState();
}
@@ -402,9 +417,10 @@
* This function is used only at boot time
*/
public void checkAndStartWifi() {
- /* Start if Wi-Fi is enabled or the saved state indicates Wi-Fi was on */
- boolean wifiEnabled = !isAirplaneModeOn()
- && (getPersistedWifiEnabled() || testAndClearWifiSavedState());
+ mAirplaneModeOn.set(isAirplaneModeOn());
+ mWifiState.set(getPersistedWifiState());
+ /* Start if Wi-Fi should be enabled or the saved state indicates Wi-Fi was on */
+ boolean wifiEnabled = shouldWifiBeEnabled() || testAndClearWifiSavedState();
Slog.i(TAG, "WifiService starting up with Wi-Fi " +
(wifiEnabled ? "enabled" : "disabled"));
setWifiEnabled(wifiEnabled);
@@ -423,21 +439,39 @@
return (wifiSavedState == 1);
}
- private boolean getPersistedWifiEnabled() {
+ private int getPersistedWifiState() {
final ContentResolver cr = mContext.getContentResolver();
try {
- return Settings.Secure.getInt(cr, Settings.Secure.WIFI_ON) == 1;
+ return Settings.Secure.getInt(cr, Settings.Secure.WIFI_ON);
} catch (Settings.SettingNotFoundException e) {
- Settings.Secure.putInt(cr, Settings.Secure.WIFI_ON, 0);
- return false;
+ Settings.Secure.putInt(cr, Settings.Secure.WIFI_ON, WIFI_DISABLED);
+ return WIFI_DISABLED;
+ }
+ }
+
+ private boolean shouldWifiBeEnabled() {
+ if (mAirplaneModeOn.get()) {
+ return mWifiState.get() == WIFI_ENABLED_AIRPLANE_OVERRIDE;
+ } else {
+ return mWifiState.get() != WIFI_DISABLED;
}
}
private void persistWifiEnabled(boolean enabled) {
final ContentResolver cr = mContext.getContentResolver();
- Settings.Secure.putInt(cr, Settings.Secure.WIFI_ON, enabled ? 1 : 0);
+ if (enabled) {
+ if (isAirplaneModeOn() && isAirplaneToggleable()) {
+ mWifiState.set(WIFI_ENABLED_AIRPLANE_OVERRIDE);
+ } else {
+ mWifiState.set(WIFI_ENABLED);
+ }
+ } else {
+ mWifiState.set(WIFI_DISABLED);
+ }
+ Settings.Secure.putInt(cr, Settings.Secure.WIFI_ON, mWifiState.get());
}
+
/**
* see {@link android.net.wifi.WifiManager#pingSupplicant()}
* @return {@code true} if the operation succeeds, {@code false} otherwise
@@ -490,11 +524,6 @@
Slog.e(TAG, "Invoking mWifiStateMachine.setWifiEnabled\n");
}
- // set a flag if the user is enabling Wifi while in airplane mode
- if (enable && isAirplaneModeOn() && isAirplaneToggleable()) {
- mAirplaneModeOverwridden.set(true);
- }
-
if (enable) {
reportStartWorkSource();
}
@@ -1037,11 +1066,8 @@
}
private void updateWifiState() {
- boolean wifiEnabled = getPersistedWifiEnabled();
- boolean airplaneMode = isAirplaneModeOn() && !mAirplaneModeOverwridden.get();
boolean lockHeld = mLocks.hasLocks();
int strongestLockMode = WifiManager.WIFI_MODE_FULL;
- boolean wifiShouldBeEnabled = wifiEnabled && !airplaneMode;
boolean wifiShouldBeStarted = !mDeviceIdle || lockHeld;
if (lockHeld) {
@@ -1053,11 +1079,11 @@
}
/* Disable tethering when airplane mode is enabled */
- if (airplaneMode) {
+ if (mAirplaneModeOn.get()) {
mWifiStateMachine.setWifiApEnabled(null, false);
}
- if (wifiShouldBeEnabled) {
+ if (shouldWifiBeEnabled()) {
if (wifiShouldBeStarted) {
reportStartWorkSource();
mWifiStateMachine.setWifiEnabled(true);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 0fab964..267c76a 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -3151,6 +3151,9 @@
try {
pm.setPackageStoppedState(packageName, true);
} catch (RemoteException e) {
+ } catch (IllegalArgumentException e) {
+ Slog.w(TAG, "Failed trying to unstop package "
+ + packageName + ": " + e);
}
}
} finally {
@@ -5559,6 +5562,9 @@
AppGlobals.getPackageManager().setPackageStoppedState(
cpr.appInfo.packageName, false);
} catch (RemoteException e) {
+ } catch (IllegalArgumentException e) {
+ Slog.w(TAG, "Failed trying to unstop package "
+ + cpr.appInfo.packageName + ": " + e);
}
ProcessRecord proc = startProcessLocked(cpi.processName,
@@ -5840,6 +5846,9 @@
AppGlobals.getPackageManager().setPackageStoppedState(
info.packageName, false);
} catch (RemoteException e) {
+ } catch (IllegalArgumentException e) {
+ Slog.w(TAG, "Failed trying to unstop package "
+ + info.packageName + ": " + e);
}
if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
@@ -6673,8 +6682,10 @@
mProcessCrashTimes.remove(app.info.processName, app.info.uid);
app.removed = true;
removeProcessLocked(app, false);
+ mMainStack.resumeTopActivityLocked(null);
return false;
}
+ mMainStack.resumeTopActivityLocked(null);
} else {
ActivityRecord r = mMainStack.topRunningActivityLocked(null);
if (r.app == app) {
@@ -6780,7 +6791,7 @@
* @param crashInfo describing the exception
*/
public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
- ProcessRecord r = findAppProcess(app);
+ ProcessRecord r = findAppProcess(app, "Crash");
EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
app == null ? "system" : (r == null ? "unknown" : r.processName),
@@ -6799,7 +6810,10 @@
IBinder app,
int violationMask,
StrictMode.ViolationInfo info) {
- ProcessRecord r = findAppProcess(app);
+ ProcessRecord r = findAppProcess(app, "StrictMode");
+ if (r == null) {
+ return;
+ }
if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Integer stackFingerprint = info.hashCode();
@@ -6973,7 +6987,7 @@
*/
public boolean handleApplicationWtf(IBinder app, String tag,
ApplicationErrorReport.CrashInfo crashInfo) {
- ProcessRecord r = findAppProcess(app);
+ ProcessRecord r = findAppProcess(app, "WTF");
EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
app == null ? "system" : (r == null ? "unknown" : r.processName),
@@ -6995,7 +7009,7 @@
* @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
* @return the corresponding {@link ProcessRecord} object, or null if none could be found
*/
- private ProcessRecord findAppProcess(IBinder app) {
+ private ProcessRecord findAppProcess(IBinder app, String reason) {
if (app == null) {
return null;
}
@@ -7011,7 +7025,9 @@
}
}
- Slog.w(TAG, "Can't find mystery application: " + app);
+ Slog.w(TAG, "Can't find mystery application for " + reason
+ + " from pid=" + Binder.getCallingPid()
+ + " uid=" + Binder.getCallingUid() + ": " + app);
return null;
}
}
@@ -9396,6 +9412,9 @@
AppGlobals.getPackageManager().setPackageStoppedState(
r.packageName, false);
} catch (RemoteException e) {
+ } catch (IllegalArgumentException e) {
+ Slog.w(TAG, "Failed trying to unstop package "
+ + r.packageName + ": " + e);
}
final String appName = r.processName;
@@ -10297,6 +10316,9 @@
AppGlobals.getPackageManager().setPackageStoppedState(
app.packageName, false);
} catch (RemoteException e) {
+ } catch (IllegalArgumentException e) {
+ Slog.w(TAG, "Failed trying to unstop package "
+ + app.packageName + ": " + e);
}
BackupRecord r = new BackupRecord(ss, app, backupMode);
@@ -11625,6 +11647,9 @@
AppGlobals.getPackageManager().setPackageStoppedState(
r.curComponent.getPackageName(), false);
} catch (RemoteException e) {
+ } catch (IllegalArgumentException e) {
+ Slog.w(TAG, "Failed trying to unstop package "
+ + r.curComponent.getPackageName() + ": " + e);
}
// Is this receiver's application already running?
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 3a613bb..c087aecf 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -1299,6 +1299,9 @@
AppGlobals.getPackageManager().setPackageStoppedState(
next.packageName, false);
} catch (RemoteException e1) {
+ } catch (IllegalArgumentException e) {
+ Slog.w(TAG, "Failed trying to unstop package "
+ + next.packageName + ": " + e);
}
// We are starting up the next activity, so tell the window manager
diff --git a/services/java/com/android/server/usb/UsbDeviceSettingsManager.java b/services/java/com/android/server/usb/UsbDeviceSettingsManager.java
index 2f22fe1a..de0b114 100644
--- a/services/java/com/android/server/usb/UsbDeviceSettingsManager.java
+++ b/services/java/com/android/server/usb/UsbDeviceSettingsManager.java
@@ -16,11 +16,14 @@
package com.android.server.usb;
+import android.app.PendingIntent;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
@@ -33,7 +36,7 @@
import android.os.FileUtils;
import android.os.Process;
import android.util.Log;
-import android.util.SparseArray;
+import android.util.SparseBooleanArray;
import android.util.Xml;
import com.android.internal.content.PackageMonitor;
@@ -62,17 +65,18 @@
private static final File sSettingsFile = new File("/data/system/usb_device_manager.xml");
private final Context mContext;
+ private final PackageManager mPackageManager;
- // maps UID to user approved USB devices
- private final SparseArray<ArrayList<DeviceFilter>> mDevicePermissionMap =
- new SparseArray<ArrayList<DeviceFilter>>();
- // maps UID to user approved USB accessories
- private final SparseArray<ArrayList<AccessoryFilter>> mAccessoryPermissionMap =
- new SparseArray<ArrayList<AccessoryFilter>>();
+ // Temporary mapping USB device name to list of UIDs with permissions for the device
+ private final HashMap<String, SparseBooleanArray> mDevicePermissionMap =
+ new HashMap<String, SparseBooleanArray>();
+ // Temporary mapping UsbAccessory to list of UIDs with permissions for the accessory
+ private final HashMap<UsbAccessory, SparseBooleanArray> mAccessoryPermissionMap =
+ new HashMap<UsbAccessory, SparseBooleanArray>();
// Maps DeviceFilter to user preferred application package
private final HashMap<DeviceFilter, String> mDevicePreferenceMap =
new HashMap<DeviceFilter, String>();
- // Maps DeviceFilter to user preferred application package
+ // Maps AccessoryFilter to user preferred application package
private final HashMap<AccessoryFilter, String> mAccessoryPreferenceMap =
new HashMap<AccessoryFilter, String>();
@@ -185,6 +189,14 @@
return false;
}
+ public boolean matches(DeviceFilter f) {
+ if (mVendorId != -1 && f.mVendorId != mVendorId) return false;
+ if (mProductId != -1 && f.mProductId != mProductId) return false;
+
+ // check device class/subclass/protocol
+ return matches(f.mClass, f.mSubclass, f.mProtocol);
+ }
+
@Override
public boolean equals(Object obj) {
// can't compare if we have wildcard strings
@@ -234,22 +246,18 @@
public final String mManufacturer;
// USB accessory model (or null for unspecified)
public final String mModel;
- // USB accessory type (or null for unspecified)
- public final String mType;
// USB accessory version (or null for unspecified)
public final String mVersion;
- public AccessoryFilter(String manufacturer, String model, String type, String version) {
+ public AccessoryFilter(String manufacturer, String model, String version) {
mManufacturer = manufacturer;
mModel = model;
- mType = type;
mVersion = version;
}
public AccessoryFilter(UsbAccessory accessory) {
mManufacturer = accessory.getManufacturer();
mModel = accessory.getModel();
- mType = accessory.getType();
mVersion = accessory.getVersion();
}
@@ -257,7 +265,6 @@
throws XmlPullParserException, IOException {
String manufacturer = null;
String model = null;
- String type = null;
String version = null;
int count = parser.getAttributeCount();
@@ -269,13 +276,11 @@
manufacturer = value;
} else if ("model".equals(name)) {
model = value;
- } else if ("type".equals(name)) {
- type = value;
} else if ("version".equals(name)) {
version = value;
}
}
- return new AccessoryFilter(manufacturer, model, type, version);
+ return new AccessoryFilter(manufacturer, model, version);
}
public void write(XmlSerializer serializer)throws IOException {
@@ -286,9 +291,6 @@
if (mModel != null) {
serializer.attribute(null, "model", mModel);
}
- if (mType != null) {
- serializer.attribute(null, "type", mType);
- }
if (mVersion != null) {
serializer.attribute(null, "version", mVersion);
}
@@ -298,29 +300,33 @@
public boolean matches(UsbAccessory acc) {
if (mManufacturer != null && !acc.getManufacturer().equals(mManufacturer)) return false;
if (mModel != null && !acc.getModel().equals(mModel)) return false;
- if (mType != null && !acc.getType().equals(mType)) return false;
if (mVersion != null && !acc.getVersion().equals(mVersion)) return false;
return true;
}
+ public boolean matches(AccessoryFilter f) {
+ if (mManufacturer != null && !f.mManufacturer.equals(mManufacturer)) return false;
+ if (mModel != null && !f.mModel.equals(mModel)) return false;
+ if (mVersion != null && !f.mVersion.equals(mVersion)) return false;
+ return true;
+ }
+
@Override
public boolean equals(Object obj) {
// can't compare if we have wildcard strings
- if (mManufacturer == null || mModel == null || mType == null || mVersion == null) {
+ if (mManufacturer == null || mModel == null || mVersion == null) {
return false;
}
if (obj instanceof AccessoryFilter) {
AccessoryFilter filter = (AccessoryFilter)obj;
return (mManufacturer.equals(filter.mManufacturer) &&
mModel.equals(filter.mModel) &&
- mType.equals(filter.mType) &&
mVersion.equals(filter.mVersion));
}
if (obj instanceof UsbAccessory) {
UsbAccessory accessory = (UsbAccessory)obj;
return (mManufacturer.equals(accessory.getManufacturer()) &&
mModel.equals(accessory.getModel()) &&
- mType.equals(accessory.getType()) &&
mVersion.equals(accessory.getVersion()));
}
return false;
@@ -330,7 +336,6 @@
public int hashCode() {
return ((mManufacturer == null ? 0 : mManufacturer.hashCode()) ^
(mModel == null ? 0 : mModel.hashCode()) ^
- (mType == null ? 0 : mType.hashCode()) ^
(mVersion == null ? 0 : mVersion.hashCode()));
}
@@ -338,78 +343,35 @@
public String toString() {
return "AccessoryFilter[mManufacturer=\"" + mManufacturer +
"\", mModel=\"" + mModel +
- "\", mType=\"" + mType +
"\", mVersion=\"" + mVersion + "\"]";
}
}
private class MyPackageMonitor extends PackageMonitor {
- public void onPackageRemoved(String packageName, int uid) {
- synchronized (mLock) {
- // clear all activity preferences for the package
- if (clearPackageDefaultsLocked(packageName)) {
- writeSettingsLocked();
- }
- }
+
+ public void onPackageAdded(String packageName, int uid) {
+ handlePackageUpdate(packageName);
}
- public void onUidRemoved(int uid) {
- synchronized (mLock) {
- // clear all permissions for the UID
- if (clearUidDefaultsLocked(uid)) {
- writeSettingsLocked();
- }
- }
+ public void onPackageChanged(String packageName, int uid, String[] components) {
+ handlePackageUpdate(packageName);
+ }
+
+ public void onPackageRemoved(String packageName, int uid) {
+ clearDefaults(packageName);
}
}
MyPackageMonitor mPackageMonitor = new MyPackageMonitor();
public UsbDeviceSettingsManager(Context context) {
mContext = context;
+ mPackageManager = context.getPackageManager();
synchronized (mLock) {
readSettingsLocked();
}
mPackageMonitor.register(context, true);
}
- private void readDevicePermission(XmlPullParser parser)
- throws XmlPullParserException, IOException {
- int uid = -1;
- ArrayList<DeviceFilter> filters = new ArrayList<DeviceFilter>();
- int count = parser.getAttributeCount();
- for (int i = 0; i < count; i++) {
- if ("uid".equals(parser.getAttributeName(i))) {
- uid = Integer.parseInt(parser.getAttributeValue(i));
- break;
- }
- }
- XmlUtils.nextElement(parser);
- while ("usb-device".equals(parser.getName())) {
- filters.add(DeviceFilter.read(parser));
- XmlUtils.nextElement(parser);
- }
- mDevicePermissionMap.put(uid, filters);
- }
-
- private void readAccessoryPermission(XmlPullParser parser)
- throws XmlPullParserException, IOException {
- int uid = -1;
- ArrayList<AccessoryFilter> filters = new ArrayList<AccessoryFilter>();
- int count = parser.getAttributeCount();
- for (int i = 0; i < count; i++) {
- if ("uid".equals(parser.getAttributeName(i))) {
- uid = Integer.parseInt(parser.getAttributeValue(i));
- break;
- }
- }
- XmlUtils.nextElement(parser);
- while ("usb-accessory".equals(parser.getName())) {
- filters.add(AccessoryFilter.read(parser));
- XmlUtils.nextElement(parser);
- }
- mAccessoryPermissionMap.put(uid, filters);
- }
-
private void readPreference(XmlPullParser parser)
throws XmlPullParserException, IOException {
String packageName = null;
@@ -441,11 +403,7 @@
XmlUtils.nextElement(parser);
while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
String tagName = parser.getName();
- if ("device-permission".equals(tagName)) {
- readDevicePermission(parser);
- } else if ("accessory-permission".equals(tagName)) {
- readAccessoryPermission(parser);
- } else if ("preference".equals(tagName)) {
+ if ("preference".equals(tagName)) {
readPreference(parser);
} else {
XmlUtils.nextElement(parser);
@@ -478,32 +436,6 @@
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
serializer.startTag(null, "settings");
- int count = mDevicePermissionMap.size();
- for (int i = 0; i < count; i++) {
- int uid = mDevicePermissionMap.keyAt(i);
- ArrayList<DeviceFilter> filters = mDevicePermissionMap.valueAt(i);
- serializer.startTag(null, "device-permission");
- serializer.attribute(null, "uid", Integer.toString(uid));
- int filterCount = filters.size();
- for (int j = 0; j < filterCount; j++) {
- filters.get(j).write(serializer);
- }
- serializer.endTag(null, "device-permission");
- }
-
- count = mAccessoryPermissionMap.size();
- for (int i = 0; i < count; i++) {
- int uid = mAccessoryPermissionMap.keyAt(i);
- ArrayList<AccessoryFilter> filters = mAccessoryPermissionMap.valueAt(i);
- serializer.startTag(null, "accessory-permission");
- serializer.attribute(null, "uid", Integer.toString(uid));
- int filterCount = filters.size();
- for (int j = 0; j < filterCount; j++) {
- filters.get(j).write(serializer);
- }
- serializer.endTag(null, "accessory-permission");
- }
-
for (DeviceFilter filter : mDevicePreferenceMap.keySet()) {
serializer.startTag(null, "preference");
serializer.attribute(null, "package", mDevicePreferenceMap.get(filter));
@@ -535,11 +467,10 @@
private boolean packageMatchesLocked(ResolveInfo info, String metaDataName,
UsbDevice device, UsbAccessory accessory) {
ActivityInfo ai = info.activityInfo;
- PackageManager pm = mContext.getPackageManager();
XmlResourceParser parser = null;
try {
- parser = ai.loadXmlMetaData(pm, metaDataName);
+ parser = ai.loadXmlMetaData(mPackageManager, metaDataName);
if (parser == null) {
Log.w(TAG, "no meta-data for " + info);
return false;
@@ -572,8 +503,7 @@
private final ArrayList<ResolveInfo> getDeviceMatchesLocked(UsbDevice device, Intent intent) {
ArrayList<ResolveInfo> matches = new ArrayList<ResolveInfo>();
- PackageManager pm = mContext.getPackageManager();
- List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent,
+ List<ResolveInfo> resolveInfos = mPackageManager.queryIntentActivities(intent,
PackageManager.GET_META_DATA);
int count = resolveInfos.size();
for (int i = 0; i < count; i++) {
@@ -588,8 +518,7 @@
private final ArrayList<ResolveInfo> getAccessoryMatchesLocked(
UsbAccessory accessory, Intent intent) {
ArrayList<ResolveInfo> matches = new ArrayList<ResolveInfo>();
- PackageManager pm = mContext.getPackageManager();
- List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent,
+ List<ResolveInfo> resolveInfos = mPackageManager.queryIntentActivities(intent,
PackageManager.GET_META_DATA);
int count = resolveInfos.size();
for (int i = 0; i < count; i++) {
@@ -602,53 +531,26 @@
}
public void deviceAttached(UsbDevice device) {
- Intent deviceIntent = new Intent(UsbManager.ACTION_USB_DEVICE_ATTACHED);
- deviceIntent.putExtra(UsbManager.EXTRA_DEVICE, device);
- deviceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ Intent intent = new Intent(UsbManager.ACTION_USB_DEVICE_ATTACHED);
+ intent.putExtra(UsbManager.EXTRA_DEVICE, device);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ArrayList<ResolveInfo> matches;
String defaultPackage;
synchronized (mLock) {
- matches = getDeviceMatchesLocked(device, deviceIntent);
+ matches = getDeviceMatchesLocked(device, intent);
// Launch our default activity directly, if we have one.
// Otherwise we will start the UsbResolverActivity to allow the user to choose.
defaultPackage = mDevicePreferenceMap.get(new DeviceFilter(device));
}
- int count = matches.size();
- // don't show the resolver activity if there are no choices available
- if (count == 0) return;
-
- if (defaultPackage != null) {
- for (int i = 0; i < count; i++) {
- ResolveInfo rInfo = matches.get(i);
- if (rInfo.activityInfo != null &&
- defaultPackage.equals(rInfo.activityInfo.packageName)) {
- try {
- deviceIntent.setComponent(new ComponentName(
- defaultPackage, rInfo.activityInfo.name));
- mContext.startActivity(deviceIntent);
- } catch (ActivityNotFoundException e) {
- Log.e(TAG, "startActivity failed", e);
- }
- return;
- }
- }
- }
-
- Intent intent = new Intent(mContext, UsbResolverActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
- intent.putExtra(Intent.EXTRA_INTENT, deviceIntent);
- intent.putParcelableArrayListExtra(UsbResolverActivity.EXTRA_RESOLVE_INFOS, matches);
- try {
- mContext.startActivity(intent);
- } catch (ActivityNotFoundException e) {
- Log.w(TAG, "unable to start UsbResolverActivity");
- }
+ resolveActivity(intent, matches, defaultPackage, device, null);
}
public void deviceDetached(UsbDevice device) {
+ // clear temporary permissions for the device
+ mDevicePermissionMap.remove(device.getDeviceName());
+
Intent intent = new Intent(UsbManager.ACTION_USB_DEVICE_DETACHED);
intent.putExtra(UsbManager.EXTRA_DEVICE, device);
Log.d(TAG, "usbDeviceRemoved, sending " + intent);
@@ -656,93 +558,322 @@
}
public void accessoryAttached(UsbAccessory accessory) {
- Intent accessoryIntent = new Intent(UsbManager.ACTION_USB_ACCESSORY_ATTACHED);
- accessoryIntent.putExtra(UsbManager.EXTRA_ACCESSORY, accessory);
- accessoryIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ Intent intent = new Intent(UsbManager.ACTION_USB_ACCESSORY_ATTACHED);
+ intent.putExtra(UsbManager.EXTRA_ACCESSORY, accessory);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ArrayList<ResolveInfo> matches;
String defaultPackage;
synchronized (mLock) {
- matches = getAccessoryMatchesLocked(accessory, accessoryIntent);
+ matches = getAccessoryMatchesLocked(accessory, intent);
// Launch our default activity directly, if we have one.
// Otherwise we will start the UsbResolverActivity to allow the user to choose.
defaultPackage = mAccessoryPreferenceMap.get(new AccessoryFilter(accessory));
}
- int count = matches.size();
- // don't show the resolver activity if there are no choices available
- if (count == 0) return;
-
- if (defaultPackage != null) {
- for (int i = 0; i < count; i++) {
- ResolveInfo rInfo = matches.get(i);
- if (rInfo.activityInfo != null &&
- defaultPackage.equals(rInfo.activityInfo.packageName)) {
- try {
- accessoryIntent.setComponent(new ComponentName(
- defaultPackage, rInfo.activityInfo.name));
- mContext.startActivity(accessoryIntent);
- } catch (ActivityNotFoundException e) {
- Log.e(TAG, "startActivity failed", e);
- }
- return;
- }
- }
- }
-
- Intent intent = new Intent(mContext, UsbResolverActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
- intent.putExtra(Intent.EXTRA_INTENT, accessoryIntent);
- intent.putParcelableArrayListExtra(UsbResolverActivity.EXTRA_RESOLVE_INFOS, matches);
- try {
- mContext.startActivity(intent);
- } catch (ActivityNotFoundException e) {
- Log.w(TAG, "unable to start UsbResolverActivity");
- }
+ resolveActivity(intent, matches, defaultPackage, null, accessory);
}
public void accessoryDetached(UsbAccessory accessory) {
+ // clear temporary permissions for the accessory
+ mAccessoryPermissionMap.remove(accessory);
+
Intent intent = new Intent(
UsbManager.ACTION_USB_ACCESSORY_DETACHED);
intent.putExtra(UsbManager.EXTRA_ACCESSORY, accessory);
mContext.sendBroadcast(intent);
}
- public void checkPermission(UsbDevice device) {
- if (device == null) return;
- synchronized (mLock) {
- ArrayList<DeviceFilter> filterList = mDevicePermissionMap.get(Binder.getCallingUid());
- if (filterList != null) {
- int count = filterList.size();
- for (int i = 0; i < count; i++) {
- DeviceFilter filter = filterList.get(i);
- if (filter.equals(device)) {
- // permission allowed
- return;
+ private void resolveActivity(Intent intent, ArrayList<ResolveInfo> matches,
+ String defaultPackage, UsbDevice device, UsbAccessory accessory) {
+ int count = matches.size();
+
+ // don't show the resolver activity if there are no choices available
+ if (count == 0) {
+ if (accessory != null) {
+ String uri = accessory.getUri();
+ if (uri != null && uri.length() > 0) {
+ // display URI to user
+ // start UsbResolverActivity so user can choose an activity
+ Intent dialogIntent = new Intent();
+ dialogIntent.setClassName("com.android.systemui",
+ "com.android.systemui.usb.UsbAccessoryUriActivity");
+ dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ dialogIntent.putExtra(UsbManager.EXTRA_ACCESSORY, accessory);
+ dialogIntent.putExtra("uri", uri);
+ try {
+ mContext.startActivity(dialogIntent);
+ } catch (ActivityNotFoundException e) {
+ Log.e(TAG, "unable to start UsbAccessoryUriActivity");
}
}
}
+
+ // do nothing
+ return;
}
- throw new SecurityException("User has not given permission to device " + device);
+
+ ResolveInfo defaultRI = null;
+ if (count == 1 && defaultPackage == null) {
+ // Check to see if our single choice is on the system partition.
+ // If so, treat it as our default without calling UsbResolverActivity
+ ResolveInfo rInfo = matches.get(0);
+ if (rInfo.activityInfo != null &&
+ rInfo.activityInfo.applicationInfo != null &&
+ (rInfo.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+ defaultRI = rInfo;
+ }
+ }
+
+ if (defaultRI == null && defaultPackage != null) {
+ // look for default activity
+ for (int i = 0; i < count; i++) {
+ ResolveInfo rInfo = matches.get(i);
+ if (rInfo.activityInfo != null &&
+ defaultPackage.equals(rInfo.activityInfo.packageName)) {
+ defaultRI = rInfo;
+ break;
+ }
+ }
+ }
+
+ if (defaultRI != null) {
+ // grant permission for default activity
+ if (device != null) {
+ grantDevicePermission(device, defaultRI.activityInfo.applicationInfo.uid);
+ } else if (accessory != null) {
+ grantAccessoryPermission(accessory, defaultRI.activityInfo.applicationInfo.uid);
+ }
+
+ // start default activity directly
+ try {
+ intent.setComponent(
+ new ComponentName(defaultRI.activityInfo.packageName,
+ defaultRI.activityInfo.name));
+ mContext.startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ Log.e(TAG, "startActivity failed", e);
+ }
+ } else {
+ Intent resolverIntent = new Intent();
+ resolverIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ if (count == 1) {
+ // start UsbConfirmActivity if there is only one choice
+ resolverIntent.setClassName("com.android.systemui",
+ "com.android.systemui.usb.UsbConfirmActivity");
+ resolverIntent.putExtra("rinfo", matches.get(0));
+
+ if (device != null) {
+ resolverIntent.putExtra(UsbManager.EXTRA_DEVICE, device);
+ } else {
+ resolverIntent.putExtra(UsbManager.EXTRA_ACCESSORY, accessory);
+ }
+ } else {
+ // start UsbResolverActivity so user can choose an activity
+ resolverIntent.setClassName("com.android.systemui",
+ "com.android.systemui.usb.UsbResolverActivity");
+ resolverIntent.putParcelableArrayListExtra("rlist", matches);
+ resolverIntent.putExtra(Intent.EXTRA_INTENT, intent);
+ }
+ try {
+ mContext.startActivity(resolverIntent);
+ } catch (ActivityNotFoundException e) {
+ Log.e(TAG, "unable to start activity " + resolverIntent);
+ }
+ }
+ }
+
+ private boolean clearCompatibleMatchesLocked(String packageName, DeviceFilter filter) {
+ boolean changed = false;
+ for (DeviceFilter test : mDevicePreferenceMap.keySet()) {
+ if (filter.matches(test)) {
+ mDevicePreferenceMap.remove(test);
+ changed = true;
+ }
+ }
+ return changed;
+ }
+
+ private boolean clearCompatibleMatchesLocked(String packageName, AccessoryFilter filter) {
+ boolean changed = false;
+ for (AccessoryFilter test : mAccessoryPreferenceMap.keySet()) {
+ if (filter.matches(test)) {
+ mAccessoryPreferenceMap.remove(test);
+ changed = true;
+ }
+ }
+ return changed;
+ }
+
+ private boolean handlePackageUpdateLocked(String packageName, ActivityInfo aInfo,
+ String metaDataName) {
+ XmlResourceParser parser = null;
+ boolean changed = false;
+
+ try {
+ parser = aInfo.loadXmlMetaData(mPackageManager, metaDataName);
+ if (parser == null) return false;
+
+ XmlUtils.nextElement(parser);
+ while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
+ String tagName = parser.getName();
+ if ("usb-device".equals(tagName)) {
+ DeviceFilter filter = DeviceFilter.read(parser);
+ if (clearCompatibleMatchesLocked(packageName, filter)) {
+ changed = true;
+ }
+ }
+ else if ("usb-accessory".equals(tagName)) {
+ AccessoryFilter filter = AccessoryFilter.read(parser);
+ if (clearCompatibleMatchesLocked(packageName, filter)) {
+ changed = true;
+ }
+ }
+ XmlUtils.nextElement(parser);
+ }
+ } catch (Exception e) {
+ Log.w(TAG, "Unable to load component info " + aInfo.toString(), e);
+ } finally {
+ if (parser != null) parser.close();
+ }
+ return changed;
+ }
+
+ // Check to see if the package supports any USB devices or accessories.
+ // If so, clear any non-matching preferences for matching devices/accessories.
+ private void handlePackageUpdate(String packageName) {
+ synchronized (mLock) {
+ PackageInfo info;
+ boolean changed = false;
+
+ try {
+ info = mPackageManager.getPackageInfo(packageName,
+ PackageManager.GET_ACTIVITIES | PackageManager.GET_META_DATA);
+ } catch (NameNotFoundException e) {
+ Log.e(TAG, "handlePackageUpdate could not find package " + packageName, e);
+ return;
+ }
+
+ ActivityInfo[] activities = info.activities;
+ if (activities == null) return;
+ for (int i = 0; i < activities.length; i++) {
+ // check for meta-data, both for devices and accessories
+ if (handlePackageUpdateLocked(packageName, activities[i],
+ UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
+ changed = true;
+ }
+ if (handlePackageUpdateLocked(packageName, activities[i],
+ UsbManager.ACTION_USB_ACCESSORY_ATTACHED)) {
+ changed = true;
+ }
+ }
+
+ if (changed) {
+ writeSettingsLocked();
+ }
+ }
+ }
+
+ public boolean hasPermission(UsbDevice device) {
+ synchronized (mLock) {
+ SparseBooleanArray uidList = mDevicePermissionMap.get(device.getDeviceName());
+ if (uidList == null) {
+ return false;
+ }
+ return uidList.get(Binder.getCallingUid());
+ }
+ }
+
+ public boolean hasPermission(UsbAccessory accessory) {
+ synchronized (mLock) {
+ SparseBooleanArray uidList = mAccessoryPermissionMap.get(accessory);
+ if (uidList == null) {
+ return false;
+ }
+ return uidList.get(Binder.getCallingUid());
+ }
+ }
+
+ public void checkPermission(UsbDevice device) {
+ if (!hasPermission(device)) {
+ throw new SecurityException("User has not given permission to device " + device);
+ }
}
public void checkPermission(UsbAccessory accessory) {
- if (accessory == null) return;
- synchronized (mLock) {
- ArrayList<AccessoryFilter> filterList = mAccessoryPermissionMap.get(Binder.getCallingUid());
- if (filterList != null) {
- int count = filterList.size();
- for (int i = 0; i < count; i++) {
- AccessoryFilter filter = filterList.get(i);
- if (filter.equals(accessory)) {
- // permission allowed
- return;
- }
- }
- }
+ if (!hasPermission(accessory)) {
+ throw new SecurityException("User has not given permission to accessory " + accessory);
}
- throw new SecurityException("User has not given permission to accessory " + accessory);
+ }
+
+ private void requestPermissionDialog(Intent intent, String packageName, PendingIntent pi) {
+ int uid = Binder.getCallingUid();
+
+ // compare uid with packageName to foil apps pretending to be someone else
+ try {
+ ApplicationInfo aInfo = mPackageManager.getApplicationInfo(packageName, 0);
+ if (aInfo.uid != uid) {
+ throw new IllegalArgumentException("package " + packageName +
+ " does not match caller's uid " + uid);
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ throw new IllegalArgumentException("package " + packageName + " not found");
+ }
+
+ long identity = Binder.clearCallingIdentity();
+ intent.setClassName("com.android.systemui",
+ "com.android.systemui.usb.UsbPermissionActivity");
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.putExtra(Intent.EXTRA_INTENT, pi);
+ intent.putExtra("package", packageName);
+ intent.putExtra("uid", uid);
+ try {
+ mContext.startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ Log.e(TAG, "unable to start UsbPermissionActivity");
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ public void requestPermission(UsbDevice device, String packageName, PendingIntent pi) {
+ Intent intent = new Intent();
+
+ // respond immediately if permission has already been granted
+ if (hasPermission(device)) {
+ intent.putExtra(UsbManager.EXTRA_DEVICE, device);
+ intent.putExtra(UsbManager.EXTRA_PERMISSION_GRANTED, true);
+ try {
+ pi.send(mContext, 0, intent);
+ } catch (PendingIntent.CanceledException e) {
+ Log.w(TAG, "requestPermission PendingIntent was cancelled");
+ }
+ return;
+ }
+
+ // start UsbPermissionActivity so user can choose an activity
+ intent.putExtra(UsbManager.EXTRA_DEVICE, device);
+ requestPermissionDialog(intent, packageName, pi);
+ }
+
+ public void requestPermission(UsbAccessory accessory, String packageName, PendingIntent pi) {
+ Intent intent = new Intent();
+
+ // respond immediately if permission has already been granted
+ if (hasPermission(accessory)) {
+ intent.putExtra(UsbManager.EXTRA_ACCESSORY, accessory);
+ intent.putExtra(UsbManager.EXTRA_PERMISSION_GRANTED, true);
+ try {
+ pi.send(mContext, 0, intent);
+ } catch (PendingIntent.CanceledException e) {
+ Log.w(TAG, "requestPermission PendingIntent was cancelled");
+ }
+ return;
+ }
+
+ intent.putExtra(UsbManager.EXTRA_ACCESSORY, accessory);
+ requestPermissionDialog(intent, packageName, pi);
}
public void setDevicePackage(UsbDevice device, String packageName) {
@@ -783,73 +914,43 @@
public void grantDevicePermission(UsbDevice device, int uid) {
synchronized (mLock) {
- ArrayList<DeviceFilter> filterList = mDevicePermissionMap.get(uid);
- if (filterList == null) {
- filterList = new ArrayList<DeviceFilter>();
- mDevicePermissionMap.put(uid, filterList);
- } else {
- int count = filterList.size();
- for (int i = 0; i < count; i++) {
- if (filterList.get(i).equals(device)) return;
- }
+ String deviceName = device.getDeviceName();
+ SparseBooleanArray uidList = mDevicePermissionMap.get(deviceName);
+ if (uidList == null) {
+ uidList = new SparseBooleanArray(1);
+ mDevicePermissionMap.put(deviceName, uidList);
}
- filterList.add(new DeviceFilter(device));
- writeSettingsLocked();
+ uidList.put(uid, true);
}
}
public void grantAccessoryPermission(UsbAccessory accessory, int uid) {
synchronized (mLock) {
- ArrayList<AccessoryFilter> filterList = mAccessoryPermissionMap.get(uid);
- if (filterList == null) {
- filterList = new ArrayList<AccessoryFilter>();
- mAccessoryPermissionMap.put(uid, filterList);
- } else {
- int count = filterList.size();
- for (int i = 0; i < count; i++) {
- if (filterList.get(i).equals(accessory)) return;
- }
+ SparseBooleanArray uidList = mAccessoryPermissionMap.get(accessory);
+ if (uidList == null) {
+ uidList = new SparseBooleanArray(1);
+ mAccessoryPermissionMap.put(accessory, uidList);
}
- filterList.add(new AccessoryFilter(accessory));
- writeSettingsLocked();
+ uidList.put(uid, true);
}
}
- public boolean hasDefaults(String packageName, int uid) {
+ public boolean hasDefaults(String packageName) {
synchronized (mLock) {
- if (mDevicePermissionMap.get(uid) != null) return true;
- if (mAccessoryPermissionMap.get(uid) != null) return true;
if (mDevicePreferenceMap.values().contains(packageName)) return true;
if (mAccessoryPreferenceMap.values().contains(packageName)) return true;
return false;
}
}
- public void clearDefaults(String packageName, int uid) {
+ public void clearDefaults(String packageName) {
synchronized (mLock) {
- boolean packageCleared = clearPackageDefaultsLocked(packageName);
- boolean uidCleared = clearUidDefaultsLocked(uid);
- if (packageCleared || uidCleared) {
+ if (clearPackageDefaultsLocked(packageName)) {
writeSettingsLocked();
}
}
}
- private boolean clearUidDefaultsLocked(int uid) {
- boolean cleared = false;
- int index = mDevicePermissionMap.indexOfKey(uid);
- if (index >= 0) {
- mDevicePermissionMap.removeAt(index);
- cleared = true;
- }
- index = mAccessoryPermissionMap.indexOfKey(uid);
- if (index >= 0) {
- mAccessoryPermissionMap.removeAt(index);
- cleared = true;
- }
- return cleared;
- }
-
private boolean clearPackageDefaultsLocked(String packageName) {
boolean cleared = false;
synchronized (mLock) {
@@ -882,24 +983,24 @@
public void dump(FileDescriptor fd, PrintWriter pw) {
synchronized (mLock) {
pw.println(" Device permissions:");
- int count = mDevicePermissionMap.size();
- for (int i = 0; i < count; i++) {
- int uid = mDevicePermissionMap.keyAt(i);
- pw.println(" " + "uid " + uid + ":");
- ArrayList<DeviceFilter> filters = mDevicePermissionMap.valueAt(i);
- for (DeviceFilter filter : filters) {
- pw.println(" " + filter);
+ for (String deviceName : mDevicePermissionMap.keySet()) {
+ pw.print(" " + deviceName + ": ");
+ SparseBooleanArray uidList = mDevicePermissionMap.get(deviceName);
+ int count = uidList.size();
+ for (int i = 0; i < count; i++) {
+ pw.print(Integer.toString(uidList.keyAt(i)) + " ");
}
+ pw.println("");
}
pw.println(" Accessory permissions:");
- count = mAccessoryPermissionMap.size();
- for (int i = 0; i < count; i++) {
- int uid = mAccessoryPermissionMap.keyAt(i);
- pw.println(" " + "uid " + uid + ":");
- ArrayList<AccessoryFilter> filters = mAccessoryPermissionMap.valueAt(i);
- for (AccessoryFilter filter : filters) {
- pw.println(" " + filter);
+ for (UsbAccessory accessory : mAccessoryPermissionMap.keySet()) {
+ pw.print(" " + accessory + ": ");
+ SparseBooleanArray uidList = mAccessoryPermissionMap.get(accessory);
+ int count = uidList.size();
+ for (int i = 0; i < count; i++) {
+ pw.print(Integer.toString(uidList.keyAt(i)) + " ");
}
+ pw.println("");
}
pw.println(" Device preferences:");
for (DeviceFilter filter : mDevicePreferenceMap.keySet()) {
diff --git a/services/java/com/android/server/usb/UsbService.java b/services/java/com/android/server/usb/UsbService.java
index 8170c61..8b419f3 100644
--- a/services/java/com/android/server/usb/UsbService.java
+++ b/services/java/com/android/server/usb/UsbService.java
@@ -16,6 +16,7 @@
package com.android.server.usb;
+import android.app.PendingIntent;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -422,10 +423,7 @@
/* returns the currently attached USB accessory (device mode) */
public UsbAccessory getCurrentAccessory() {
- synchronized (mLock) {
- mDeviceManager.checkPermission(mCurrentAccessory);
- return mCurrentAccessory;
- }
+ return mCurrentAccessory;
}
/* opens the currently attached USB accessory (device mode) */
@@ -454,6 +452,24 @@
mDeviceManager.setAccessoryPackage(accessory, packageName);
}
+ public boolean hasDevicePermission(UsbDevice device) {
+ return mDeviceManager.hasPermission(device);
+ }
+
+ public boolean hasAccessoryPermission(UsbAccessory accessory) {
+ return mDeviceManager.hasPermission(accessory);
+ }
+
+ public void requestDevicePermission(UsbDevice device, String packageName,
+ PendingIntent pi) {
+ mDeviceManager.requestPermission(device, packageName, pi);
+ }
+
+ public void requestAccessoryPermission(UsbAccessory accessory, String packageName,
+ PendingIntent pi) {
+ mDeviceManager.requestPermission(accessory, packageName, pi);
+ }
+
public void grantDevicePermission(UsbDevice device, int uid) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
mDeviceManager.grantDevicePermission(device, uid);
@@ -464,14 +480,14 @@
mDeviceManager.grantAccessoryPermission(accessory, uid);
}
- public boolean hasDefaults(String packageName, int uid) {
+ public boolean hasDefaults(String packageName) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
- return mDeviceManager.hasDefaults(packageName, uid);
+ return mDeviceManager.hasDefaults(packageName);
}
- public void clearDefaults(String packageName, int uid) {
+ public void clearDefaults(String packageName) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
- mDeviceManager.clearDefaults(packageName, uid);
+ mDeviceManager.clearDefaults(packageName);
}
/*
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index eed41a0..33e6a36 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -4727,7 +4727,15 @@
SystemProperties.set(StrictMode.VISUAL_PROPERTY, value);
}
- public Bitmap screenshotApplications(IBinder appToken, int maxWidth, int maxHeight) {
+ /**
+ * Takes a snapshot of the screen. In landscape mode this grabs the whole screen.
+ * In portrait mode, it grabs the upper region of the screen based on the vertical dimension
+ * of the target image.
+ *
+ * @param width the width of the target bitmap
+ * @param height the height of the target bitmap
+ */
+ public Bitmap screenshotApplications(IBinder appToken, int width, int height) {
if (!checkCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
"screenshotApplications()")) {
throw new SecurityException("Requires READ_FRAME_BUFFER permission");
@@ -4739,7 +4747,7 @@
final Rect frame = new Rect();
float scale;
- int sw, sh, dw, dh;
+ int dw, dh;
int rot;
synchronized(mWindowMap) {
@@ -4791,19 +4799,23 @@
if (maxLayer < ws.mAnimLayer) {
maxLayer = ws.mAnimLayer;
}
- final Rect wf = ws.mFrame;
- final Rect cr = ws.mContentInsets;
- int left = wf.left + cr.left;
- int top = wf.top + cr.top;
- int right = wf.right - cr.right;
- int bottom = wf.bottom - cr.bottom;
- frame.union(left, top, right, bottom);
+
+ // Don't include wallpaper in bounds calculation
+ if (!ws.mIsWallpaper) {
+ final Rect wf = ws.mFrame;
+ final Rect cr = ws.mContentInsets;
+ int left = wf.left + cr.left;
+ int top = wf.top + cr.top;
+ int right = wf.right - cr.right;
+ int bottom = wf.bottom - cr.bottom;
+ frame.union(left, top, right, bottom);
+ }
}
Binder.restoreCallingIdentity(ident);
// Constrain frame to the screen size.
frame.intersect(0, 0, dw, dh);
-
+
if (frame.isEmpty() || maxLayer == 0) {
return null;
}
@@ -4814,15 +4826,7 @@
int fh = frame.height();
// First try reducing to fit in x dimension.
- scale = maxWidth/(float)fw;
- sw = maxWidth;
- sh = (int)(fh*scale);
- if (sh > maxHeight) {
- // y dimension became too long; constrain by that.
- scale = maxHeight/(float)fh;
- sw = (int)(fw*scale);
- sh = maxHeight;
- }
+ scale = width/(float)fw;
// The screen shot will contain the entire screen.
dw = (int)(dw*scale);
@@ -4841,8 +4845,8 @@
+ ") to layer " + maxLayer);
return null;
}
-
- Bitmap bm = Bitmap.createBitmap(sw, sh, rawss.getConfig());
+
+ Bitmap bm = Bitmap.createBitmap(width, height, rawss.getConfig());
Matrix matrix = new Matrix();
ScreenRotationAnimation.createRotationMatrix(rot, dw, dh, matrix);
matrix.postTranslate(-(int)(frame.left*scale), -(int)(frame.top*scale));
@@ -5460,8 +5464,9 @@
shortSize = (int)(shortSize/dm.density);
// These semi-magic numbers define our compatibility modes for
- // applications with different screens. Don't change unless you
- // make sure to test lots and lots of apps!
+ // applications with different screens. These are guarantees to
+ // app developers about the space they can expect for a particular
+ // configuration. DO NOT CHANGE!
if (longSize < 470) {
// This is shorter than an HVGA normal density screen (which
// is 480 pixels on its long side).
@@ -5469,12 +5474,12 @@
| Configuration.SCREENLAYOUT_LONG_NO;
} else {
// What size is this screen screen?
- if (longSize >= 800 && shortSize >= 600) {
- // SVGA or larger screens at medium density are the point
+ if (longSize >= 960 && shortSize >= 720) {
+ // 1.5xVGA or larger screens at medium density are the point
// at which we consider it to be an extra large screen.
mScreenLayout = Configuration.SCREENLAYOUT_SIZE_XLARGE;
- } else if (longSize >= 530 && shortSize >= 400) {
- // SVGA or larger screens at high density are the point
+ } else if (longSize >= 640 && shortSize >= 480) {
+ // VGA or larger screens at medium density are the point
// at which we consider it to be a large screen.
mScreenLayout = Configuration.SCREENLAYOUT_SIZE_LARGE;
} else {
diff --git a/services/jni/com_android_server_InputApplication.cpp b/services/jni/com_android_server_InputApplication.cpp
index e64ec4e..1f80242 100644
--- a/services/jni/com_android_server_InputApplication.cpp
+++ b/services/jni/com_android_server_InputApplication.cpp
@@ -26,8 +26,6 @@
namespace android {
static struct {
- jclass clazz;
-
jfieldID inputApplicationHandle;
jfieldID name;
jfieldID dispatchingTimeoutNanos;
@@ -69,25 +67,25 @@
#define FIND_CLASS(var, className) \
var = env->FindClass(className); \
- LOG_FATAL_IF(! var, "Unable to find class " className); \
- var = jclass(env->NewGlobalRef(var));
+ LOG_FATAL_IF(! var, "Unable to find class " className);
#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
LOG_FATAL_IF(! var, "Unable to find field " fieldName);
int register_android_server_InputApplication(JNIEnv* env) {
- FIND_CLASS(gInputApplicationClassInfo.clazz, "com/android/server/wm/InputApplication");
+ jclass clazz;
+ FIND_CLASS(clazz, "com/android/server/wm/InputApplication");
GET_FIELD_ID(gInputApplicationClassInfo.inputApplicationHandle,
- gInputApplicationClassInfo.clazz,
+ clazz,
"inputApplicationHandle", "Lcom/android/server/wm/InputApplicationHandle;");
- GET_FIELD_ID(gInputApplicationClassInfo.name, gInputApplicationClassInfo.clazz,
+ GET_FIELD_ID(gInputApplicationClassInfo.name, clazz,
"name", "Ljava/lang/String;");
GET_FIELD_ID(gInputApplicationClassInfo.dispatchingTimeoutNanos,
- gInputApplicationClassInfo.clazz,
+ clazz,
"dispatchingTimeoutNanos", "J");
return 0;
}
diff --git a/services/jni/com_android_server_InputApplicationHandle.cpp b/services/jni/com_android_server_InputApplicationHandle.cpp
index 3a1214f..9516964 100644
--- a/services/jni/com_android_server_InputApplicationHandle.cpp
+++ b/services/jni/com_android_server_InputApplicationHandle.cpp
@@ -26,8 +26,6 @@
namespace android {
static struct {
- jclass clazz;
-
jfieldID ptr;
} gInputApplicationHandleClassInfo;
@@ -98,8 +96,7 @@
#define FIND_CLASS(var, className) \
var = env->FindClass(className); \
- LOG_FATAL_IF(! var, "Unable to find class " className); \
- var = jclass(env->NewGlobalRef(var));
+ LOG_FATAL_IF(! var, "Unable to find class " className);
#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
@@ -110,9 +107,10 @@
gInputApplicationHandleMethods, NELEM(gInputApplicationHandleMethods));
LOG_FATAL_IF(res < 0, "Unable to register native methods.");
- FIND_CLASS(gInputApplicationHandleClassInfo.clazz, "com/android/server/wm/InputApplicationHandle");
+ jclass clazz;
+ FIND_CLASS(clazz, "com/android/server/wm/InputApplicationHandle");
- GET_FIELD_ID(gInputApplicationHandleClassInfo.ptr, gInputApplicationHandleClassInfo.clazz,
+ GET_FIELD_ID(gInputApplicationHandleClassInfo.ptr, clazz,
"ptr", "I");
return 0;
diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp
index 3be3b1b..31d0732 100644
--- a/services/jni/com_android_server_InputManager.cpp
+++ b/services/jni/com_android_server_InputManager.cpp
@@ -52,8 +52,6 @@
namespace android {
static struct {
- jclass clazz;
-
jmethodID notifyConfigurationChanged;
jmethodID notifyLidSwitchChanged;
jmethodID notifyInputChannelBroken;
@@ -95,16 +93,12 @@
} gInputDeviceClassInfo;
static struct {
- jclass clazz;
-
jfieldID touchscreen;
jfieldID keyboard;
jfieldID navigation;
} gConfigurationClassInfo;
static struct {
- jclass clazz;
-
jfieldID bitmap;
jfieldID hotSpotX;
jfieldID hotSpotY;
@@ -727,14 +721,14 @@
};
if (wmActions & WM_ACTION_GO_TO_SLEEP) {
-#ifdef DEBUG_INPUT_DISPATCHER_POLICY
+#if DEBUG_INPUT_DISPATCHER_POLICY
LOGD("handleInterceptActions: Going to sleep.");
#endif
android_server_PowerManagerService_goToSleep(when);
}
if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
-#ifdef DEBUG_INPUT_DISPATCHER_POLICY
+#if DEBUG_INPUT_DISPATCHER_POLICY
LOGD("handleInterceptActions: Poking user activity.");
#endif
android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
@@ -743,7 +737,7 @@
if (wmActions & WM_ACTION_PASS_TO_USER) {
policyFlags |= POLICY_FLAG_PASS_TO_USER;
} else {
-#ifdef DEBUG_INPUT_DISPATCHER_POLICY
+#if DEBUG_INPUT_DISPATCHER_POLICY
LOGD("handleInterceptActions: Not passing key to user.");
#endif
}
@@ -1103,12 +1097,11 @@
env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
- const KeyedVector<int, InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
+ const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
for (size_t i = 0; i < ranges.size(); i++) {
- int rangeType = ranges.keyAt(i);
- const InputDeviceInfo::MotionRange& range = ranges.valueAt(i);
+ const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
- rangeType, range.min, range.max, range.flat, range.fuzz);
+ range.axis, range.source, range.min, range.max, range.flat, range.fuzz);
if (env->ExceptionCheck()) {
return NULL;
}
@@ -1227,8 +1220,7 @@
#define FIND_CLASS(var, className) \
var = env->FindClass(className); \
- LOG_FATAL_IF(! var, "Unable to find class " className); \
- var = jclass(env->NewGlobalRef(var));
+ LOG_FATAL_IF(! var, "Unable to find class " className);
#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
var = env->GetMethodID(clazz, methodName, methodDescriptor); \
@@ -1245,83 +1237,88 @@
// Callbacks
- FIND_CLASS(gCallbacksClassInfo.clazz, "com/android/server/wm/InputManager$Callbacks");
+ jclass clazz;
+ FIND_CLASS(clazz, "com/android/server/wm/InputManager$Callbacks");
- GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, gCallbacksClassInfo.clazz,
+ GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, clazz,
"notifyConfigurationChanged", "(J)V");
- GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, gCallbacksClassInfo.clazz,
+ GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, clazz,
"notifyLidSwitchChanged", "(JZ)V");
- GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, gCallbacksClassInfo.clazz,
+ GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, clazz,
"notifyInputChannelBroken", "(Lcom/android/server/wm/InputWindowHandle;)V");
- GET_METHOD_ID(gCallbacksClassInfo.notifyANR, gCallbacksClassInfo.clazz,
+ GET_METHOD_ID(gCallbacksClassInfo.notifyANR, clazz,
"notifyANR",
"(Lcom/android/server/wm/InputApplicationHandle;Lcom/android/server/wm/InputWindowHandle;)J");
- GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, gCallbacksClassInfo.clazz,
+ GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, clazz,
"interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;IZ)I");
GET_METHOD_ID(gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
- gCallbacksClassInfo.clazz,
+ clazz,
"interceptMotionBeforeQueueingWhenScreenOff", "(I)I");
- GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, gCallbacksClassInfo.clazz,
+ GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, clazz,
"interceptKeyBeforeDispatching",
"(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Z");
- GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, gCallbacksClassInfo.clazz,
+ GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, clazz,
"dispatchUnhandledKey",
"(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
- GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, gCallbacksClassInfo.clazz,
+ GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, clazz,
"checkInjectEventsPermission", "(II)Z");
- GET_METHOD_ID(gCallbacksClassInfo.filterTouchEvents, gCallbacksClassInfo.clazz,
+ GET_METHOD_ID(gCallbacksClassInfo.filterTouchEvents, clazz,
"filterTouchEvents", "()Z");
- GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, gCallbacksClassInfo.clazz,
+ GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, clazz,
"filterJumpyTouchEvents", "()Z");
- GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyQuietTimeMillis, gCallbacksClassInfo.clazz,
+ GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyQuietTimeMillis, clazz,
"getVirtualKeyQuietTimeMillis", "()I");
- GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, gCallbacksClassInfo.clazz,
+ GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, clazz,
"getExcludedDeviceNames", "()[Ljava/lang/String;");
- GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatTimeout, gCallbacksClassInfo.clazz,
+ GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatTimeout, clazz,
"getKeyRepeatTimeout", "()I");
- GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatDelay, gCallbacksClassInfo.clazz,
+ GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatDelay, clazz,
"getKeyRepeatDelay", "()I");
- GET_METHOD_ID(gCallbacksClassInfo.getMaxEventsPerSecond, gCallbacksClassInfo.clazz,
+ GET_METHOD_ID(gCallbacksClassInfo.getMaxEventsPerSecond, clazz,
"getMaxEventsPerSecond", "()I");
- GET_METHOD_ID(gCallbacksClassInfo.getPointerLayer, gCallbacksClassInfo.clazz,
+ GET_METHOD_ID(gCallbacksClassInfo.getPointerLayer, clazz,
"getPointerLayer", "()I");
- GET_METHOD_ID(gCallbacksClassInfo.getPointerIcon, gCallbacksClassInfo.clazz,
+ GET_METHOD_ID(gCallbacksClassInfo.getPointerIcon, clazz,
"getPointerIcon", "()Lcom/android/server/wm/InputManager$PointerIcon;");
// KeyEvent
FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
+ gKeyEventClassInfo.clazz = jclass(env->NewGlobalRef(gKeyEventClassInfo.clazz));
+
// MotionEvent
FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
+ gMotionEventClassInfo.clazz = jclass(env->NewGlobalRef(gMotionEventClassInfo.clazz));
// InputDevice
FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
+ gInputDeviceClassInfo.clazz = jclass(env->NewGlobalRef(gInputDeviceClassInfo.clazz));
GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
"<init>", "()V");
GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
- "addMotionRange", "(IFFFF)V");
+ "addMotionRange", "(IIFFFF)V");
GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
"mId", "I");
@@ -1337,28 +1334,28 @@
// Configuration
- FIND_CLASS(gConfigurationClassInfo.clazz, "android/content/res/Configuration");
+ FIND_CLASS(clazz, "android/content/res/Configuration");
- GET_FIELD_ID(gConfigurationClassInfo.touchscreen, gConfigurationClassInfo.clazz,
+ GET_FIELD_ID(gConfigurationClassInfo.touchscreen, clazz,
"touchscreen", "I");
- GET_FIELD_ID(gConfigurationClassInfo.keyboard, gConfigurationClassInfo.clazz,
+ GET_FIELD_ID(gConfigurationClassInfo.keyboard, clazz,
"keyboard", "I");
- GET_FIELD_ID(gConfigurationClassInfo.navigation, gConfigurationClassInfo.clazz,
+ GET_FIELD_ID(gConfigurationClassInfo.navigation, clazz,
"navigation", "I");
// PointerIcon
- FIND_CLASS(gPointerIconClassInfo.clazz, "com/android/server/wm/InputManager$PointerIcon");
+ FIND_CLASS(clazz, "com/android/server/wm/InputManager$PointerIcon");
- GET_FIELD_ID(gPointerIconClassInfo.bitmap, gPointerIconClassInfo.clazz,
+ GET_FIELD_ID(gPointerIconClassInfo.bitmap, clazz,
"bitmap", "Landroid/graphics/Bitmap;");
- GET_FIELD_ID(gPointerIconClassInfo.hotSpotX, gPointerIconClassInfo.clazz,
+ GET_FIELD_ID(gPointerIconClassInfo.hotSpotX, clazz,
"hotSpotX", "F");
- GET_FIELD_ID(gPointerIconClassInfo.hotSpotY, gPointerIconClassInfo.clazz,
+ GET_FIELD_ID(gPointerIconClassInfo.hotSpotY, clazz,
"hotSpotY", "F");
return 0;
diff --git a/services/jni/com_android_server_InputWindow.cpp b/services/jni/com_android_server_InputWindow.cpp
index 8548b47..99f625c 100644
--- a/services/jni/com_android_server_InputWindow.cpp
+++ b/services/jni/com_android_server_InputWindow.cpp
@@ -28,8 +28,6 @@
namespace android {
static struct {
- jclass clazz;
-
jfieldID inputWindowHandle;
jfieldID inputChannel;
jfieldID name;
@@ -136,71 +134,71 @@
#define FIND_CLASS(var, className) \
var = env->FindClass(className); \
- LOG_FATAL_IF(! var, "Unable to find class " className); \
- var = jclass(env->NewGlobalRef(var));
+ LOG_FATAL_IF(! var, "Unable to find class " className);
#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
LOG_FATAL_IF(! var, "Unable to find field " fieldName);
int register_android_server_InputWindow(JNIEnv* env) {
- FIND_CLASS(gInputWindowClassInfo.clazz, "com/android/server/wm/InputWindow");
+ jclass clazz;
+ FIND_CLASS(clazz, "com/android/server/wm/InputWindow");
- GET_FIELD_ID(gInputWindowClassInfo.inputWindowHandle, gInputWindowClassInfo.clazz,
+ GET_FIELD_ID(gInputWindowClassInfo.inputWindowHandle, clazz,
"inputWindowHandle", "Lcom/android/server/wm/InputWindowHandle;");
- GET_FIELD_ID(gInputWindowClassInfo.inputChannel, gInputWindowClassInfo.clazz,
+ GET_FIELD_ID(gInputWindowClassInfo.inputChannel, clazz,
"inputChannel", "Landroid/view/InputChannel;");
- GET_FIELD_ID(gInputWindowClassInfo.name, gInputWindowClassInfo.clazz,
+ GET_FIELD_ID(gInputWindowClassInfo.name, clazz,
"name", "Ljava/lang/String;");
- GET_FIELD_ID(gInputWindowClassInfo.layoutParamsFlags, gInputWindowClassInfo.clazz,
+ GET_FIELD_ID(gInputWindowClassInfo.layoutParamsFlags, clazz,
"layoutParamsFlags", "I");
- GET_FIELD_ID(gInputWindowClassInfo.layoutParamsType, gInputWindowClassInfo.clazz,
+ GET_FIELD_ID(gInputWindowClassInfo.layoutParamsType, clazz,
"layoutParamsType", "I");
- GET_FIELD_ID(gInputWindowClassInfo.dispatchingTimeoutNanos, gInputWindowClassInfo.clazz,
+ GET_FIELD_ID(gInputWindowClassInfo.dispatchingTimeoutNanos, clazz,
"dispatchingTimeoutNanos", "J");
- GET_FIELD_ID(gInputWindowClassInfo.frameLeft, gInputWindowClassInfo.clazz,
+ GET_FIELD_ID(gInputWindowClassInfo.frameLeft, clazz,
"frameLeft", "I");
- GET_FIELD_ID(gInputWindowClassInfo.frameTop, gInputWindowClassInfo.clazz,
+ GET_FIELD_ID(gInputWindowClassInfo.frameTop, clazz,
"frameTop", "I");
- GET_FIELD_ID(gInputWindowClassInfo.frameRight, gInputWindowClassInfo.clazz,
+ GET_FIELD_ID(gInputWindowClassInfo.frameRight, clazz,
"frameRight", "I");
- GET_FIELD_ID(gInputWindowClassInfo.frameBottom, gInputWindowClassInfo.clazz,
+ GET_FIELD_ID(gInputWindowClassInfo.frameBottom, clazz,
"frameBottom", "I");
- GET_FIELD_ID(gInputWindowClassInfo.touchableRegion, gInputWindowClassInfo.clazz,
+ GET_FIELD_ID(gInputWindowClassInfo.touchableRegion, clazz,
"touchableRegion", "Landroid/graphics/Region;");
- GET_FIELD_ID(gInputWindowClassInfo.visible, gInputWindowClassInfo.clazz,
+ GET_FIELD_ID(gInputWindowClassInfo.visible, clazz,
"visible", "Z");
- GET_FIELD_ID(gInputWindowClassInfo.canReceiveKeys, gInputWindowClassInfo.clazz,
+ GET_FIELD_ID(gInputWindowClassInfo.canReceiveKeys, clazz,
"canReceiveKeys", "Z");
- GET_FIELD_ID(gInputWindowClassInfo.hasFocus, gInputWindowClassInfo.clazz,
+ GET_FIELD_ID(gInputWindowClassInfo.hasFocus, clazz,
"hasFocus", "Z");
- GET_FIELD_ID(gInputWindowClassInfo.hasWallpaper, gInputWindowClassInfo.clazz,
+ GET_FIELD_ID(gInputWindowClassInfo.hasWallpaper, clazz,
"hasWallpaper", "Z");
- GET_FIELD_ID(gInputWindowClassInfo.paused, gInputWindowClassInfo.clazz,
+ GET_FIELD_ID(gInputWindowClassInfo.paused, clazz,
"paused", "Z");
- GET_FIELD_ID(gInputWindowClassInfo.layer, gInputWindowClassInfo.clazz,
+ GET_FIELD_ID(gInputWindowClassInfo.layer, clazz,
"layer", "I");
- GET_FIELD_ID(gInputWindowClassInfo.ownerPid, gInputWindowClassInfo.clazz,
+ GET_FIELD_ID(gInputWindowClassInfo.ownerPid, clazz,
"ownerPid", "I");
- GET_FIELD_ID(gInputWindowClassInfo.ownerUid, gInputWindowClassInfo.clazz,
+ GET_FIELD_ID(gInputWindowClassInfo.ownerUid, clazz,
"ownerUid", "I");
return 0;
}
diff --git a/services/jni/com_android_server_InputWindowHandle.cpp b/services/jni/com_android_server_InputWindowHandle.cpp
index 5b74e43..aaf679c 100644
--- a/services/jni/com_android_server_InputWindowHandle.cpp
+++ b/services/jni/com_android_server_InputWindowHandle.cpp
@@ -27,8 +27,6 @@
namespace android {
static struct {
- jclass clazz;
-
jfieldID ptr;
jfieldID inputApplicationHandle;
} gInputWindowHandleClassInfo;
@@ -108,8 +106,7 @@
#define FIND_CLASS(var, className) \
var = env->FindClass(className); \
- LOG_FATAL_IF(! var, "Unable to find class " className); \
- var = jclass(env->NewGlobalRef(var));
+ LOG_FATAL_IF(! var, "Unable to find class " className);
#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
@@ -120,13 +117,14 @@
gInputWindowHandleMethods, NELEM(gInputWindowHandleMethods));
LOG_FATAL_IF(res < 0, "Unable to register native methods.");
- FIND_CLASS(gInputWindowHandleClassInfo.clazz, "com/android/server/wm/InputWindowHandle");
+ jclass clazz;
+ FIND_CLASS(clazz, "com/android/server/wm/InputWindowHandle");
- GET_FIELD_ID(gInputWindowHandleClassInfo.ptr, gInputWindowHandleClassInfo.clazz,
+ GET_FIELD_ID(gInputWindowHandleClassInfo.ptr, clazz,
"ptr", "I");
GET_FIELD_ID(gInputWindowHandleClassInfo.inputApplicationHandle,
- gInputWindowHandleClassInfo.clazz,
+ clazz,
"inputApplicationHandle", "Lcom/android/server/wm/InputApplicationHandle;");
return 0;
diff --git a/services/jni/com_android_server_PowerManagerService.cpp b/services/jni/com_android_server_PowerManagerService.cpp
index 705be60..a389c11 100644
--- a/services/jni/com_android_server_PowerManagerService.cpp
+++ b/services/jni/com_android_server_PowerManagerService.cpp
@@ -35,8 +35,6 @@
// ----------------------------------------------------------------------------
static struct {
- jclass clazz;
-
jmethodID goToSleep;
jmethodID userActivity;
} gPowerManagerServiceClassInfo;
@@ -144,8 +142,7 @@
#define FIND_CLASS(var, className) \
var = env->FindClass(className); \
- LOG_FATAL_IF(! var, "Unable to find class " className); \
- var = jclass(env->NewGlobalRef(var));
+ LOG_FATAL_IF(! var, "Unable to find class " className);
#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
var = env->GetMethodID(clazz, methodName, methodDescriptor); \
@@ -162,12 +159,13 @@
// Callbacks
- FIND_CLASS(gPowerManagerServiceClassInfo.clazz, "com/android/server/PowerManagerService");
+ jclass clazz;
+ FIND_CLASS(clazz, "com/android/server/PowerManagerService");
- GET_METHOD_ID(gPowerManagerServiceClassInfo.goToSleep, gPowerManagerServiceClassInfo.clazz,
+ GET_METHOD_ID(gPowerManagerServiceClassInfo.goToSleep, clazz,
"goToSleep", "(J)V");
- GET_METHOD_ID(gPowerManagerServiceClassInfo.userActivity, gPowerManagerServiceClassInfo.clazz,
+ GET_METHOD_ID(gPowerManagerServiceClassInfo.userActivity, clazz,
"userActivity", "(JZIZ)V");
// Initialize
diff --git a/services/jni/com_android_server_UsbService.cpp b/services/jni/com_android_server_UsbService.cpp
index 3c49e54..c66f181 100644
--- a/services/jni/com_android_server_UsbService.cpp
+++ b/services/jni/com_android_server_UsbService.cpp
@@ -193,12 +193,13 @@
return NULL;
}
jclass stringClass = env->FindClass("java/lang/String");
- jobjectArray strArray = env->NewObjectArray(4, stringClass, NULL);
+ jobjectArray strArray = env->NewObjectArray(5, 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_DESCRIPTION, strArray, 2);
set_accessory_string(env, fd, ACCESSORY_GET_STRING_VERSION, strArray, 3);
+ set_accessory_string(env, fd, ACCESSORY_GET_STRING_URI, strArray, 4);
out:
close(fd);
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 697e879..ce1ab3d 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -340,11 +340,14 @@
if (rec->addConnection(connection)) {
// this sensor is already activated, but we are adding a
// connection that uses it. Immediately send down the last
- // known value of the requested sensor.
- sensors_event_t scratch;
- sensors_event_t& event(mLastEventSeen.editValueFor(handle));
- if (event.version == sizeof(sensors_event_t)) {
- connection->sendEvents(&event, 1);
+ // known value of the requested sensor if it's not a
+ // "continuous" sensor.
+ if (sensor->getSensor().getMinDelay() == 0) {
+ sensors_event_t scratch;
+ sensors_event_t& event(mLastEventSeen.editValueFor(handle));
+ if (event.version == sizeof(sensors_event_t)) {
+ connection->sendEvents(&event, 1);
+ }
}
}
}
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 57af001..7a69097 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -52,15 +52,16 @@
Layer::Layer(SurfaceFlinger* flinger,
DisplayID display, const sp<Client>& client)
: LayerBaseClient(flinger, display, client),
+ mFormat(PIXEL_FORMAT_NONE),
mGLExtensions(GLExtensions::getInstance()),
mNeedsBlending(true),
mNeedsDithering(false),
mSecure(false),
mProtectedByApp(false),
- mProtectedByDRM(false),
mTextureManager(),
mBufferManager(mTextureManager),
- mWidth(0), mHeight(0), mNeedsScaling(false), mFixedSize(false)
+ mWidth(0), mHeight(0),
+ mNeedsScaling(false), mFixedSize(false)
{
}
@@ -191,7 +192,6 @@
mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
mProtectedByApp = (flags & ISurfaceComposer::eProtectedByApp) ? true : false;
- mProtectedByDRM = (flags & ISurfaceComposer::eProtectedByDRM) ? true : false;
mNeedsBlending = (info.h_alpha - info.l_alpha) > 0 &&
(flags & ISurfaceComposer::eOpaque) == 0;
@@ -392,6 +392,12 @@
return LayerBase::needsFiltering();
}
+bool Layer::isProtected() const
+{
+ sp<GraphicBuffer> activeBuffer(mBufferManager.getActiveBuffer());
+ return (activeBuffer != 0) &&
+ (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
+}
status_t Layer::setBufferCount(int bufferCount)
{
@@ -515,7 +521,7 @@
// request EGLImage for all buffers
usage |= GraphicBuffer::USAGE_HW_TEXTURE;
}
- if (mProtectedByApp || mProtectedByDRM) {
+ if (mProtectedByApp) {
// need a hardware-protected path to external video sink
usage |= GraphicBuffer::USAGE_PROTECTED;
}
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index bccc900..128f93d 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -80,8 +80,7 @@
virtual bool needsDithering() const { return mNeedsDithering; }
virtual bool needsFiltering() const;
virtual bool isSecure() const { return mSecure; }
- virtual bool isProtectedByApp() const { return mProtectedByApp; }
- virtual bool isProtectedByDRM() const { return mProtectedByDRM; }
+ virtual bool isProtected() const;
virtual sp<Surface> createSurface() const;
virtual status_t ditch();
virtual void onRemoved();
@@ -222,7 +221,6 @@
// page-flip thread (currently main thread)
bool mSecure; // no screenshots
bool mProtectedByApp; // application requires protected path to external sink
- bool mProtectedByDRM; // DRM agent requires protected path to external sink
Region mPostedDirtyRegion;
// page-flip thread and transaction thread (currently main thread)
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index bfe92e6..7162e47 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -197,16 +197,10 @@
virtual bool isSecure() const { return false; }
/**
- * isProtectedByApp - true if application says this surface is protected, that
- * is if it requires a hardware-protected data path to an external sink.
+ * isProtected - true if the layer may contain protected content in the
+ * GRALLOC_USAGE_PROTECTED sense.
*/
- virtual bool isProtectedByApp() const { return false; }
-
- /**
- * isProtectedByDRM - true if DRM agent says this surface is protected, that
- * is if it requires a hardware-protected data path to an external sink.
- */
- virtual bool isProtectedByDRM() const { return false; }
+ virtual bool isProtected() const { return false; }
/** Called from the main thread, when the surface is removed from the
* draw list */
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 554fa43..ea283c606 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -327,6 +327,40 @@
const_cast<SurfaceFlinger*>(this)->signalEvent();
}
+bool SurfaceFlinger::authenticateSurface(const sp<ISurface>& surface) const {
+ Mutex::Autolock _l(mStateLock);
+ sp<IBinder> surfBinder(surface->asBinder());
+
+ // Check the visible layer list for the ISurface
+ const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
+ size_t count = currentLayers.size();
+ for (size_t i=0 ; i<count ; i++) {
+ const sp<LayerBase>& layer(currentLayers[i]);
+ sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
+ if (lbc != NULL && lbc->getSurfaceBinder() == surfBinder) {
+ return true;
+ }
+ }
+
+ // Check the layers in the purgatory. This check is here so that if a
+ // Surface gets destroyed before all the clients are done using it, the
+ // error will not be reported as "surface XYZ is not authenticated", but
+ // will instead fail later on when the client tries to use the surface,
+ // which should be reported as "surface XYZ returned an -ENODEV". The
+ // purgatorized layers are no less authentic than the visible ones, so this
+ // should not cause any harm.
+ size_t purgatorySize = mLayerPurgatory.size();
+ for (size_t i=0 ; i<purgatorySize ; i++) {
+ const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
+ sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
+ if (lbc != NULL && lbc->getSurfaceBinder() == surfBinder) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
status_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
nsecs_t reltime, uint32_t flags)
{
@@ -566,7 +600,7 @@
}
void SurfaceFlinger::computeVisibleRegions(
- LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
+ const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
{
const GraphicPlane& plane(graphicPlane(0));
const Transform& planeTransform(plane.transform());
@@ -701,8 +735,7 @@
void SurfaceFlinger::handlePageFlip()
{
bool visibleRegions = mVisibleRegionsDirty;
- LayerVector& currentLayers(
- const_cast<LayerVector&>(mDrawingState.layersSortedByZ));
+ const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
visibleRegions |= lockPageFlip(currentLayers);
const DisplayHardware& hw = graphicPlane(0).displayHardware();
@@ -714,9 +747,8 @@
/*
* rebuild the visible layer list
*/
+ const size_t count = currentLayers.size();
mVisibleLayersSortedByZ.clear();
- const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
- size_t count = currentLayers.size();
mVisibleLayersSortedByZ.setCapacity(count);
for (size_t i=0 ; i<count ; i++) {
if (!currentLayers[i]->visibleRegionScreen.isEmpty())
@@ -2135,6 +2167,19 @@
if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
return BAD_VALUE;
+ // make sure none of the layers are protected
+ const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
+ const size_t count = layers.size();
+ for (size_t i=0 ; i<count ; ++i) {
+ const sp<LayerBase>& layer(layers[i]);
+ const uint32_t z = layer->drawingState().z;
+ if (z >= minLayerZ && z <= maxLayerZ) {
+ if (layer->isProtected()) {
+ return INVALID_OPERATION;
+ }
+ }
+ }
+
if (!GLExtensions::getInstance().haveFramebufferObject())
return INVALID_OPERATION;
@@ -2183,8 +2228,6 @@
glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);
- const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
- const size_t count = layers.size();
for (size_t i=0 ; i<count ; ++i) {
const sp<LayerBase>& layer(layers[i]);
const uint32_t z = layer->drawingState().z;
@@ -2470,7 +2513,7 @@
}
break;
}
- if (++name >= SharedBufferStack::NUM_LAYERS_MAX)
+ if (++name >= int32_t(SharedBufferStack::NUM_LAYERS_MAX))
name = NO_MEMORY;
} while(name >= 0);
@@ -2517,7 +2560,7 @@
void GraphicBufferAlloc::freeAllGraphicBuffersExcept(int bufIdx) {
Mutex::Autolock _l(mLock);
- if (0 <= bufIdx && bufIdx < mBuffers.size()) {
+ if (bufIdx >= 0 && size_t(bufIdx) < mBuffers.size()) {
sp<GraphicBuffer> b(mBuffers[bufIdx]);
mBuffers.clear();
mBuffers.add(b);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 6dd91ac..0964848 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -209,6 +209,7 @@
virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags);
virtual int setOrientation(DisplayID dpy, int orientation, uint32_t flags);
virtual void signal() const;
+ virtual bool authenticateSurface(const sp<ISurface>& surface) const;
virtual status_t captureScreen(DisplayID dpy,
sp<IMemoryHeap>* heap,
@@ -303,7 +304,7 @@
Vector< sp<LayerBase> >& ditchedLayers);
void computeVisibleRegions(
- LayerVector& currentLayers,
+ const LayerVector& currentLayers,
Region& dirtyRegion,
Region& wormholeRegion);
@@ -370,7 +371,6 @@
// access must be protected by mStateLock
mutable Mutex mStateLock;
State mCurrentState;
- State mDrawingState;
volatile int32_t mTransactionFlags;
volatile int32_t mTransactionCount;
Condition mTransactionCV;
@@ -394,6 +394,7 @@
// Can only accessed from the main thread, these members
// don't need synchronization
+ State mDrawingState;
Region mDirtyRegion;
Region mDirtyRegionRemovedLayer;
Region mInvalidRegion;
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 5dcb820..ba05837 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -92,9 +92,11 @@
/** @hide */
public static final int RADIO_TECHNOLOGY_EVDO_B = 12;
/** @hide */
- public static final int RADIO_TECHNOLOGY_LTE = 13;
+ public static final int RADIO_TECHNOLOGY_EHRPD = 13;
/** @hide */
- public static final int RADIO_TECHNOLOGY_EHRPD = 14;
+ public static final int RADIO_TECHNOLOGY_LTE = 14;
+ /** @hide */
+ public static final int RADIO_TECHNOLOGY_HSPAP = 15;
/**
* Available registration states for GSM, UMTS and CDMA.
@@ -429,10 +431,13 @@
radioTechnology = "EvDo rev. B";
break;
case 13:
- radioTechnology = "LTE";
+ radioTechnology = "eHRPD";
break;
case 14:
- radioTechnology = "eHRPD";
+ radioTechnology = "LTE";
+ break;
+ case 15:
+ radioTechnology = "HSPAP";
break;
default:
Log.w(LOG_TAG, "mRadioTechnology variable out of range.");
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
index ea38543..9e1e0c6 100644
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java
@@ -27,9 +27,8 @@
* {@hide}
*/
public interface CommandsInterface {
- // TODO: Get rid of mot from property.
static final boolean LTE_AVAILABLE_ON_CDMA =
- SystemProperties.getBoolean("ro.mot.lte_on_cdma", false);
+ SystemProperties.getBoolean(TelephonyProperties.PROPERTY_NETWORK_LTE_ON_CDMA, false);
enum RadioState {
RADIO_OFF(0), /* Radio explictly powered off (eg CFUN=0) */
RADIO_UNAVAILABLE(0), /* Radio unavailable (eg, resetting or not booted) */
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index 89513fd..1f5fc05 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -219,10 +219,8 @@
protected static final int EVENT_LOG_BAD_DNS_ADDRESS = 50100;
//***** Member Variables
- protected int mId;
protected int mTag;
protected PhoneBase phone;
- protected RetryManager mRetryMgr;
protected int cid;
protected LinkProperties mLinkProperties = new LinkProperties();
protected LinkCapabilities mCapabilities = new LinkCapabilities();
@@ -244,10 +242,11 @@
//***** Constructor
- protected DataConnection(PhoneBase phone, String name, RetryManager rm) {
+ protected DataConnection(PhoneBase phone, String name, int id, RetryManager rm) {
super(name);
if (DBG) log("DataConnection constructor E");
this.phone = phone;
+ mId = id;
mRetryMgr = rm;
this.cid = -1;
clearSettings();
@@ -342,10 +341,88 @@
clearSettings();
}
- public RetryManager getRetryMgr() {
- return mRetryMgr;
+ /*
+ * **************************************************************************
+ * Begin Members and methods owned by DataConnectionTracker but stored
+ * in a DataConnection because there is one per connection.
+ * **************************************************************************
+ */
+
+ /*
+ * The id is owned by DataConnectionTracker.
+ */
+ private int mId;
+
+ /**
+ * Get the DataConnection ID
+ */
+ public int getDataConnectionId() {
+ return mId;
}
+ /*
+ * The retry manager is currently owned by the DataConnectionTracker but is stored
+ * in the DataConnection because there is one per connection. These methods
+ * should only be used by the DataConnectionTracker although someday the retrying
+ * maybe managed by the DataConnection itself and these methods could disappear.
+ */
+ private RetryManager mRetryMgr;
+
+ /**
+ * @return retry manager retryCount
+ */
+ public int getRetryCount() {
+ return mRetryMgr.getRetryCount();
+ }
+
+ /**
+ * @return retry manager retryTimer
+ */
+ public int getRetryTimer() {
+ return mRetryMgr.getRetryTimer();
+ }
+
+ /**
+ * increaseRetryCount of retry manager
+ */
+ public void increaseRetryCount() {
+ mRetryMgr.increaseRetryCount();
+ }
+
+ /**
+ * @return retry manager isRetryNeeded
+ */
+ public boolean isRetryNeeded() {
+ return mRetryMgr.isRetryNeeded();
+ }
+
+ /**
+ * resetRetryCount of retry manager
+ */
+ public void resetRetryCount() {
+ mRetryMgr.resetRetryCount();
+ }
+
+ /**
+ * set retryForeverUsingLasttimeout of retry manager
+ */
+ public void retryForeverUsingLastTimeout() {
+ mRetryMgr.retryForeverUsingLastTimeout();
+ }
+
+ /**
+ * @return retry manager isRetryForever
+ */
+ public boolean isRetryForever() {
+ return mRetryMgr.isRetryForever();
+ }
+
+ /*
+ * **************************************************************************
+ * End members owned by DataConnectionTracker
+ * **************************************************************************
+ */
+
/**
* Clear all settings called when entering mInactiveState.
*/
@@ -964,13 +1041,6 @@
}
/**
- * Get the DataConnection ID
- */
- public int getDataConnectionId() {
- return mId;
- }
-
- /**
* Return the LinkProperties for the connection.
*
* @return a copy of the LinkProperties, is never null.
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index 4c1e0cf..7f0c7c7d8 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -38,6 +38,8 @@
import android.text.TextUtils;
import android.util.Log;
+import com.android.internal.R;
+
import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.atomic.AtomicInteger;
@@ -209,9 +211,6 @@
protected int mNoRecvPollCount = 0;
protected boolean mNetStatPollEnabled = false;
- /** Manage the behavior of data retry after failure (TODO: One per connection in the future?) */
- protected RetryManager mRetryMgr = new RetryManager();
-
// wifi connection status will be updated by sticky intent
protected boolean mIsWifiConnected = false;
@@ -356,9 +355,26 @@
public boolean isApnTypeActive(String type) {
// TODO: support simultaneous with List instead
+ if (Phone.APN_TYPE_DUN.equals(type)) {
+ ApnSetting dunApn = fetchDunApn();
+ if (dunApn != null) {
+ return ((mActiveApn != null) && (dunApn.toString().equals(mActiveApn.toString())));
+ }
+ }
return mActiveApn != null && mActiveApn.canHandleType(type);
}
+ protected ApnSetting fetchDunApn() {
+ Context c = mPhone.getContext();
+ String apnData = Settings.Secure.getString(c.getContentResolver(),
+ Settings.Secure.TETHER_DUN_APN);
+ ApnSetting dunSetting = ApnSetting.fromString(apnData);
+ if (dunSetting != null) return dunSetting;
+
+ apnData = c.getResources().getString(R.string.config_tether_apndata);
+ return ApnSetting.fromString(apnData);
+ }
+
public String[] getActiveApnTypes() {
String[] result;
if (mActiveApn != null) {
@@ -397,7 +413,7 @@
Settings.Secure.DATA_ROAMING, enabled ? 1 : 0);
if (mPhone.getServiceState().getRoaming()) {
if (enabled) {
- mRetryMgr.resetRetryCount();
+ resetAllRetryCounts();
}
sendMessage(obtainMessage(EVENT_ROAMING_ON));
}
@@ -449,7 +465,7 @@
case EVENT_ROAMING_OFF:
if (getDataOnRoamingEnabled() == false) {
- mRetryMgr.resetRetryCount();
+ resetAllRetryCounts();
}
onRoamingOff();
break;
@@ -883,7 +899,7 @@
}
if (prevEnabled != getAnyDataEnabled()) {
if (!prevEnabled) {
- mRetryMgr.resetRetryCount();
+ resetAllRetryCounts();
onTrySetupData(Phone.REASON_DATA_ENABLED);
} else {
cleanUpAllConnections();
@@ -917,7 +933,7 @@
Settings.Secure.MOBILE_DATA, enable ? 1 : 0);
if (prevEnabled != getAnyDataEnabled()) {
if (!prevEnabled) {
- mRetryMgr.resetRetryCount();
+ resetAllRetryCounts();
onTrySetupData(Phone.REASON_DATA_ENABLED);
} else {
onCleanUpConnection(true, APN_DEFAULT_ID, Phone.REASON_DATA_DISABLED);
@@ -925,4 +941,10 @@
}
}
}
+
+ protected void resetAllRetryCounts() {
+ for (DataConnection dc : mDataConnections.values()) {
+ dc.resetRetryCount();
+ }
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/IccCard.java b/telephony/java/com/android/internal/telephony/IccCard.java
index d9c2e9a..dbfc0d4 100644
--- a/telephony/java/com/android/internal/telephony/IccCard.java
+++ b/telephony/java/com/android/internal/telephony/IccCard.java
@@ -86,9 +86,8 @@
private static final int EVENT_QUERY_FACILITY_FDN_DONE = 10;
private static final int EVENT_CHANGE_FACILITY_FDN_DONE = 11;
- // FIXME: remove mot from property
static final boolean LTE_AVAILABLE_ON_CDMA =
- SystemProperties.getBoolean("ro.mot.lte_on_cdma", false);
+ SystemProperties.getBoolean(TelephonyProperties.PROPERTY_NETWORK_LTE_ON_CDMA, false);
/*
UNKNOWN is a transient state, for example, after uesr inputs ICC pin under
diff --git a/telephony/java/com/android/internal/telephony/PhoneFactory.java b/telephony/java/com/android/internal/telephony/PhoneFactory.java
index c25a53d..ab0bb63 100644
--- a/telephony/java/com/android/internal/telephony/PhoneFactory.java
+++ b/telephony/java/com/android/internal/telephony/PhoneFactory.java
@@ -37,7 +37,7 @@
static final int SOCKET_OPEN_RETRY_MILLIS = 2 * 1000;
static final int SOCKET_OPEN_MAX_RETRY = 3;
static final boolean LTE_AVAILABLE_ON_CDMA =
- SystemProperties.getBoolean("ro.mot.lte_on_cdma", false);
+ SystemProperties.getBoolean(TelephonyProperties.PROPERTY_NETWORK_LTE_ON_CDMA, false);
//***** Class Variables
@@ -160,7 +160,8 @@
return Phone.PHONE_TYPE_CDMA;
case RILConstants.NETWORK_MODE_LTE_ONLY:
- if (SystemProperties.getBoolean("ro.mot.lte_on_cdma", false)) {
+ if (SystemProperties.getBoolean(TelephonyProperties.PROPERTY_NETWORK_LTE_ON_CDMA,
+ false)) {
return Phone.PHONE_TYPE_CDMA;
} else {
return Phone.PHONE_TYPE_GSM;
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index 1d194d0..88aed28 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -639,7 +639,8 @@
mPhoneType = RILConstants.CDMA_PHONE;
break;
case RILConstants.NETWORK_MODE_LTE_ONLY:
- if (SystemProperties.getBoolean("ro.mot.lte_on_cdma", false)) {
+ if (SystemProperties.getBoolean(TelephonyProperties.PROPERTY_NETWORK_LTE_ON_CDMA,
+ false)) {
mPhoneType = RILConstants.CDMA_PHONE;
} else {
mPhoneType = RILConstants.GSM_PHONE;
@@ -1396,33 +1397,29 @@
if(mInitialRadioStateChange) {
synchronized (mStateMonitor) {
if (!mState.isOn()) {
- RILRequest rrPnt = RILRequest.obtain(
- RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, null);
-
- rrPnt.mp.writeInt(1);
- rrPnt.mp.writeInt(mNetworkMode);
- if (RILJ_LOGD) riljLog(rrPnt.serialString() + "> "
- + requestToString(rrPnt.mRequest) + " : " + mNetworkMode);
-
- send(rrPnt);
+ setPreferredNetworkType(mNetworkMode, null);
RILRequest rrCs = RILRequest.obtain(
RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, null);
rrCs.mp.writeInt(1);
rrCs.mp.writeInt(mCdmaSubscription);
- if (RILJ_LOGD) riljLog(rrCs.serialString() + "> "
- + requestToString(rrCs.mRequest) + " : " + mCdmaSubscription);
+ if (RILJ_LOGD) {
+ riljLog(rrCs.serialString() + "> "
+ + requestToString(rrCs.mRequest) + " : " + mCdmaSubscription);
+ }
send(rrCs);
}
}
}
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_RADIO_POWER, result);
+ RILRequest rr = RILRequest.obtain(RIL_REQUEST_RADIO_POWER, result);
rr.mp.writeInt(1);
rr.mp.writeInt(on ? 1 : 0);
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+ if (RILJ_LOGD) {
+ riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+ + (on ? " on" : " off"));
+ }
send(rr);
}
@@ -2071,17 +2068,10 @@
*/
if (RILJ_LOGD) Log.d(LOG_TAG, "Radio ON @ init; reset to OFF");
setRadioPower(false, null);
- // MultimodeRIL needs to know the preferred network at power up.
- RILRequest rrPnt = RILRequest.obtain(
- RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, null);
- rrPnt.mp.writeInt(1);
- rrPnt.mp.writeInt(mNetworkMode);
- if (RILJ_LOGD) riljLog(rrPnt.serialString() + "> "
- + requestToString(rrPnt.mRequest) + " : " + mNetworkMode);
- send(rrPnt);
} else {
if (DBG) Log.d(LOG_TAG, "Radio OFF @ init");
setRadioState(newState);
+ setPreferredNetworkType(mNetworkMode, null);
}
mInitialRadioStateChange = false;
} else {
diff --git a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
index 912f75e..3905415 100644
--- a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -320,7 +320,7 @@
Registrant r = new Registrant(h, what, obj);
mDetachedRegistrants.add(r);
- if (getCurrentDataConnectionState() == ServiceState.STATE_OUT_OF_SERVICE) {
+ if (getCurrentDataConnectionState() != ServiceState.STATE_IN_SERVICE) {
r.notifyRegistrant();
}
}
diff --git a/telephony/java/com/android/internal/telephony/TelephonyProperties.java b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
index e6189be..c4fab66 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyProperties.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
@@ -72,6 +72,11 @@
*/
static final String PROPERTY_OPERATOR_ISO_COUNTRY = "gsm.operator.iso-country";
+ /** 'true' if device supports both LTE and CDMA mode of operation.
+ * Availability: Set only on devices supporting LTE and CDMA.
+ */
+ static final String PROPERTY_NETWORK_LTE_ON_CDMA = "ro.telephony.lte_on_cdma";
+
static final String CURRENT_ACTIVE_PHONE = "gsm.current.phone-type";
//****** SIM Card
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
index 1a0dbc2..4f27e7f 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
@@ -33,8 +33,8 @@
private static final String LOG_TAG = "CDMA";
// ***** Constructor
- private CdmaDataConnection(CDMAPhone phone, String name, RetryManager rm) {
- super(phone, name, rm);
+ private CdmaDataConnection(CDMAPhone phone, String name, int id, RetryManager rm) {
+ super(phone, name, id, rm);
}
/**
@@ -49,11 +49,10 @@
synchronized (mCountLock) {
mCount += 1;
}
- CdmaDataConnection cdmaDc = new CdmaDataConnection(phone,
- "CdmaDataConnection-" + mCount, rm);
+ CdmaDataConnection cdmaDc = new CdmaDataConnection(phone, "CdmaDataConnection-" + mCount,
+ id, rm);
cdmaDc.start();
if (DBG) cdmaDc.log("Made " + cdmaDc.getName());
- cdmaDc.mId = id;
return cdmaDc;
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
index 81cfead..345d0d9 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -328,7 +328,7 @@
setState(State.CONNECTED);
notifyDataConnection(reason);
startNetStatPoll();
- mRetryMgr.resetRetryCount();
+ mDataConnections.get(0).resetRetryCount();
}
private void resetPollStats() {
@@ -478,7 +478,7 @@
* at the last time until the state is changed.
* TODO: Make this configurable?
*/
- int nextReconnectDelay = mRetryMgr.getRetryTimer();
+ int nextReconnectDelay = mDataConnections.get(0).getRetryTimer();
log("Data Connection activate failed. Scheduling next attempt for "
+ (nextReconnectDelay / 1000) + "s");
@@ -492,7 +492,7 @@
SystemClock.elapsedRealtime() + nextReconnectDelay,
mReconnectIntent);
- mRetryMgr.increaseRetryCount();
+ mDataConnections.get(0).increaseRetryCount();
if (!shouldPostNotification(lastFailCauseCode)) {
log("NOT Posting Data Connection Unavailable notification "
@@ -593,7 +593,7 @@
*/
@Override
protected void onRadioOffOrNotAvailable() {
- mRetryMgr.resetRetryCount();
+ mDataConnections.get(0).resetRetryCount();
if (mPhone.getSimulatedRadioControl() != null) {
// Assume data is connected on the simulator
@@ -708,7 +708,7 @@
}
notifyDataAvailability(Phone.REASON_VOICE_CALL_ENDED);
} else {
- mRetryMgr.resetRetryCount();
+ mDataConnections.get(0).resetRetryCount();
// in case data setup was attempted when we were on a voice call
trySetupData(Phone.REASON_VOICE_CALL_ENDED);
}
@@ -729,20 +729,19 @@
private void createAllDataConnectionList() {
CdmaDataConnection dataConn;
- /** TODO: Use one retry manager for all connections for now */
- RetryManager rm = mRetryMgr;
- if (!rm.configure(SystemProperties.get("ro.cdma.data_retry_config"))) {
- if (!rm.configure(DEFAULT_DATA_RETRY_CONFIG)) {
- // Should never happen, log an error and default to a simple linear sequence.
- log("Could not configure using DEFAULT_DATA_RETRY_CONFIG="
- + DEFAULT_DATA_RETRY_CONFIG);
- rm.configure(20, 2000, 1000);
- }
- }
-
+ String retryConfig = SystemProperties.get("ro.cdma.data_retry_config");
for (int i = 0; i < DATA_CONNECTION_POOL_SIZE; i++) {
- int id = mUniqueIdGenerator.getAndIncrement();
+ RetryManager rm = new RetryManager();
+ if (!rm.configure(retryConfig)) {
+ if (!rm.configure(DEFAULT_DATA_RETRY_CONFIG)) {
+ // Should never happen, log an error and default to a simple linear sequence.
+ log("Could not configure using DEFAULT_DATA_RETRY_CONFIG="
+ + DEFAULT_DATA_RETRY_CONFIG);
+ rm.configure(20, 2000, 1000);
+ }
+ }
+ int id = mUniqueIdGenerator.getAndIncrement();
dataConn = CdmaDataConnection.makeDataConnection(mCdmaPhone, id, rm);
mDataConnections.put(id, dataConn);
}
@@ -761,7 +760,7 @@
} else {
if (mState == State.FAILED) {
cleanUpConnection(false, Phone.REASON_CDMA_DATA_DETACHED);
- mRetryMgr.resetRetryCount();
+ mDataConnections.get(0).resetRetryCount();
CdmaCellLocation loc = (CdmaCellLocation)(mPhone.getCellLocation());
EventLog.writeEvent(EventLogTags.CDMA_DATA_SETUP_FAILED,
@@ -779,7 +778,7 @@
switch (otaPrivision[0]) {
case Phone.CDMA_OTA_PROVISION_STATUS_COMMITTED:
case Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED:
- mRetryMgr.resetRetryCount();
+ mDataConnections.get(0).resetRetryCount();
break;
default:
break;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
index 2f4bd5b..386b636 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
@@ -387,12 +387,10 @@
}
if (hasCdmaDataConnectionAttached) {
- cdmaDataConnectionAttachedRegistrants.notifyRegistrants();
mAttachedRegistrants.notifyRegistrants();
}
if (hasCdmaDataConnectionDetached) {
- cdmaDataConnectionDetachedRegistrants.notifyRegistrants();
mDetachedRegistrants.notifyRegistrants();
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index f2b84ee..6966345 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -16,8 +16,6 @@
package com.android.internal.telephony.cdma;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC;
-
import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.DataConnectionTracker;
@@ -102,8 +100,6 @@
protected int cdmaDataConnectionState = ServiceState.STATE_OUT_OF_SERVICE;
protected int newCdmaDataConnectionState = ServiceState.STATE_OUT_OF_SERVICE;
protected int mRegistrationState = -1;
- protected RegistrantList cdmaDataConnectionAttachedRegistrants = new RegistrantList();
- protected RegistrantList cdmaDataConnectionDetachedRegistrants = new RegistrantList();
protected RegistrantList cdmaForSubscriptionInfoReadyRegistrants = new RegistrantList();
/**
@@ -1098,11 +1094,11 @@
}
if (hasCdmaDataConnectionAttached) {
- cdmaDataConnectionAttachedRegistrants.notifyRegistrants();
+ mAttachedRegistrants.notifyRegistrants();
}
if (hasCdmaDataConnectionDetached) {
- cdmaDataConnectionDetachedRegistrants.notifyRegistrants();
+ mDetachedRegistrants.notifyRegistrants();
}
if (hasCdmaDataConnectionChanged || hasNetworkTypeChanged) {
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
old mode 100644
new mode 100755
index cf06dab..12644c8
--- a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
@@ -34,6 +34,9 @@
import com.android.internal.util.BitwiseInputStream;
import com.android.internal.util.BitwiseOutputStream;
+import android.content.res.Resources;
+
+
/**
* An object to encode and decode CDMA SMS bearer data.
@@ -910,6 +913,16 @@
return true;
}
+ private static String decodeUtf8(byte[] data, int offset, int numFields)
+ throws CodingException
+ {
+ try {
+ return new String(data, offset, numFields, "UTF-8");
+ } catch (java.io.UnsupportedEncodingException ex) {
+ throw new CodingException("UTF-8 decode failed: " + ex);
+ }
+ }
+
private static String decodeUtf16(byte[] data, int offset, int numFields)
throws CodingException
{
@@ -994,9 +1007,15 @@
}
switch (userData.msgEncoding) {
case UserData.ENCODING_OCTET:
+ /*
+ * Octet decoding depends on the carrier service.
+ */
+ boolean decodingtypeUTF8 = Resources.getSystem()
+ .getBoolean(com.android.internal.R.bool.config_sms_utf8_support);
+
// Strip off any padding bytes, meaning any differences between the length of the
- // array and the target length specified by numFields. This is to avoid any confusion
- // by code elsewhere that only considers the payload array length.
+ // array and the target length specified by numFields. This is to avoid any
+ // confusion by code elsewhere that only considers the payload array length.
byte[] payload = new byte[userData.numFields];
int copyLen = userData.numFields < userData.payload.length
? userData.numFields : userData.payload.length;
@@ -1004,9 +1023,13 @@
System.arraycopy(userData.payload, 0, payload, 0, copyLen);
userData.payload = payload;
- // There are many devices in the market that send 8bit text sms (latin encoded) as
- // octet encoded.
- userData.payloadStr = decodeLatin(userData.payload, offset, userData.numFields);
+ if (!decodingtypeUTF8) {
+ // There are many devices in the market that send 8bit text sms (latin encoded) as
+ // octet encoded.
+ userData.payloadStr = decodeLatin(userData.payload, offset, userData.numFields);
+ } else {
+ userData.payloadStr = decodeUtf8(userData.payload, offset, userData.numFields);
+ }
break;
case UserData.ENCODING_IA5:
case UserData.ENCODING_7BIT_ASCII:
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
index 9f7673c..344486a 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
@@ -41,8 +41,8 @@
protected int mProfileId = RILConstants.DATA_PROFILE_DEFAULT;
protected String mActiveApnType = Phone.APN_TYPE_DEFAULT;
//***** Constructor
- private GsmDataConnection(PhoneBase phone, String name, RetryManager rm) {
- super(phone, name, rm);
+ private GsmDataConnection(PhoneBase phone, String name, int id, RetryManager rm) {
+ super(phone, name, id, rm);
}
/**
@@ -57,11 +57,10 @@
synchronized (mCountLock) {
mCount += 1;
}
- GsmDataConnection gsmDc = new GsmDataConnection(phone, "GsmDataConnection-" + mCount, rm);
+ GsmDataConnection gsmDc = new GsmDataConnection(phone, "GsmDataConnection-" + mCount,
+ id, rm);
gsmDc.start();
if (DBG) gsmDc.log("Made " + gsmDc.getName());
- gsmDc.mId = id;
- gsmDc.mRetryMgr = rm;
return gsmDc;
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index e06d63f..0f62907 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -546,7 +546,7 @@
ApnContext defaultApnContext = mApnContexts.get(Phone.APN_TYPE_DEFAULT);
if (defaultApnContext.getState() == State.FAILED) {
cleanUpConnection(false, defaultApnContext);
- mRetryMgr.resetRetryCount();
+ defaultApnContext.getDataConnection().resetRetryCount();
}
trySetupData(Phone.REASON_GPRS_ATTACHED, Phone.APN_TYPE_DEFAULT);
}
@@ -934,7 +934,7 @@
cleanUpAllConnections(isConnected, Phone.REASON_APN_CHANGED);
if (!isConnected) {
// TODO: Won't work for multiple connections!!!!
- mRetryMgr.resetRetryCount();
+ defaultApnContext.getDataConnection().resetRetryCount();
defaultApnContext.setReason(Phone.REASON_APN_CHANGED);
trySetupData(defaultApnContext);
}
@@ -1032,7 +1032,7 @@
mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
startNetStatPoll();
// reset reconnect timer
- mRetryMgr.resetRetryCount();
+ apnContext.getDataConnection().resetRetryCount();
}
// TODO: For multiple Active APNs not exactly sure how to do this.
@@ -1233,7 +1233,7 @@
return;
}
if (apnContext.getState() == State.FAILED) {
- if (!mRetryMgr.isRetryNeeded()) {
+ if (!apnContext.getDataConnection().isRetryNeeded()) {
if (!apnContext.getApnType().equals(Phone.APN_TYPE_DEFAULT)){
// if no more retries on a secondary APN attempt, tell the world and revert.
notifyDataConnection(Phone.REASON_APN_FAILED);
@@ -1241,18 +1241,18 @@
}
if (mReregisterOnReconnectFailure) {
// We've re-registerd once now just retry forever.
- mRetryMgr.retryForeverUsingLastTimeout();
+ apnContext.getDataConnection().retryForeverUsingLastTimeout();
} else {
// Try to Re-register to the network.
log("PDP activate failed, Reregistering to the network");
mReregisterOnReconnectFailure = true;
mPhone.getServiceStateTracker().reRegisterNetwork(null);
- mRetryMgr.resetRetryCount();
+ apnContext.getDataConnection().resetRetryCount();
return;
}
}
- int nextReconnectDelay = mRetryMgr.getRetryTimer();
+ int nextReconnectDelay = apnContext.getDataConnection().getRetryTimer();
log("PDP activate failed. Scheduling next attempt for "
+ (nextReconnectDelay / 1000) + "s");
@@ -1268,7 +1268,7 @@
SystemClock.elapsedRealtime() + nextReconnectDelay,
apnContext.getReconnectIntent());
- mRetryMgr.increaseRetryCount();
+ apnContext.getDataConnection().increaseRetryCount();
if (!shouldPostNotification(lastFailCauseCode)) {
Log.d(LOG_TAG, "NOT Posting GPRS Unavailable notification "
@@ -1308,14 +1308,12 @@
if (apnContext.getApnType().equals(Phone.APN_TYPE_DEFAULT)) {
log("onEnableNewApn default type");
ApnContext defaultApnContext = mApnContexts.get(Phone.APN_TYPE_DEFAULT);
- mRetryMgr = defaultApnContext.getDataConnection().getRetryMgr();
- mRetryMgr.resetRetryCount();
+ defaultApnContext.getDataConnection().resetRetryCount();
} else if (mApnToDataConnectionId.get(apnContext.getApnType()) == null) {
log("onEnableNewApn ApnType=" + apnContext.getApnType() +
" missing, make a new connection");
int id = createDataConnection(apnContext.getApnType());
- mRetryMgr = mDataConnections.get(id).getRetryMgr();
- mRetryMgr.resetRetryCount();
+ mDataConnections.get(id).resetRetryCount();
} else {
log("oneEnableNewApn connection already exists, nothing to setup");
}
@@ -1378,7 +1376,10 @@
protected void onRadioOffOrNotAvailable() {
// Make sure our reconnect delay starts at the initial value
// next time the radio comes on
- mRetryMgr.resetRetryCount();
+
+ for (DataConnection dc : mDataConnections.values()) {
+ dc.resetRetryCount();
+ }
mReregisterOnReconnectFailure = false;
if (mPhone.getSimulatedRadioControl() != null) {
@@ -1568,7 +1569,8 @@
}
} else {
// reset reconnect timer
- mRetryMgr.resetRetryCount();
+ ApnContext defaultApnContext = mApnContexts.get(Phone.APN_TYPE_DEFAULT);
+ defaultApnContext.getDataConnection().resetRetryCount();
mReregisterOnReconnectFailure = false;
// in case data setup was attempted when we were on a voice call
trySetupData(Phone.REASON_VOICE_CALL_ENDED, Phone.APN_TYPE_DEFAULT);
@@ -1686,17 +1688,6 @@
}
}
- private ApnSetting fetchDunApn() {
- Context c = mPhone.getContext();
- String apnData = Settings.Secure.getString(c.getContentResolver(),
- Settings.Secure.TETHER_DUN_APN);
- ApnSetting dunSetting = ApnSetting.fromString(apnData);
- if (dunSetting != null) return dunSetting;
-
- apnData = c.getResources().getString(R.string.config_tether_apndata);
- return ApnSetting.fromString(apnData);
- }
-
/**
* Build a list of APNs to be used to create PDP's.
*
@@ -1883,7 +1874,7 @@
// TODO: Should all PDN states be checked to fail?
if (mState == State.FAILED) {
cleanUpAllConnections(false, Phone.REASON_PS_RESTRICT_ENABLED);
- mRetryMgr.resetRetryCount();
+ resetAllRetryCounts();
mReregisterOnReconnectFailure = false;
}
trySetupData(Phone.REASON_PS_RESTRICT_ENABLED, Phone.APN_TYPE_DEFAULT);
diff --git a/telephony/java/com/android/internal/telephony/gsm/SimCard.java b/telephony/java/com/android/internal/telephony/gsm/SimCard.java
index 5a2f871..781746c 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SimCard.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SimCard.java
@@ -20,6 +20,7 @@
import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.PhoneBase;
+import com.android.internal.telephony.TelephonyProperties;
import android.os.SystemProperties;
/**
@@ -46,7 +47,7 @@
mPhone.mCM.registerForSIMReady(mHandler, EVENT_ICC_READY, null);
updateStateProperty();
- if(SystemProperties.getBoolean("ro.mot.lte_on_cdma", false)) {
+ if(SystemProperties.getBoolean(TelephonyProperties.PROPERTY_NETWORK_LTE_ON_CDMA, false)) {
mPhone.mCM.registerForNVReady(mHandler, EVENT_ICC_READY, null);
}
}
diff --git a/tests/HugeBackup/Android.mk b/tests/HugeBackup/Android.mk
new file mode 100644
index 0000000..4789bc8
--- /dev/null
+++ b/tests/HugeBackup/Android.mk
@@ -0,0 +1,15 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := HugeBackup
+
+LOCAL_SDK_VERSION := current
+
+LOCAL_PROGUARD_FLAG_FILES := proguard.flags
+
+include $(BUILD_PACKAGE)
diff --git a/tests/HugeBackup/AndroidManifest.xml b/tests/HugeBackup/AndroidManifest.xml
new file mode 100644
index 0000000..923881b
--- /dev/null
+++ b/tests/HugeBackup/AndroidManifest.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<!-- Declare the contents of this Android application. The namespace
+ attribute brings in the Android platform namespace, and the package
+ supplies a unique name for the application. When writing your
+ own application, the package name must be changed from "com.example.*"
+ to come from a domain that you own or have control over. -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.hugebackup"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <!-- The backup/restore mechanism was introduced in API version 8 -->
+ <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="8" />
+
+ <application android:label="Huge Backup"
+ android:backupAgent="HugeAgent">
+
+ <meta-data android:name="com.google.android.backup.api_key"
+ android:value="AEdPqrEAAAAINyoagzQOEEpIH3yw7LYCFN7CRX4FMd6TGIGVaA" />
+
+ <activity android:name="HugeBackupActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+</manifest>
diff --git a/tests/HugeBackup/proguard.flags b/tests/HugeBackup/proguard.flags
new file mode 100644
index 0000000..b4d01bf
--- /dev/null
+++ b/tests/HugeBackup/proguard.flags
@@ -0,0 +1,3 @@
+-keepclassmembers class com.android.hugebackup.HugeBackupActivity {
+ public void onRestoreButtonClick(android.view.View);
+}
diff --git a/tests/HugeBackup/res/layout/backup_restore.xml b/tests/HugeBackup/res/layout/backup_restore.xml
new file mode 100644
index 0000000..7f11984
--- /dev/null
+++ b/tests/HugeBackup/res/layout/backup_restore.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<!-- Layout description of the BackupRestore sample's main activity -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <ScrollView
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:layout_weight="1">
+
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <TextView android:text="@string/filling_text"
+ android:textSize="20dp"
+ android:layout_marginTop="20dp"
+ android:layout_marginBottom="10dp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+
+ <RadioGroup android:id="@+id/filling_group"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="20dp"
+ android:orientation="vertical">
+
+ <RadioButton android:id="@+id/bacon"
+ android:text="@string/bacon_label"/>
+ <RadioButton android:id="@+id/pastrami"
+ android:text="@string/pastrami_label"/>
+ <RadioButton android:id="@+id/hummus"
+ android:text="@string/hummus_label"/>
+
+ </RadioGroup>
+
+ <TextView android:text="@string/extras_text"
+ android:textSize="20dp"
+ android:layout_marginTop="20dp"
+ android:layout_marginBottom="10dp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+
+ <CheckBox android:id="@+id/mayo"
+ android:text="@string/mayo_text"
+ android:layout_marginLeft="20dp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+
+ <CheckBox android:id="@+id/tomato"
+ android:text="@string/tomato_text"
+ android:layout_marginLeft="20dp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+
+ </LinearLayout>
+
+ </ScrollView>
+
+ <Button android:id="@+id/restore_button"
+ android:text="@string/restore_text"
+ android:onClick="onRestoreButtonClick"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_weight="0" />
+
+</LinearLayout>
diff --git a/tests/HugeBackup/res/values/strings.xml b/tests/HugeBackup/res/values/strings.xml
new file mode 100644
index 0000000..c0b9226
--- /dev/null
+++ b/tests/HugeBackup/res/values/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources>
+ <string name="filling_text">Choose a sandwich filling:</string>
+ <string name="bacon_label">Bacon</string>
+ <string name="pastrami_label">Pastrami</string>
+ <string name="hummus_label">Hummus</string>
+
+ <string name="extras_text">Extras:</string>
+ <string name="mayo_text">Mayonnaise\?</string>
+ <string name="tomato_text">Tomato\?</string>
+
+ <string name="restore_text">Restore last data</string>
+</resources>
diff --git a/tests/HugeBackup/src/com/android/hugebackup/HugeAgent.java b/tests/HugeBackup/src/com/android/hugebackup/HugeAgent.java
new file mode 100644
index 0000000..f90bd9f
--- /dev/null
+++ b/tests/HugeBackup/src/com/android/hugebackup/HugeAgent.java
@@ -0,0 +1,261 @@
+/*
+ * 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 com.android.hugebackup;
+
+import android.app.backup.BackupAgent;
+import android.app.backup.BackupDataInput;
+import android.app.backup.BackupDataOutput;
+import android.os.ParcelFileDescriptor;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+/**
+ * This is the backup/restore agent class for the BackupRestore sample
+ * application. This particular agent illustrates using the backup and
+ * restore APIs directly, without taking advantage of any helper classes.
+ */
+public class HugeAgent extends BackupAgent {
+ /**
+ * We put a simple version number into the state files so that we can
+ * tell properly how to read "old" versions if at some point we want
+ * to change what data we back up and how we store the state blob.
+ */
+ static final int AGENT_VERSION = 1;
+
+ /**
+ * Pick an arbitrary string to use as the "key" under which the
+ * data is backed up. This key identifies different data records
+ * within this one application's data set. Since we only maintain
+ * one piece of data we don't need to distinguish, so we just pick
+ * some arbitrary tag to use.
+ */
+ static final String APP_DATA_KEY = "alldata";
+ static final String HUGE_DATA_KEY = "colossus";
+
+ /** The app's current data, read from the live disk file */
+ boolean mAddMayo;
+ boolean mAddTomato;
+ int mFilling;
+
+ /** The location of the application's persistent data file */
+ File mDataFile;
+
+ /** For convenience, we set up the File object for the app's data on creation */
+ @Override
+ public void onCreate() {
+ mDataFile = new File(getFilesDir(), HugeBackupActivity.DATA_FILE_NAME);
+ }
+
+ /**
+ * The set of data backed up by this application is very small: just
+ * two booleans and an integer. With such a simple dataset, it's
+ * easiest to simply store a copy of the backed-up data as the state
+ * blob describing the last dataset backed up. The state file
+ * contents can be anything; it is private to the agent class, and
+ * is never stored off-device.
+ *
+ * <p>One thing that an application may wish to do is tag the state
+ * blob contents with a version number. This is so that if the
+ * application is upgraded, the next time it attempts to do a backup,
+ * it can detect that the last backup operation was performed by an
+ * older version of the agent, and might therefore require different
+ * handling.
+ */
+ @Override
+ public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
+ ParcelFileDescriptor newState) throws IOException {
+ // First, get the current data from the application's file. This
+ // may throw an IOException, but in that case something has gone
+ // badly wrong with the app's data on disk, and we do not want
+ // to back up garbage data. If we just let the exception go, the
+ // Backup Manager will handle it and simply skip the current
+ // backup operation.
+ synchronized (HugeBackupActivity.sDataLock) {
+ RandomAccessFile file = new RandomAccessFile(mDataFile, "r");
+ mFilling = file.readInt();
+ mAddMayo = file.readBoolean();
+ mAddTomato = file.readBoolean();
+ }
+
+ // If the new state file descriptor is null, this is the first time
+ // a backup is being performed, so we know we have to write the
+ // data. If there <em>is</em> a previous state blob, we want to
+ // double check whether the current data is actually different from
+ // our last backup, so that we can avoid transmitting redundant
+ // data to the storage backend.
+ boolean doBackup = (oldState == null);
+ if (!doBackup) {
+ doBackup = compareStateFile(oldState);
+ }
+
+ // If we decided that we do in fact need to write our dataset, go
+ // ahead and do that. The way this agent backs up the data is to
+ // flatten it into a single buffer, then write that to the backup
+ // transport under the single key string.
+ if (doBackup) {
+ ByteArrayOutputStream bufStream = new ByteArrayOutputStream();
+
+ // We use a DataOutputStream to write structured data into
+ // the buffering stream
+ DataOutputStream outWriter = new DataOutputStream(bufStream);
+ outWriter.writeInt(mFilling);
+ outWriter.writeBoolean(mAddMayo);
+ outWriter.writeBoolean(mAddTomato);
+
+ // Okay, we've flattened the data for transmission. Pull it
+ // out of the buffering stream object and send it off.
+ byte[] buffer = bufStream.toByteArray();
+ int len = buffer.length;
+ data.writeEntityHeader(APP_DATA_KEY, len);
+ data.writeEntityData(buffer, len);
+
+ // ***** pathological behavior *****
+ // Now, in order to incur deliberate too-much-data failures,
+ // try to back up 20 MB of data besides what we already pushed.
+ final int MEGABYTE = 1024*1024;
+ final int NUM_MEGS = 20;
+ buffer = new byte[MEGABYTE];
+ data.writeEntityHeader(HUGE_DATA_KEY, NUM_MEGS * MEGABYTE);
+ for (int i = 0; i < NUM_MEGS; i++) {
+ data.writeEntityData(buffer, MEGABYTE);
+ }
+ }
+
+ // Finally, in all cases, we need to write the new state blob
+ writeStateFile(newState);
+ }
+
+ /**
+ * Helper routine - read a previous state file and decide whether to
+ * perform a backup based on its contents.
+ *
+ * @return <code>true</code> if the application's data has changed since
+ * the last backup operation; <code>false</code> otherwise.
+ */
+ boolean compareStateFile(ParcelFileDescriptor oldState) {
+ FileInputStream instream = new FileInputStream(oldState.getFileDescriptor());
+ DataInputStream in = new DataInputStream(instream);
+
+ try {
+ int stateVersion = in.readInt();
+ if (stateVersion > AGENT_VERSION) {
+ // Whoops; the last version of the app that backed up
+ // data on this device was <em>newer</em> than the current
+ // version -- the user has downgraded. That's problematic.
+ // In this implementation, we recover by simply rewriting
+ // the backup.
+ return true;
+ }
+
+ // The state data we store is just a mirror of the app's data;
+ // read it from the state file then return 'true' if any of
+ // it differs from the current data.
+ int lastFilling = in.readInt();
+ boolean lastMayo = in.readBoolean();
+ boolean lastTomato = in.readBoolean();
+
+ return (lastFilling != mFilling)
+ || (lastTomato != mAddTomato)
+ || (lastMayo != mAddMayo);
+ } catch (IOException e) {
+ // If something went wrong reading the state file, be safe
+ // and back up the data again.
+ return true;
+ }
+ }
+
+ /**
+ * Write out the new state file: the version number, followed by the
+ * three bits of data as we sent them off to the backup transport.
+ */
+ void writeStateFile(ParcelFileDescriptor stateFile) throws IOException {
+ FileOutputStream outstream = new FileOutputStream(stateFile.getFileDescriptor());
+ DataOutputStream out = new DataOutputStream(outstream);
+
+ out.writeInt(AGENT_VERSION);
+ out.writeInt(mFilling);
+ out.writeBoolean(mAddMayo);
+ out.writeBoolean(mAddTomato);
+ }
+
+ /**
+ * This application does not do any "live" restores of its own data,
+ * so the only time a restore will happen is when the application is
+ * installed. This means that the activity itself is not going to
+ * be running while we change its data out from under it. That, in
+ * turn, means that there is no need to send out any sort of notification
+ * of the new data: we only need to read the data from the stream
+ * provided here, build the application's new data file, and then
+ * write our new backup state blob that will be consulted at the next
+ * backup operation.
+ *
+ * <p>We don't bother checking the versionCode of the app who originated
+ * the data because we have never revised the backup data format. If
+ * we had, the 'appVersionCode' parameter would tell us how we should
+ * interpret the data we're about to read.
+ */
+ @Override
+ public void onRestore(BackupDataInput data, int appVersionCode,
+ ParcelFileDescriptor newState) throws IOException {
+ // We should only see one entity in the data stream, but the safest
+ // way to consume it is using a while() loop
+ while (data.readNextHeader()) {
+ String key = data.getKey();
+ int dataSize = data.getDataSize();
+
+ if (APP_DATA_KEY.equals(key)) {
+ // It's our saved data, a flattened chunk of data all in
+ // one buffer. Use some handy structured I/O classes to
+ // extract it.
+ byte[] dataBuf = new byte[dataSize];
+ data.readEntityData(dataBuf, 0, dataSize);
+ ByteArrayInputStream baStream = new ByteArrayInputStream(dataBuf);
+ DataInputStream in = new DataInputStream(baStream);
+
+ mFilling = in.readInt();
+ mAddMayo = in.readBoolean();
+ mAddTomato = in.readBoolean();
+
+ // Now we are ready to construct the app's data file based
+ // on the data we are restoring from.
+ synchronized (HugeBackupActivity.sDataLock) {
+ RandomAccessFile file = new RandomAccessFile(mDataFile, "rw");
+ file.setLength(0L);
+ file.writeInt(mFilling);
+ file.writeBoolean(mAddMayo);
+ file.writeBoolean(mAddTomato);
+ }
+ } else {
+ // Curious! This entity is data under a key we do not
+ // understand how to process. Just skip it.
+ data.skipEntityData();
+ }
+ }
+
+ // The last thing to do is write the state blob that describes the
+ // app's data as restored from backup.
+ writeStateFile(newState);
+ }
+}
diff --git a/tests/HugeBackup/src/com/android/hugebackup/HugeBackupActivity.java b/tests/HugeBackup/src/com/android/hugebackup/HugeBackupActivity.java
new file mode 100644
index 0000000..84e31aa
--- /dev/null
+++ b/tests/HugeBackup/src/com/android/hugebackup/HugeBackupActivity.java
@@ -0,0 +1,214 @@
+/*
+ * 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 com.android.hugebackup;
+
+import android.app.Activity;
+import android.app.backup.BackupManager;
+import android.app.backup.RestoreObserver;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.RadioGroup;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+/**
+ * Deliberately back up waaaaaaay too much data. Cloned with some alterations
+ * from the Backup/Restore sample application.
+ */
+public class HugeBackupActivity extends Activity {
+ static final String TAG = "HugeBackupActivity";
+
+ /**
+ * We serialize access to our persistent data through a global static
+ * object. This ensures that in the unlikely event of the our backup/restore
+ * agent running to perform a backup while our UI is updating the file, the
+ * agent will not accidentally read partially-written data.
+ *
+ * <p>Curious but true: a zero-length array is slightly lighter-weight than
+ * merely allocating an Object, and can still be synchronized on.
+ */
+ static final Object[] sDataLock = new Object[0];
+
+ /** Also supply a global standard file name for everyone to use */
+ static final String DATA_FILE_NAME = "saved_data";
+
+ /** The various bits of UI that the user can manipulate */
+ RadioGroup mFillingGroup;
+ CheckBox mAddMayoCheckbox;
+ CheckBox mAddTomatoCheckbox;
+
+ /** Cache a reference to our persistent data file */
+ File mDataFile;
+
+ /** Also cache a reference to the Backup Manager */
+ BackupManager mBackupManager;
+
+ /** Set up the activity and populate its UI from the persistent data. */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ /** Establish the activity's UI */
+ setContentView(R.layout.backup_restore);
+
+ /** Once the UI has been inflated, cache the controls for later */
+ mFillingGroup = (RadioGroup) findViewById(R.id.filling_group);
+ mAddMayoCheckbox = (CheckBox) findViewById(R.id.mayo);
+ mAddTomatoCheckbox = (CheckBox) findViewById(R.id.tomato);
+
+ /** Set up our file bookkeeping */
+ mDataFile = new File(getFilesDir(), HugeBackupActivity.DATA_FILE_NAME);
+
+ /** It is handy to keep a BackupManager cached */
+ mBackupManager = new BackupManager(this);
+
+ /**
+ * Finally, build the UI from the persistent store
+ */
+ populateUI();
+ }
+
+ /**
+ * Configure the UI based on our persistent data, creating the
+ * data file and establishing defaults if necessary.
+ */
+ void populateUI() {
+ RandomAccessFile file;
+
+ // Default values in case there's no data file yet
+ int whichFilling = R.id.pastrami;
+ boolean addMayo = false;
+ boolean addTomato = false;
+
+ /** Hold the data-access lock around access to the file */
+ synchronized (HugeBackupActivity.sDataLock) {
+ boolean exists = mDataFile.exists();
+ try {
+ file = new RandomAccessFile(mDataFile, "rw");
+ if (exists) {
+ Log.v(TAG, "datafile exists");
+ whichFilling = file.readInt();
+ addMayo = file.readBoolean();
+ addTomato = file.readBoolean();
+ Log.v(TAG, " mayo=" + addMayo
+ + " tomato=" + addTomato
+ + " filling=" + whichFilling);
+ } else {
+ // The default values were configured above: write them
+ // to the newly-created file.
+ Log.v(TAG, "creating default datafile");
+ writeDataToFileLocked(file,
+ addMayo, addTomato, whichFilling);
+
+ // We also need to perform an initial backup; ask for one
+ mBackupManager.dataChanged();
+ }
+ } catch (IOException ioe) {
+ }
+ }
+
+ /** Now that we've processed the file, build the UI outside the lock */
+ mFillingGroup.check(whichFilling);
+ mAddMayoCheckbox.setChecked(addMayo);
+ mAddTomatoCheckbox.setChecked(addTomato);
+
+ /**
+ * We also want to record the new state when the user makes changes,
+ * so install simple observers that do this
+ */
+ mFillingGroup.setOnCheckedChangeListener(
+ new RadioGroup.OnCheckedChangeListener() {
+ public void onCheckedChanged(RadioGroup group,
+ int checkedId) {
+ // As with the checkbox listeners, rewrite the
+ // entire state file
+ Log.v(TAG, "New radio item selected: " + checkedId);
+ recordNewUIState();
+ }
+ });
+
+ CompoundButton.OnCheckedChangeListener checkListener
+ = new CompoundButton.OnCheckedChangeListener() {
+ public void onCheckedChanged(CompoundButton buttonView,
+ boolean isChecked) {
+ // Whichever one is altered, we rewrite the entire UI state
+ Log.v(TAG, "Checkbox toggled: " + buttonView);
+ recordNewUIState();
+ }
+ };
+ mAddMayoCheckbox.setOnCheckedChangeListener(checkListener);
+ mAddTomatoCheckbox.setOnCheckedChangeListener(checkListener);
+ }
+
+ /**
+ * Handy helper routine to write the UI data to a file.
+ */
+ void writeDataToFileLocked(RandomAccessFile file,
+ boolean addMayo, boolean addTomato, int whichFilling)
+ throws IOException {
+ file.setLength(0L);
+ file.writeInt(whichFilling);
+ file.writeBoolean(addMayo);
+ file.writeBoolean(addTomato);
+ Log.v(TAG, "NEW STATE: mayo=" + addMayo
+ + " tomato=" + addTomato
+ + " filling=" + whichFilling);
+ }
+
+ /**
+ * Another helper; this one reads the current UI state and writes that
+ * to the persistent store, then tells the backup manager that we need
+ * a backup.
+ */
+ void recordNewUIState() {
+ boolean addMayo = mAddMayoCheckbox.isChecked();
+ boolean addTomato = mAddTomatoCheckbox.isChecked();
+ int whichFilling = mFillingGroup.getCheckedRadioButtonId();
+ try {
+ synchronized (HugeBackupActivity.sDataLock) {
+ RandomAccessFile file = new RandomAccessFile(mDataFile, "rw");
+ writeDataToFileLocked(file, addMayo, addTomato, whichFilling);
+ }
+ } catch (IOException e) {
+ Log.e(TAG, "Unable to record new UI state");
+ }
+
+ mBackupManager.dataChanged();
+ }
+
+ /**
+ * Click handler, designated in the layout, that runs a restore of the app's
+ * most recent data when the button is pressed.
+ */
+ public void onRestoreButtonClick(View v) {
+ Log.v(TAG, "Requesting restore of our most recent data");
+ mBackupManager.requestRestore(
+ new RestoreObserver() {
+ public void restoreFinished(int error) {
+ /** Done with the restore! Now draw the new state of our data */
+ Log.v(TAG, "Restore finished, error = " + error);
+ populateUI();
+ }
+ }
+ );
+ }
+}
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/TextActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/TextActivity.java
index e7f431c..3c8432e 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/TextActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/TextActivity.java
@@ -58,10 +58,12 @@
mScaledPaint = new Paint();
mScaledPaint.setAntiAlias(true);
mScaledPaint.setTextSize(16.0f);
+ mScaledPaint.setShadowLayer(3.0f, 3.0f, 3.0f, 0xff00ff00);
mSkewPaint = new Paint();
mSkewPaint.setAntiAlias(true);
- mSkewPaint.setTextSize(16.0f);
+ mSkewPaint.setTextSize(16.0f);
+ mSkewPaint.setShadowLayer(3.0f, 3.0f, 3.0f, 0xff000000);
}
@Override
@@ -106,11 +108,11 @@
mStrikePaint.setUnderlineText(true);
mSkewPaint.setTextSkewX(-0.25f);
- canvas.drawText("Hello OpenGL renderer!", 680, 200, mSkewPaint);
+ canvas.drawText("Hello OpenGL renderer!", 980, 200, mSkewPaint);
mSkewPaint.setTextSkewX(0.5f);
- canvas.drawText("Hello OpenGL renderer!", 680, 230, mSkewPaint);
+ canvas.drawText("Hello OpenGL renderer!", 980, 230, mSkewPaint);
mSkewPaint.setTextSkewX(0.0f);
- canvas.drawText("Hello OpenGL renderer!", 680, 260, mSkewPaint);
+ canvas.drawText("Hello OpenGL renderer!", 980, 260, mSkewPaint);
mScaledPaint.setTextScaleX(0.5f);
canvas.drawText("Hello OpenGL renderer!", 500, 200, mScaledPaint);
@@ -125,4 +127,4 @@
canvas.restore();
}
}
-}
\ No newline at end of file
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
index 6c9f48f..db14e53 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
@@ -28,10 +28,12 @@
import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.geom.Area;
+import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
+import java.awt.geom.RoundRectangle2D;
/**
* Delegate implementing the native methods of android.graphics.Path
@@ -331,58 +333,91 @@
@LayoutlibDelegate
/*package*/ static void native_addOval(int nPath, RectF oval, int dir) {
- // FIXME
- Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
- "Path.addOval is not supported.", null, null /*data*/);
+ Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+ if (pathDelegate == null) {
+ return;
+ }
+
+ pathDelegate.mPath.append(new Ellipse2D.Float(
+ oval.left, oval.top, oval.width(), oval.height()), false);
}
@LayoutlibDelegate
/*package*/ static void native_addCircle(int nPath, float x, float y, float radius, int dir) {
- // FIXME
- Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
- "Path.addCircle is not supported.", null, null /*data*/);
+ Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+ if (pathDelegate == null) {
+ return;
+ }
+
+ // because x/y is the center of the circle, need to offset this by the radius
+ pathDelegate.mPath.append(new Ellipse2D.Float(
+ x - radius, y - radius, radius * 2, radius * 2), false);
}
@LayoutlibDelegate
/*package*/ static void native_addArc(int nPath, RectF oval,
float startAngle, float sweepAngle) {
- // FIXME
- Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
- "Path.addArc is not supported.", null, null /*data*/);
+ Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+ if (pathDelegate == null) {
+ return;
+ }
+
+ // because x/y is the center of the circle, need to offset this by the radius
+ pathDelegate.mPath.append(new Arc2D.Float(
+ oval.left, oval.top, oval.width(), oval.height(),
+ startAngle, sweepAngle, Arc2D.OPEN), false);
}
@LayoutlibDelegate
- /*package*/ static void native_addRoundRect(int nPath, RectF rect,
- float rx, float ry, int dir) {
- // FIXME
- Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
- "Path.addRoundRect is not supported.", null, null /*data*/);
+ /*package*/ static void native_addRoundRect(
+ int nPath, RectF rect, float rx, float ry, int dir) {
+
+ Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+ if (pathDelegate == null) {
+ return;
+ }
+
+ pathDelegate.mPath.append(new RoundRectangle2D.Float(
+ rect.left, rect.top, rect.width(), rect.height(), rx * 2, ry * 2), false);
}
@LayoutlibDelegate
- /*package*/ static void native_addRoundRect(int nPath, RectF r, float[] radii, int dir) {
- // FIXME
- Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
- "Path.addRoundRect is not supported.", null, null /*data*/);
+ /*package*/ static void native_addRoundRect(int nPath, RectF rect, float[] radii, int dir) {
+ // Java2D doesn't support different rounded corners in each corner, so just use the
+ // first value.
+ native_addRoundRect(nPath, rect, radii[0], radii[1], dir);
+
+ // there can be a case where this API is used but with similar values for all corners, so
+ // in that case we don't warn.
+ // we only care if 2 corners are different so just compare to the next one.
+ for (int i = 0 ; i < 3 ; i++) {
+ if (radii[i * 2] != radii[(i + 1) * 2] || radii[i * 2 + 1] != radii[(i + 1) * 2 + 1]) {
+ Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+ "Different corner sizes are not supported in Path.addRoundRect.",
+ null, null /*data*/);
+ break;
+ }
+ }
}
@LayoutlibDelegate
/*package*/ static void native_addPath(int nPath, int src, float dx, float dy) {
- // FIXME
- Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
- "Path.addPath is not supported.", null, null /*data*/);
+ addPath(nPath, src, AffineTransform.getTranslateInstance(dx, dy));
}
@LayoutlibDelegate
/*package*/ static void native_addPath(int nPath, int src) {
- native_addPath(nPath, src, 0, 0);
+ addPath(nPath, src, null /*transform*/);
}
@LayoutlibDelegate
/*package*/ static void native_addPath(int nPath, int src, int matrix) {
- // FIXME
- Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
- "Path.addPath is not supported.", null, null /*data*/);
+ Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(matrix);
+ if (matrixDelegate == null) {
+ return;
+ }
+
+ addPath(nPath, src, matrixDelegate.getAffineTransform());
}
@LayoutlibDelegate
@@ -487,6 +522,26 @@
return null;
}
+ private static void addPath(int destPath, int srcPath, AffineTransform transform) {
+ Path_Delegate destPathDelegate = sManager.getDelegate(destPath);
+ if (destPathDelegate == null) {
+ return;
+ }
+
+ Path_Delegate srcPathDelegate = sManager.getDelegate(srcPath);
+ if (srcPathDelegate == null) {
+ return;
+ }
+
+ if (transform != null) {
+ destPathDelegate.mPath.append(
+ srcPathDelegate.mPath.getPathIterator(transform), false);
+ } else {
+ destPathDelegate.mPath.append(srcPathDelegate.mPath, false);
+ }
+ }
+
+
/**
* Returns whether the path is empty.
* @return true if the path is empty.
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index acc7379..e6e9647 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -192,7 +192,7 @@
Capability.UNBOUND_RENDERING,
Capability.CUSTOM_BACKGROUND_COLOR,
Capability.RENDER,
- Capability.LAYOUT_ONLY,
+ //Capability.LAYOUT_ONLY, // disable to run on ADT 10.0 which doesn't include this.
Capability.EMBEDDED_LAYOUT,
Capability.VIEW_MANIPULATION,
Capability.PLAY_ANIMATION,
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
index c1d7600..138a455 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
@@ -412,9 +412,7 @@
return LayoutParams.MATCH_PARENT;
} else if (s.equals(BridgeConstants.WRAP_CONTENT)) {
return LayoutParams.WRAP_CONTENT;
- }
-
- if (RenderResources.REFERENCE_NULL.equals(s)) {
+ } else if (RenderResources.REFERENCE_NULL.equals(s)) {
return defValue;
}
@@ -486,23 +484,32 @@
return LayoutParams.MATCH_PARENT;
} else if (s.equals(BridgeConstants.WRAP_CONTENT)) {
return LayoutParams.WRAP_CONTENT;
- }
-
- if (RenderResources.REFERENCE_NULL.equals(s)) {
+ } else if (RenderResources.REFERENCE_NULL.equals(s)) {
return defValue;
}
- // FIXME huh?
+ if (ResourceHelper.stringToFloat(s, mValue)) {
+ float f = mValue.getDimension(mBridgeResources.mMetrics);
- float f = getDimension(index, defValue);
- final int res = (int)(f+0.5f);
- if (res != 0) return res;
- if (f == 0) return 0;
- if (f > 0) return 1;
+ if (f < 0) {
+ // negative values are not allowed in pixel dimensions
+ Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+ "Negative pixel dimension: " + s,
+ null, null /*data*/);
+ return defValue;
+ }
- Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
- "Can't convert to dimension: " + Integer.toString(index),
- null, null /*data*/);
+ if (f == 0) return 0;
+ if (f < 1) return 1;
+
+ return (int)(f+0.5f);
+ }
+
+ // looks like we were unable to resolve the dimension value
+ Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
+ String.format(
+ "\"%1$s\" in attribute \"%2$s\" is not a valid format.",
+ s, mNames[index]), null /*data*/);
return defValue;
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
index 69f46e6..649160e 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
@@ -377,7 +377,7 @@
}
// check the first character
- if (buf[0] < '0' && buf[0] > '9' && buf[0] != '.') {
+ if (buf[0] < '0' && buf[0] > '9' && buf[0] != '.' && buf[0] != '-') {
return false;
}
diff --git a/voip/java/android/net/rtp/AudioCodec.java b/voip/java/android/net/rtp/AudioCodec.java
index 3877aeb..85255c8 100644
--- a/voip/java/android/net/rtp/AudioCodec.java
+++ b/voip/java/android/net/rtp/AudioCodec.java
@@ -33,7 +33,6 @@
* </pre>
*
* @see AudioStream
- * @hide
*/
public class AudioCodec {
/**
diff --git a/voip/java/android/net/rtp/AudioGroup.java b/voip/java/android/net/rtp/AudioGroup.java
index 20c8969..3e7ace8 100644
--- a/voip/java/android/net/rtp/AudioGroup.java
+++ b/voip/java/android/net/rtp/AudioGroup.java
@@ -59,7 +59,6 @@
* the AudioGroups is in use.</p>
*
* @see AudioStream
- * @hide
*/
public class AudioGroup {
/**
diff --git a/voip/java/android/net/rtp/AudioStream.java b/voip/java/android/net/rtp/AudioStream.java
index b45cc5e..d761214 100644
--- a/voip/java/android/net/rtp/AudioStream.java
+++ b/voip/java/android/net/rtp/AudioStream.java
@@ -41,7 +41,6 @@
*
* @see RtpStream
* @see AudioGroup
- * @hide
*/
public class AudioStream extends RtpStream {
private AudioCodec mCodec;
diff --git a/voip/java/android/net/rtp/RtpStream.java b/voip/java/android/net/rtp/RtpStream.java
index 87d8bc6..e94ac42 100644
--- a/voip/java/android/net/rtp/RtpStream.java
+++ b/voip/java/android/net/rtp/RtpStream.java
@@ -27,7 +27,6 @@
*
* <p class="note">Using this class requires
* {@link android.Manifest.permission#INTERNET} permission.</p>
- * @hide
*/
public class RtpStream {
/**