Merge "Initial commit of GLESv2 debugger server"
diff --git a/api/current.xml b/api/current.xml
index a01658a..bc71bcc 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -28850,7 +28850,7 @@
deprecated="not deprecated"
visibility="public"
>
-<method name="completedDownload"
+<method name="addCompletedDownload"
return="long"
abstract="false"
native="false"
@@ -30386,9 +30386,26 @@
synchronized="false"
static="false"
final="false"
+ deprecated="deprecated"
+ visibility="public"
+>
+<parameter name="attrs" type="android.util.AttributeSet">
+</parameter>
+<parameter name="savedInstanceState" type="android.os.Bundle">
+</parameter>
+</method>
+<method name="onInflate"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
deprecated="not deprecated"
visibility="public"
>
+<parameter name="activity" type="android.app.Activity">
+</parameter>
<parameter name="attrs" type="android.util.AttributeSet">
</parameter>
<parameter name="savedInstanceState" type="android.os.Bundle">
@@ -95440,6 +95457,32 @@
visibility="public"
>
</method>
+<method name="hasPermission"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="device" type="android.hardware.usb.UsbDevice">
+</parameter>
+</method>
+<method name="hasPermission"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="accessory" type="android.hardware.usb.UsbAccessory">
+</parameter>
+</method>
<method name="isFunctionEnabled"
return="boolean"
abstract="false"
@@ -95492,6 +95535,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"
@@ -95569,6 +95642,17 @@
visibility="public"
>
</field>
+<field name="EXTRA_PERMISSION_GRANTED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""permission""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="USB_CONFIGURATION"
type="java.lang.String"
transient="false"
@@ -105751,6 +105835,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"
@@ -105828,6 +105923,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"
@@ -105861,6 +105978,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"
@@ -118068,6 +118207,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"
@@ -143820,6 +144450,21 @@
<parameter name="key" type="java.lang.String">
</parameter>
</method>
+<method name="getCharSequence"
+ return="java.lang.CharSequence"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="key" type="java.lang.String">
+</parameter>
+<parameter name="defaultValue" type="java.lang.CharSequence">
+</parameter>
+</method>
<method name="getCharSequenceArray"
return="java.lang.CharSequence[]"
abstract="false"
@@ -144153,6 +144798,21 @@
<parameter name="key" type="java.lang.String">
</parameter>
</method>
+<method name="getString"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="key" type="java.lang.String">
+</parameter>
+<parameter name="defaultValue" type="java.lang.String">
+</parameter>
+</method>
<method name="getStringArray"
return="java.lang.String[]"
abstract="false"
@@ -194867,7 +195527,7 @@
synchronized="false"
static="false"
final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
<parameter name="contextStart" type="int">
@@ -206638,21 +207298,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"
@@ -218068,6 +218713,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"
@@ -218321,6 +218988,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"
@@ -218365,6 +219043,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"
@@ -218420,6 +219109,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"
@@ -244278,6 +244978,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"
@@ -266726,7 +267445,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="arg0" type="T">
+<parameter name="t" type="T">
</parameter>
</method>
</interface>
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 3a82c78..edfd6ef 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -4137,7 +4137,7 @@
fragment.mInLayout = true;
fragment.mImmediateActivity = this;
fragment.mFragmentManager = mFragments;
- fragment.onInflate(attrs, fragment.mSavedFragmentState);
+ fragment.onInflate(this, attrs, fragment.mSavedFragmentState);
mFragments.addFragment(fragment, true);
} else if (fragment.mInLayout) {
@@ -4156,7 +4156,7 @@
// from last saved state), then give it the attributes to
// initialize itself.
if (!fragment.mRetaining) {
- fragment.onInflate(attrs, fragment.mSavedFragmentState);
+ fragment.onInflate(this, attrs, fragment.mSavedFragmentState);
}
mFragments.moveToState(fragment);
}
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index b409f2f..bd83762 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -200,6 +200,8 @@
static Handler sMainThreadHandler; // set once in main()
+ Bundle mCoreSettings = null;
+
private static final class ActivityClientRecord {
IBinder token;
int ident;
@@ -354,7 +356,6 @@
boolean restrictedBackupMode;
Configuration config;
boolean handlingProfiling;
- Bundle coreSettings;
public String toString() {
return "AppBindData{appInfo=" + appInfo + "}";
}
@@ -559,6 +560,8 @@
ServiceManager.initServiceCache(services);
}
+ setCoreSettings(coreSettings);
+
AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
@@ -570,7 +573,6 @@
data.debugMode = debugMode;
data.restrictedBackupMode = isRestrictedBackupMode;
data.config = config;
- data.coreSettings = coreSettings;
queueOrSendMessage(H.BIND_APPLICATION, data);
}
@@ -898,8 +900,8 @@
pw.println(String.format(format, objs));
}
- public void setCoreSettings(Bundle settings) {
- queueOrSendMessage(H.SET_CORE_SETTINGS, settings);
+ public void setCoreSettings(Bundle coreSettings) {
+ queueOrSendMessage(H.SET_CORE_SETTINGS, coreSettings);
}
}
@@ -2720,10 +2722,8 @@
}
private void handleSetCoreSettings(Bundle coreSettings) {
- if (mBoundApplication != null) {
- synchronized (mBoundApplication) {
- mBoundApplication.coreSettings = coreSettings;
- }
+ synchronized (mPackages) {
+ mCoreSettings = coreSettings;
}
}
@@ -3990,13 +3990,9 @@
}
public int getIntCoreSetting(String key, int defaultValue) {
- if (mBoundApplication == null) {
- return defaultValue;
- }
- synchronized (mBoundApplication) {
- Bundle coreSettings = mBoundApplication.coreSettings;
- if (coreSettings != null) {
- return coreSettings.getInt(key, defaultValue);
+ synchronized (mPackages) {
+ if (mCoreSettings != null) {
+ return mCoreSettings.getInt(key, defaultValue);
} else {
return defaultValue;
}
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/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/Fragment.java b/core/java/android/app/Fragment.java
index 8982110f..53dc7c8 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -859,32 +859,57 @@
}
/**
+ * @deprecated Use {@link #onInflate(Activity, AttributeSet, Bundle)} instead.
+ */
+ @Deprecated
+ public void onInflate(AttributeSet attrs, Bundle savedInstanceState) {
+ mCalled = true;
+ }
+
+ /**
* Called when a fragment is being created as part of a view layout
* inflation, typically from setting the content view of an activity. This
- * will be called immediately after the fragment is created from a <fragment>
+ * may be called immediately after the fragment is created from a <fragment>
* tag in a layout file. Note this is <em>before</em> the fragment's
* {@link #onAttach(Activity)} has been called; all you should do here is
- * parse the attributes and save them away. A convenient thing to do is
- * simply copy them into a Bundle that is given to {@link #setArguments(Bundle)}.
+ * parse the attributes and save them away.
*
* <p>This is called every time the fragment is inflated, even if it is
- * being inflated into a new instance with saved state. Because a fragment's
- * arguments are retained across instances, it may make no sense to re-parse
- * the attributes into new arguments. You may want to first check
- * {@link #getArguments()} and only parse the attributes if it returns null,
- * the assumption being that if it is non-null those are the same arguments
- * from the first time the fragment was inflated. (That said, you may want
- * to have layouts change for different configurations such as landscape
- * and portrait, which can have different attributes. If so, you will need
- * to re-parse the attributes each time this is called to generate new
- * arguments.)</p>
+ * being inflated into a new instance with saved state. It typically makes
+ * sense to re-parse the parameters each time, to allow them to change with
+ * different configurations.</p>
+ *
+ * <p>Here is a typical implementation of a fragment that can take parameters
+ * both through attributes supplied here as well from {@link #getArguments()}:</p>
+ *
+ * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentArguments.java
+ * fragment}
+ *
+ * <p>Note that parsing the XML attributes uses a "styleable" resource. The
+ * declaration for the styleable used here is:</p>
+ *
+ * {@sample development/samples/ApiDemos/res/values/attrs.xml fragment_arguments}
*
+ * <p>The fragment can then be declared within its activity's content layout
+ * through a tag like this:</p>
+ *
+ * {@sample development/samples/ApiDemos/res/layout/fragment_arguments.xml from_attributes}
+ *
+ * <p>This fragment can also be created dynamically from arguments given
+ * at runtime in the arguments Bundle; here is an example of doing so at
+ * creation of the containing activity:</p>
+ *
+ * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentArguments.java
+ * create}
+ *
+ * @param activity The Activity that is inflating this fragment.
* @param attrs The attributes at the tag where the fragment is
* being created.
* @param savedInstanceState If the fragment is being re-created from
* a previous saved state, this is the state.
*/
- public void onInflate(AttributeSet attrs, Bundle savedInstanceState) {
+ public void onInflate(Activity activity, AttributeSet attrs, Bundle savedInstanceState) {
+ onInflate(attrs, savedInstanceState);
mCalled = true;
}
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index d8d0a5b..ab60cf0 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -660,6 +660,12 @@
}
if (f.mState < newState) {
+ // For fragments that are created from a layout, when restoring from
+ // state we don't want to allow them to be created until they are
+ // being reloaded from the layout.
+ if (f.mFromLayout && !f.mInLayout) {
+ return;
+ }
if (f.mAnimatingAway != null) {
// The fragment is currently being animated... but! Now we
// want to move our state back up. Give up on waiting for the
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/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl
index be65bdb..c79a458 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;
@@ -50,6 +51,25 @@
*/
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);
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index 6683179..9f1b8ea 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;
@@ -176,12 +178,24 @@
*/
public static final String EXTRA_ACCESSORY = "accessory";
- private IUsbManager mService;
+ /**
+ * Name of extra added to the {@link android.app.PendingIntent}
+ * passed into
+ * {#requestPermission(android.content.Context, android.hardware.usb.UsbDevice, android.app.PendingIntent)}
+ * or
+ * {#requestPermission(android.content.Context, android.hardware.usb.UsbAccessory, android.app.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;
}
@@ -245,7 +259,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 +274,87 @@
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.
+ *
+ * @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.
+ *
+ * @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 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.
+ * 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 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 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");
}
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/Bundle.java b/core/java/android/os/Bundle.java
index 8eac7aa..c288f8a 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -1028,7 +1028,6 @@
}
}
-
/**
* Returns the value associated with the given key, or null if
* no mapping of the desired type exists for the given key or a null
@@ -1052,6 +1051,28 @@
}
/**
+ * Returns the value associated with the given key, or defaultValue if
+ * no mapping of the desired type exists for the given key.
+ *
+ * @param key a String, or null
+ * @param defaultValue Value to return if key does not exist
+ * @return a String value, or null
+ */
+ public String getString(String key, String defaultValue) {
+ unparcel();
+ Object o = mMap.get(key);
+ if (o == null) {
+ return defaultValue;
+ }
+ try {
+ return (String) o;
+ } catch (ClassCastException e) {
+ typeWarning(key, o, "String", e);
+ return defaultValue;
+ }
+ }
+
+ /**
* Returns the value associated with the given key, or null if
* no mapping of the desired type exists for the given key or a null
* value is explicitly associated with the key.
@@ -1074,6 +1095,28 @@
}
/**
+ * Returns the value associated with the given key, or defaultValue if
+ * no mapping of the desired type exists for the given key.
+ *
+ * @param key a String, or null
+ * @param defaultValue Value to return if key does not exist
+ * @return a CharSequence value, or null
+ */
+ public CharSequence getCharSequence(String key, CharSequence defaultValue) {
+ unparcel();
+ Object o = mMap.get(key);
+ if (o == null) {
+ return defaultValue;
+ }
+ try {
+ return (CharSequence) o;
+ } catch (ClassCastException e) {
+ typeWarning(key, o, "CharSequence", e);
+ return defaultValue;
+ }
+ }
+
+ /**
* Returns the value associated with the given key, or null if
* no mapping of the desired type exists for the given key or a null
* value is explicitly associated with the key.
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/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 6d7b7ce..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.
*/
@@ -414,8 +416,10 @@
/**
* {@hide}
+ * Total number of cached speech parameters.
+ * This number should be equal to (max param position/2) + 1.
*/
- protected static final int NB_CACHED_PARAMS = 20;
+ protected static final int NB_CACHED_PARAMS = 10;
}
/**
@@ -577,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.
@@ -624,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;
}
@@ -681,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;
}
@@ -728,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;
}
@@ -788,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;
}
}
@@ -847,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;
}
}
@@ -899,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;
}
}
@@ -937,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;
}
@@ -975,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;
}
}
@@ -1030,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;
}
}
@@ -1075,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;
}
}
@@ -1139,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;
}
}
@@ -1189,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;
}
@@ -1231,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;
}
}
@@ -1291,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;
}
}
@@ -1364,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;
}
}
@@ -1407,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;
}
}
@@ -1445,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;
}
}
@@ -1484,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/SpannableStringBuilder.java b/core/java/android/text/SpannableStringBuilder.java
index 53fa7c2..ea5cdfe 100644
--- a/core/java/android/text/SpannableStringBuilder.java
+++ b/core/java/android/text/SpannableStringBuilder.java
@@ -1192,7 +1192,9 @@
* CURSOR_AT_OR_BEFORE, or CURSOR_AT
* @param p the Paint object that is requesting this information
* @return the offset of the next position, or -1
+ * @deprecated This is an internal method, refrain from using it in your code
*/
+ @Deprecated
public int getTextRunCursor(int contextStart, int contextEnd, int flags, int offset,
int cursorOpt, Paint p) {
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/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..11908bb 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -1606,13 +1606,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/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index ab4bfe1..6306274 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -1043,13 +1043,16 @@
// These ids need to be in sync with enum rawResId in PlatformBridge.h
private static final int NODOMAIN = 1;
private static final int LOADERROR = 2;
- private static final int DRAWABLEDIR = 3;
+ /* package */ static final int DRAWABLEDIR = 3;
private static final int FILE_UPLOAD_LABEL = 4;
private static final int RESET_LABEL = 5;
private static final int SUBMIT_LABEL = 6;
private static final int FILE_UPLOAD_NO_FILE_CHOSEN = 7;
- String getRawResFilename(int id) {
+ private String getRawResFilename(int id) {
+ return getRawResFilename(id, mContext);
+ }
+ /* package */ static String getRawResFilename(int id, Context context) {
int resid;
switch (id) {
case NODOMAIN:
@@ -1066,19 +1069,19 @@
break;
case FILE_UPLOAD_LABEL:
- return mContext.getResources().getString(
+ return context.getResources().getString(
com.android.internal.R.string.upload_file);
case RESET_LABEL:
- return mContext.getResources().getString(
+ return context.getResources().getString(
com.android.internal.R.string.reset);
case SUBMIT_LABEL:
- return mContext.getResources().getString(
+ return context.getResources().getString(
com.android.internal.R.string.submit);
case FILE_UPLOAD_NO_FILE_CHOSEN:
- return mContext.getResources().getString(
+ return context.getResources().getString(
com.android.internal.R.string.no_file_chosen);
default:
@@ -1086,7 +1089,7 @@
return "";
}
TypedValue value = new TypedValue();
- mContext.getResources().getValue(resid, value, true);
+ context.getResources().getValue(resid, value, true);
if (id == DRAWABLEDIR) {
String path = value.string.toString();
int index = path.lastIndexOf('/');
@@ -1237,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/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 47c69be..28b09519 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -415,7 +415,7 @@
}
CharSequence text = getText();
// Copy from the existing Layout.
- mLayout = new WebTextViewLayout(text, text, getPaint(), w,
+ mLayout = new WebTextViewLayout(text, text, getPaint(), mLayout.getWidth(),
mLayout.getAlignment(), mLayout.getSpacingMultiplier(),
mLayout.getSpacingAdd(), false, null, ellipsisWidth,
lineHeight);
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 975f815..a527afe 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -27,6 +27,7 @@
import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.database.DataSetObserver;
import android.graphics.Bitmap;
@@ -351,7 +352,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;
/**
@@ -847,6 +849,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;
/**
@@ -3001,7 +3006,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.
@@ -3011,7 +3017,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;
}
@@ -4017,15 +4023,10 @@
}
}
- 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);
}
private void onZoomAnimationStart() {
@@ -4098,7 +4099,7 @@
}
if (animateZoom) {
mZoomManager.animateZoom(canvas);
- } else {
+ } else if (!canvas.isHardwareAccelerated()) {
canvas.scale(mZoomManager.getScale(), mZoomManager.getScale());
}
@@ -4135,7 +4136,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;
@@ -5036,6 +5037,9 @@
* @hide pending API Council approval.
*/
public SearchBox getSearchBox() {
+ if ((mWebViewCore == null) || (mWebViewCore.getBrowserFrame() == null)) {
+ return null;
+ }
return mWebViewCore.getBrowserFrame().getSearchBox();
}
@@ -5062,6 +5066,8 @@
}
addAccessibilityApisToJavaScript();
+
+ mTouchEventQueue.reset();
}
@Override
@@ -5234,6 +5240,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;
@@ -5241,7 +5248,8 @@
} else {
mGLViewportEmpty = true;
}
- nativeUpdateDrawGLFunction(mGLViewportEmpty ? null : mGLRectViewport);
+ nativeUpdateDrawGLFunction(mGLViewportEmpty ? null : mGLRectViewport,
+ mGLViewportEmpty ? null : mViewRectViewport);
}
/**
@@ -5413,34 +5421,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;
}
/*
@@ -5560,6 +5551,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
@@ -5606,6 +5598,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) {
@@ -5787,6 +5780,7 @@
ted.mReprocess = mDeferTouchProcess;
ted.mNativeLayer = mScrollingLayer;
ted.mNativeLayerRect.set(mScrollingLayerRect);
+ ted.mSequence = mTouchEventQueue.nextTouchSequence();
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
}
mLastTouchUpTime = eventTime;
@@ -5809,6 +5803,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);
@@ -5933,7 +5928,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();
@@ -5948,6 +5943,7 @@
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);
@@ -5997,7 +5993,7 @@
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);
@@ -6025,6 +6021,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;
}
@@ -7102,6 +7099,297 @@
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 QueuedTouch mTouchEventQueue;
+ private QueuedTouch mQueuedTouchRecycleBin;
+ private int mQueuedTouchRecycleCount;
+ private static final int MAX_RECYCLED_QUEUED_TOUCH = 15;
+
+ private QueuedTouch obtainQueuedTouch() {
+ if (mQueuedTouchRecycleBin != null) {
+ QueuedTouch result = mQueuedTouchRecycleBin;
+ mQueuedTouchRecycleBin = result.mNext;
+ mQueuedTouchRecycleCount--;
+ return result;
+ }
+ return new QueuedTouch();
+ }
+
+ 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;
+ 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 (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();
+ 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 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
+ mIsHandlingMultiTouch = true;
+
+ handleMultiTouchInWebView(ev);
+ } 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);
+ }
+
+ 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.mAction == MotionEvent.ACTION_POINTER_UP &&
+ ted.mMotionEvent.getPointerCount() == 2) {
+ mIsHandlingMultiTouch = false;
+ }
+ if (!ted.mNativeResult) {
+ 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.
@@ -7217,6 +7505,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;
@@ -7262,7 +7551,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;
@@ -7325,7 +7614,10 @@
}
case WEBCORE_INITIALIZED_MSG_ID:
// nativeCreate sets mNativeClass to a non-zero value
- nativeCreate(msg.arg1);
+ String drawableDir = BrowserFrame.getRawResFilename(
+ BrowserFrame.DRAWABLEDIR, mContext);
+ AssetManager am = mContext.getAssets();
+ nativeCreate(msg.arg1, drawableDir, am);
break;
case UPDATE_TEXTFIELD_TEXT_MSG_ID:
// Make sure that the textfield is currently focused
@@ -7431,106 +7723,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:
@@ -8291,7 +8490,7 @@
private native Rect nativeCacheHitNodeBounds();
private native int nativeCacheHitNodePointer();
/* package */ native void nativeClearCursor();
- private native void nativeCreate(int ptr);
+ private native void nativeCreate(int ptr, String drawableDir, AssetManager am);
private native int nativeCursorFramePointer();
private native Rect nativeCursorNodeBounds();
private native int nativeCursorNodePointer();
@@ -8318,8 +8517,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,
@@ -8395,7 +8595,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..b920a30 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -825,6 +825,8 @@
MotionEvent mMotionEvent;
int mNativeLayer;
Rect mNativeLayerRect = new Rect();
+ long mSequence;
+ boolean mNativeResult;
}
static class GeolocationPermissionsData {
@@ -1332,13 +1334,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 28f64a9..942425af 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -16,6 +16,9 @@
package android.webkit;
+import java.util.LinkedList;
+import java.util.Queue;
+
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Canvas;
@@ -23,6 +26,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 +116,24 @@
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;
+
+ /*
+ * mFocusMovement keeps track of the total movement that the focus point
+ * has been through. Comparing to the difference of mCurrlen and mPrevLen,
+ * it determines if the gesture is for panning or zooming or both.
+ */
+ private static final int FOCUS_QUEUE_SIZE = 5;
+ private float mFocusMovementSum;
+ private Queue<Float> 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
@@ -169,7 +191,7 @@
private int mInitialScrollY;
private long mZoomStart;
- private static final int ZOOM_ANIMATION_LENGTH = 500;
+ private static final int ZOOM_ANIMATION_LENGTH = 175;
// whether support multi-touch
private boolean mSupportMultiTouch;
@@ -196,6 +218,8 @@
* viewport size is.
*/
setZoomOverviewWidth(WebView.DEFAULT_VIEWPORT_WIDTH);
+
+ mFocusMovementQueue = new LinkedList<Float>();
}
/**
@@ -715,10 +739,11 @@
}
private class ScaleDetectorListener implements ScaleGestureDetector.OnScaleGestureListener {
-
public boolean onScaleBegin(ScaleGestureDetector detector) {
mInitialZoomOverview = false;
dismissZoomPicker();
+ mFocusMovementSum = 0;
+ mFocusMovementQueue.clear();
mWebView.mViewManager.startZoom();
mWebView.onPinchToZoomAnimationStart();
return true;
@@ -729,6 +754,29 @@
float scale = Math.max(
computeScaleWithLimits(detector.getScaleFactor() * mActualScale),
getZoomOverviewScale());
+
+ 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));
+ mFocusMovementSum += focusDelta;
+ mFocusMovementQueue.add(focusDelta);
+ if (mFocusMovementQueue.size() > FOCUS_QUEUE_SIZE) {
+ mFocusMovementSum -= mFocusMovementQueue.remove();
+ }
+ float deltaSpan = Math.abs(detector.getCurrentSpan() - detector.getPreviousSpan());
+
+ // If the user moves the fingers but keeps the same distance between them,
+ // we should do panning only.
+ if (mFocusMovementSum > deltaSpan) {
+ mFocusMovementSum = 0;
+ mFocusMovementQueue.clear();
+ return true;
+ }
+
if (mPinchToZoomAnimating || willScaleTriggerZoom(scale)) {
mPinchToZoomAnimating = true;
// limit the scale change per step
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 2802144..af954c9 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -3015,8 +3015,23 @@
@Override
public boolean isOpaque() {
- return (mCachingActive && mIsCacheColorOpaque && mDividerIsOpaque &&
+ boolean retValue = (mCachingActive && mIsCacheColorOpaque && mDividerIsOpaque &&
hasOpaqueScrollbars()) || super.isOpaque();
+ if (retValue) {
+ // only return true if the list items cover the entire area of the view
+ 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 != null ? mListPadding.bottom : mPaddingBottom);
+ View last = getChildAt(getChildCount() - 1);
+ if (last == null || last.getBottom() < listBottom) {
+ return false;
+ }
+ }
+ return retValue;
}
@Override
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..70d71fb 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() {
@@ -4557,15 +4555,7 @@
* @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();
- }
+ // TODO remove
}
@Override
@@ -6285,15 +6275,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;
}
}
@@ -7356,14 +7346,9 @@
}
if (isTextEditable() || mTextIsSelectable) {
- if (mScrollX != oldScrollX || mScrollY != oldScrollY) {
+ if (mScrollX != oldScrollX || mScrollY != oldScrollY) { // TODO remove
// 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();
- }
+ hideInsertionPointCursorController(); // TODO any motion should hide it
}
if (touchIsFinished) {
@@ -7373,7 +7358,6 @@
handled |= imm != null && imm.showSoftInput(this, 0);
}
-
boolean selectAllGotFocus = mSelectAllOnFocus && didTouchFocusSelect();
if (!selectAllGotFocus && hasSelection()) {
startSelectionActionMode();
@@ -8653,26 +8637,31 @@
}
}
- private class HandleView extends View implements ViewTreeObserver.OnScrollChangedListener {
+ private class HandleView extends View implements ViewTreeObserver.OnPreDrawListener {
private Drawable mDrawable;
- private final ScrollingPopupWindow mContainer;
- private int mPositionX;
- private int mPositionY;
+ private final PopupWindow mContainer;
+ // Position with respect to the parent TextView
+ private int mPositionX, mPositionY;
private final CursorController mController;
private boolean mIsDragging;
- private float mTouchToWindowOffsetX;
- private float mTouchToWindowOffsetY;
+ // Offset from touch position to mPosition
+ private float mTouchToWindowOffsetX, mTouchToWindowOffsetY;
private 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;
+ // Parent's (TextView) position in window
+ private int mLastParentX, mLastParentY;
private float mDownPositionX, mDownPositionY;
+ // PopupWindow container absolute position with respect to the enclosing window
private int mContainerPositionX, mContainerPositionY;
- private long mTouchTimer;
+ // Visible or not (scrolled off screen), whether or not this handle should be visible
+ private boolean mIsActive = false;
+ // The insertion handle can have an associated PastePopupMenu
private boolean mIsInsertionHandle = false;
+ // Used to detect taps on the insertion handle, which will affect the PastePopupMenu
+ private long mTouchTimer;
private PastePopupMenu mPastePopupWindow;
// Touch-up filter: number of previous positions remembered
@@ -8684,12 +8673,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 +8691,7 @@
mNumberPreviousOffsets++;
}
- public void filterOnTouchUp() {
+ private void filterOnTouchUp() {
final long now = SystemClock.uptimeMillis();
int i = 0;
int index = mPreviousOffsetIndex;
@@ -8725,16 +8714,17 @@
public HandleView(CursorController controller, int pos) {
super(TextView.this.mContext);
mController = controller;
- mContainer = new ScrollingPopupWindow(TextView.this.mContext, null,
+ 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);
- setOrientation(pos);
+ setPosition(pos);
}
- public void setOrientation(int pos) {
+ private void setPosition(int pos) {
int handleWidth;
switch (pos) {
case LEFT: {
@@ -8774,38 +8764,48 @@
}
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();
+ } else {
+ mContainer.showAtLocation(TextView.this, 0,
+ mContainerPositionX, mContainerPositionY);
+
+ mIsActive = true;
+
+ ViewTreeObserver vto = TextView.this.getViewTreeObserver();
+ vto.addOnPreDrawListener(this);
+ }
+ }
+
+ private void dismiss() {
+ mIsDragging = false;
+ mContainer.dismiss();
hidePastePopupWindow();
}
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 +8829,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 +8854,59 @@
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];
+ }
+ // Hide paste popup window as soon as the handle is dragged.
+ hidePastePopupWindow();
+ }
+ }
- mContainer.update(TextView.this, mContainerPositionX, mContainerPositionY,
- mRight - mLeft, mBottom - mTop);
+ /**
+ * Updates the global container's position.
+ * @return whether or not the position has actually changed
+ */
+ private boolean updateContainerPosition() {
+ // TODO Prevent this using different HandleView subclasses
+ mController.updateOffset(this, mController.getCurrentOffset(this));
+ TextView.this.getLocationInWindow(mTempCoords);
+ final int containerPositionX = mTempCoords[0] + mPositionX;
+ final int containerPositionY = mTempCoords[1] + mPositionY;
- // Hide paste popup window as soon as a scroll occurs.
- hidePastePopupWindow();
+ 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
+ hidePastePopupWindow();
}
+ return true;
}
@Override
@@ -8979,7 +8992,7 @@
return mIsDragging;
}
- void positionAtCursor(final int offset) {
+ void positionAtCursor(int offset) {
addPositionToTouchUpFilter(offset);
final int width = mDrawable.getIntrinsicWidth();
final int height = mDrawable.getIntrinsicHeight();
@@ -9013,50 +9026,6 @@
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);
- }
}
private class InsertionPointCursorController implements CursorController {
@@ -9074,7 +9043,7 @@
}
public void show(int delayBeforePaste) {
- updatePosition();
+ getHandle().show();
hideDelayed();
removePastePopupCallback();
final long durationSinceCutOrCopy = SystemClock.uptimeMillis() - sLastCutOrCopyTime;
@@ -9213,7 +9182,6 @@
if (mEndHandle == null) mEndHandle = new HandleView(this, HandleView.RIGHT);
mIsShowing = true;
- updatePosition();
mStartHandle.show();
mEndHandle.show();
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/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/graphics/NinePatchPeeker.h b/core/jni/android/graphics/NinePatchPeeker.h
index 1f37b8b..8567e23 100644
--- a/core/jni/android/graphics/NinePatchPeeker.h
+++ b/core/jni/android/graphics/NinePatchPeeker.h
@@ -14,6 +14,9 @@
* limitations under the License.
*/
+#ifndef NinePatchPeeker_h
+#define NinePatchPeeker_h
+
#include "SkImageDecoder.h"
#include <utils/ResourceTypes.h>
@@ -40,3 +43,4 @@
virtual bool peek(const char tag[], const void* data, size_t length);
};
+#endif // NinePatchPeeker_h
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_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_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/ic_menu_copy_holo_dark.png b/core/res/res/drawable-hdpi/ic_menu_copy_holo_dark.png
new file mode 100644
index 0000000..852f146
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_menu_copy_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_copy_holo_light.png b/core/res/res/drawable-hdpi/ic_menu_copy_holo_light.png
new file mode 100644
index 0000000..ad09b37
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_menu_copy_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_cut_holo_dark.png b/core/res/res/drawable-hdpi/ic_menu_cut_holo_dark.png
new file mode 100644
index 0000000..7716a94
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_menu_cut_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_cut_holo_light.png b/core/res/res/drawable-hdpi/ic_menu_cut_holo_light.png
new file mode 100644
index 0000000..bea6db1
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_menu_cut_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_find_holo_dark.png b/core/res/res/drawable-hdpi/ic_menu_find_holo_dark.png
new file mode 100644
index 0000000..b888202
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_menu_find_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_find_holo_light.png b/core/res/res/drawable-hdpi/ic_menu_find_holo_light.png
new file mode 100644
index 0000000..b888202
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_menu_find_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_paste_holo_dark.png b/core/res/res/drawable-hdpi/ic_menu_paste_holo_dark.png
new file mode 100644
index 0000000..5579443
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_menu_paste_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_paste_holo_light.png b/core/res/res/drawable-hdpi/ic_menu_paste_holo_light.png
new file mode 100644
index 0000000..6674914
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_menu_paste_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_search_holo_dark.png b/core/res/res/drawable-hdpi/ic_menu_search_holo_dark.png
new file mode 100644
index 0000000..a7f9bbe
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_menu_search_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_share_holo_dark.png b/core/res/res/drawable-hdpi/ic_menu_share_holo_dark.png
new file mode 100644
index 0000000..2837615
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_menu_share_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_share_holo_light.png b/core/res/res/drawable-hdpi/ic_menu_share_holo_light.png
new file mode 100644
index 0000000..2837615
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_menu_share_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 477d820..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..9646e63 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..8c8e56a 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..b9407ba
--- /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..0090124
--- /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..16b75c6
--- /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..472c564
--- /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..d097577 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..f36cad8 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/ic_menu_copy_holo_dark.png b/core/res/res/drawable-mdpi/ic_menu_copy_holo_dark.png
new file mode 100644
index 0000000..35c3318
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_menu_copy_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_copy_holo_light.png b/core/res/res/drawable-mdpi/ic_menu_copy_holo_light.png
new file mode 100644
index 0000000..3b179d8
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_menu_copy_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_cut_holo_dark.png b/core/res/res/drawable-mdpi/ic_menu_cut_holo_dark.png
new file mode 100644
index 0000000..dfe8b4a
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_menu_cut_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_cut_holo_light.png b/core/res/res/drawable-mdpi/ic_menu_cut_holo_light.png
new file mode 100644
index 0000000..748dc9b
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_menu_cut_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_find_holo_dark.png b/core/res/res/drawable-mdpi/ic_menu_find_holo_dark.png
new file mode 100644
index 0000000..82dcba7
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_menu_find_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_find_holo_light.png b/core/res/res/drawable-mdpi/ic_menu_find_holo_light.png
new file mode 100644
index 0000000..82dcba7
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_menu_find_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_paste_holo_dark.png b/core/res/res/drawable-mdpi/ic_menu_paste_holo_dark.png
new file mode 100644
index 0000000..caec299
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_menu_paste_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_paste_holo_light.png b/core/res/res/drawable-mdpi/ic_menu_paste_holo_light.png
new file mode 100644
index 0000000..434f5d1
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_menu_paste_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_search_holo_dark.png b/core/res/res/drawable-mdpi/ic_menu_search_holo_dark.png
new file mode 100755
index 0000000..5d3155e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_menu_search_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_share_holo_dark.png b/core/res/res/drawable-mdpi/ic_menu_share_holo_dark.png
new file mode 100755
index 0000000..d89ca5f
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_menu_share_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_share_holo_light.png b/core/res/res/drawable-mdpi/ic_menu_share_holo_light.png
new file mode 100755
index 0000000..d89ca5f
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_menu_share_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..25fef56 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 477d820..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..9646e63 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..8c8e56a 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..b9407ba
--- /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..0090124
--- /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..16b75c6
--- /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..472c564
--- /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..d097577 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..f36cad8 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/menu/webview_copy.xml b/core/res/res/menu/webview_copy.xml
index ecb82b3..31bcec5 100644
--- a/core/res/res/menu/webview_copy.xml
+++ b/core/res/res/menu/webview_copy.xml
@@ -25,17 +25,17 @@
android:showAsAction="ifRoom|withText"
/>
<item android:id="@+id/share"
- android:icon="@drawable/ic_menu_share"
+ android:icon="?android:attr/actionModeShareDrawable"
android:title="@string/share"
android:showAsAction="ifRoom|withText"
/>
<item android:id="@+id/find"
- android:icon="@drawable/ic_menu_find"
+ android:icon="?android:attr/actionModeFindDrawable"
android:title="@string/find"
android:showAsAction="ifRoom|withText"
/>
<item android:id="@+id/websearch"
- android:icon="@drawable/ic_menu_search"
+ android:icon="?android:attr/actionModeWebSearchDrawable"
android:title="@string/websearch"
android:showAsAction="ifRoom|withText"
/>
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-es-rUS-xlarge/strings.xml b/core/res/res/values-es-rUS-xlarge/strings.xml
deleted file mode 100644
index b1409ba..0000000
--- a/core/res/res/values-es-rUS-xlarge/strings.xml
+++ /dev/null
@@ -1,337 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- XL -->
- <string name="fileSizeSuffix" msgid="3468563433835560758">"Segmento <xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
- <!-- XL -->
- <string name="unknownName" msgid="3202822008051920747">"(Desconocido)"</string>
- <!-- XL -->
- <string name="defaultVoiceMailAlphaTag" msgid="3668436100965334106">"Buzón de voz"</string>
- <!-- XL -->
- <string name="serviceClassVoice" msgid="7086876533404179039">"Google Voice"</string>
- <!-- XL -->
- <string name="cfTemplateNotForwarded" msgid="8534356655497306518">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: no se ha reenviado"</string>
- <!-- XL -->
- <string name="cfTemplateRegistered" msgid="1255841210142514510">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: no se ha reenviado"</string>
- <!-- XL -->
- <string name="cfTemplateRegisteredTime" msgid="7798907169190952367">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: no se ha reenviado"</string>
- <!-- XL -->
- <string name="notification_title" msgid="5210128823045542445">"Error al acceder a <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
- <!-- XL -->
- <string name="low_memory" product="tablet" msgid="4855646606241379548">"¡El espacio de almacenamiento de la tableta está completo! Elimina algunos archivos para liberar espacio."</string>
- <string name="low_memory" product="default" msgid="9195238880281578473">"¡El espacio de almacenamiento está completo! Elimina algunos archivos para liberar espacio."</string>
- <!-- XL -->
- <string name="power_dialog" product="tablet" msgid="6884163545695410971">"Opciones de tableta"</string>
- <string name="power_dialog" product="default" msgid="8882103237148972564">"Opciones de teléfono"</string>
- <!-- XL -->
- <string name="silent_mode" msgid="5687977677409351252">"Modo silencio"</string>
- <!-- XL -->
- <string name="shutdown_confirm" product="tablet" msgid="5776903973889956395">"Tu tableta se apagará."</string>
- <string name="shutdown_confirm" product="default" msgid="3040950969577046278">"Tu teléfono se apagará."</string>
- <!-- XL -->
- <string name="global_actions" product="tablet" msgid="110297659383505180">"Opciones de tableta"</string>
- <string name="global_actions" product="default" msgid="2108237350837066773">"Opciones de teléfono"</string>
- <!-- XL -->
- <string name="global_action_toggle_silent_mode" msgid="4538951049191334644">"Modo silencio"</string>
- <!-- XL -->
- <string name="global_action_silent_mode_off_status" msgid="9045822172493147761">"El sonido está ENCENDIDO"</string>
- <!-- XL -->
- <string name="global_actions_airplane_mode_on_status" msgid="7272433204482202219">"El modo avión está ENCENDIDO"</string>
- <!-- XL -->
- <string name="android_system_label" msgid="844561213652704593">"Sistema Androide"</string>
- <!-- XL -->
- <string name="permgroupdesc_costMoney" msgid="4836624191696189469">"Admitir que las aplicaciones realicen actividades que se cobran."</string>
- <!-- XL -->
- <string name="permgroupdesc_developmentTools" msgid="5514251182135739578">"Las funciones sólo son necesarias para los programadores de aplicaciones."</string>
- <!-- XL -->
- <string name="permgrouplab_storage" msgid="746210798053836644">"Almacenamiento"</string>
- <!-- XL -->
- <string name="permdesc_readSms" product="tablet" msgid="3026416194429353337">"Permite que la aplicación lea los mensajes SMS almacenados en tu tableta o tarjeta SIM. Las aplicaciones maliciosas pueden leer tus mensajes confidenciales."</string>
- <string name="permdesc_readSms" product="default" msgid="191875931331016383">"Admite que la aplicación lea los mensajes SMS almacenados en tu teléfono o tarjeta SIM. Las aplicaciones maliciosas pueden leer tus mensajes confidenciales."</string>
- <!-- XL -->
- <string name="permdesc_writeSms" product="tablet" msgid="692041754996169941">"Permite que la aplicación escriba a los mensajes SMS almacenados en tu tableta o tarjeta SIM. Las aplicaciones maliciosas pueden borrar tus mensajes."</string>
- <string name="permdesc_writeSms" product="default" msgid="1659315878254882599">"Admite que la aplicación escriba a los mensajes SMS almacenados en tu teléfono o tarjeta SIM. Las aplicaciones maliciosas pueden borrar tus mensajes."</string>
- <!-- XL -->
- <string name="permlab_forceStopPackages" msgid="1277034765943155677">"provocar la detención de otras aplicaciones"</string>
- <!-- XL -->
- <string name="permlab_forceBack" msgid="4272218642115232597">"cerrar la aplicación a la fuerza"</string>
- <!-- XL -->
- <string name="permdesc_injectEvents" product="tablet" msgid="6096352450860864899">"Permite que una aplicación ofrezca sus propios eventos de entrada (presionar teclas, etc.) a otras aplicaciones. Las aplicaciones maliciosas pueden utilizarlo para tomar el control de la tableta."</string>
- <string name="permdesc_injectEvents" product="default" msgid="2842435693076075109">"Admite una aplicación que ofrece sus propios eventos de entrada (presionar teclas, etc.) a otras aplicaciones. Las aplicaciones maliciosas pueden utilizarlo para tomar el control del teléfono."</string>
- <!-- XL -->
- <string name="permdesc_clearAppCache" product="tablet" msgid="1147333973960547529">"Permite que una aplicación libere espacio de almacenamiento en la tableta eliminando archivos del directorio de memoria caché de la aplicación. En general, el acceso es muy restringido para el proceso del sistema."</string>
- <string name="permdesc_clearAppCache" product="default" msgid="5790679870501740958">"Admite una aplicación que libera espacio de almacenamiento en el teléfono al eliminar archivos del directorio de memoria caché de la aplicación. En general, el acceso es muy restringido para el proceso del sistema."</string>
- <!-- XL -->
- <string name="permdesc_readLogs" product="tablet" msgid="3701009088710926065">"Permite que una aplicación lea diversos archivos de registro del sistema. Esto le permite descubrir información general acerca de lo que haces con la tableta, y puede potencialmente incluir información personal o privada."</string>
- <string name="permdesc_readLogs" product="default" msgid="8520101632251038537">"Admite una aplicación que lee diversos archivos de registro del sistema. Esto te permite descubrir información general acerca de lo que haces con el teléfono, y puede potencialmente incluir información personal o privada."</string>
- <!-- XL -->
- <string name="permdesc_changeComponentState" product="tablet" msgid="1791075936446230356">"Permite que una aplicación cambie si se debe activar o no un componente de otra aplicación. Las aplicaciones maliciosas pueden utilizarlo para desactivar funciones importantes de la tableta. Se debe tener cuidado con el permiso, ya que es posible que los componentes de la aplicación alcancen un estado inservible, imperfecto e inestable."</string>
- <string name="permdesc_changeComponentState" product="default" msgid="587130297076242796">"Permite que una aplicación cambie si se debe activar o no un componente de otra aplicación. Las aplicaciones maliciosas pueden utilizarlo para desactivar funciones importantes del teléfono. Se debe tener cuidado con el permiso, ya que es posible que los componentes de la aplicación alcancen un estado inservible, imperfecto e inestable."</string>
- <!-- XL -->
- <string name="permdesc_receiveBootCompleted" product="tablet" msgid="8660405432665162821">"Permite que una aplicación se inicie en cuanto el sistema haya finalizado la inicialización. Esto puede ocasionar que la tableta demore más en inicializar y que la aplicación retarde el funcionamiento total de la tableta al estar en ejecución constante."</string>
- <string name="permdesc_receiveBootCompleted" product="default" msgid="1827765096700833418">"Admite una aplicación que se inicia cuando el sistema haya finalizado la inicialización. Esto puede ocasionar que se demore más tiempo en inicializar el teléfono y que la aplicación retarde el funcionamiento total del teléfono al estar en ejecución constante."</string>
- <!-- XL -->
- <string name="permdesc_readContacts" product="tablet" msgid="1611730857475623952">"Permite que una aplicación lea todos los datos de de contacto (direcciones) almacenados en tu tableta. Las aplicaciones maliciosas pueden utilizarlo para enviar tus datos a otras personas."</string>
- <string name="permdesc_readContacts" product="default" msgid="6610535719925788049">"Admite una aplicación que lee todos los datos de (direcciones) de contactos almacenados en tu teléfono. Las aplicaciones maliciosas pueden utilizarlo para enviar tus eventos de calendario a otras personas."</string>
- <!-- XL -->
- <string name="permdesc_writeContacts" product="tablet" msgid="4572703488642353934">"Permite que una aplicación modifique los datos de (dirección) guardados en tu tableta. Las aplicaciones maliciosas pueden utilizarlo para borrar o modificar los datos de contacto."</string>
- <string name="permdesc_writeContacts" product="default" msgid="714397557711969040">"Admite una aplicación que modifica los datos de (dirección de) contacto guardados en tu teléfono. Las aplicaciones maliciosas pueden utilizarlo para borrar o modificar los datos de contacto."</string>
- <!-- XL -->
- <string name="permdesc_readCalendar" product="tablet" msgid="2991522150157238929">"Permite que una aplicación lea todos los eventos de calendario almacenados en tu tableta. Las aplicaciones maliciosas pueden utilizarlo para enviar tus eventos de calendario a otras personas."</string>
- <string name="permdesc_readCalendar" product="default" msgid="2618681024074734985">"Admite que una aplicación lea todos los eventos de calendario almacenados en tu teléfono. Las aplicaciones maliciosas pueden utilizarlo para enviar tus eventos de calendario a otras personas."</string>
- <!-- XL -->
- <string name="permdesc_accessFineLocation" product="tablet" msgid="9186984659787705379">"Accede a las fuentes de ubicación precisa, como el Sistema de posicionamiento global en la tableta, si está disponible. Las aplicaciones maliciosas pueden utilizarlo para determinar donde te encuentras y puede consumir energía adicional de la batería."</string>
- <string name="permdesc_accessFineLocation" product="default" msgid="7130852247133907221">"Accede a las fuentes de ubicación precisa, como el Sistema de posicionamiento global en el teléfono, si está disponible. Las aplicaciones maliciosas pueden utilizarlo para determinar donde te encuentras y puede consumir energía adicional de la batería."</string>
- <!-- XL -->
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="2943949975553225591">"Accede a las fuentes de ubicación aproximada, como la base de datos de la red de celulares, para determinar la ubicación aproximada de un tableta, si está disponible. Las aplicaciones maliciosas pueden utilizarlo para determinar aproximadamente dónde te encuentras."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7474972764638621839">"Accede a las fuentes de ubicación aproximada, como la base de datos de la red de celulares, para determinar una ubicación telefónica aproximada, si está disponible. Las aplicaciones maliciosas pueden utilizarlo para determinar aproximadamente donde te encuentras."</string>
- <!-- XL -->
- <string name="permlab_brick" product="tablet" msgid="6967130388106614085">"inhabilitar tableta de forma permanente"</string>
- <string name="permlab_brick" product="default" msgid="3120283238813720510">"desactivar teléfono de manera permanente"</string>
- <!-- XL -->
- <string name="permdesc_brick" product="tablet" msgid="8506097851567246888">"Permite que la aplicación desactive todo la tableta de manera permanente. Esto es muy peligroso."</string>
- <string name="permdesc_brick" product="default" msgid="6696459767254028146">"Admite que la aplicación desactive todo el teléfono de manera permanente. Esto es muy peligroso."</string>
- <!-- XL -->
- <string name="permlab_reboot" product="tablet" msgid="8299304590708874992">"forzar reinicio de la tableta"</string>
- <string name="permlab_reboot" product="default" msgid="7761230490609718232">"provocar el reinicio del teléfono"</string>
- <!-- XL -->
- <string name="permdesc_reboot" product="tablet" msgid="8289402537687518137">"Permite que la aplicación provoque el reinicio de la tableta."</string>
- <string name="permdesc_reboot" product="default" msgid="2425170170087532554">"Admite que la aplicación provoque que el teléfono se reinicie."</string>
- <!-- XL -->
- <string name="permlab_performCdmaProvisioning" product="tablet" msgid="1602175938040327630">"iniciar directamente la configuración CDMA de la tableta"</string>
- <string name="permlab_performCdmaProvisioning" product="default" msgid="2364447039211144234">"comienza directamente la configuración CDMA del teléfono"</string>
- <!-- XL -->
- <string name="permlab_checkinProperties" msgid="8770356116386811264">"acceder a las propiedades de registro"</string>
- <!-- XL -->
- <string name="permlab_bindGadget" msgid="2772444448613501375">"elegir controles"</string>
- <!-- XL -->
- <string name="permdesc_bindGadget" msgid="5172327215211875807">"Admite que la aplicación indique al sistema cuáles controles puede utilizar cada aplicación. Con este permiso, las aplicaciones pueden brindar acceso a los datos personales a otras aplicaciones. Las aplicaciones normales no deben utilizarlo."</string>
- <!-- XL -->
- <string name="permlab_wakeLock" product="tablet" msgid="8548785337425173690">"evitar que la tableta entre en estado de inactividad"</string>
- <string name="permlab_wakeLock" product="default" msgid="7590534090355174805">"evitar que el teléfono entre en estado de inactividad"</string>
- <!-- XL -->
- <string name="permdesc_wakeLock" product="tablet" msgid="6871828582124115814">"Permite que una aplicación evite que la tableta entre en estado de inactividad."</string>
- <string name="permdesc_wakeLock" product="default" msgid="1200311528451468554">"Admite una aplicación que evita que el teléfono entre en estado de inactividad."</string>
- <!-- XL -->
- <string name="permlab_devicePower" product="tablet" msgid="4737873025369971061">"apagar o encender la tableta"</string>
- <string name="permlab_devicePower" product="default" msgid="6879460773734563850">"apagar o encender el teléfono"</string>
- <!-- XL -->
- <string name="permdesc_devicePower" product="tablet" msgid="5930342678996327905">"Permite que una aplicación encienda o apague la tableta."</string>
- <string name="permdesc_devicePower" product="default" msgid="6653901512148320818">"Admite que la aplicación encienda o apague el teléfono."</string>
- <!-- XL -->
- <string name="permdesc_factoryTest" product="tablet" msgid="396653994609190055">"Se ejecuta como una prueba de fábrica de bajo nivel que permite un acceso completo al hardware de la tableta. Sólo disponible cuando la tableta se ejecuta en el modo de prueba de fábrica."</string>
- <string name="permdesc_factoryTest" product="default" msgid="4581239666568781766">"Se ejecuta como una prueba de fábrica de bajo nivel que permite un acceso completo al hardware del teléfono. Sólo disponible cuando un teléfono se ejecuta en el modo de prueba de fábrica."</string>
- <!-- XL -->
- <string name="permlab_setWallpaper" msgid="845032615203772571">"establecer fondo de pantalla"</string>
- <!-- XL -->
- <string name="permdesc_setWallpaper" msgid="3378501759667797259">"Admite que la aplicación establezca el fondo de pantalla del sistema."</string>
- <!-- XL -->
- <string name="permlab_setWallpaperHints" msgid="4995885499848128983">"establecer sugerencias de tamaño del fondo de pantalla"</string>
- <!-- XL -->
- <string name="permdesc_setWallpaperHints" msgid="8857901708691279048">"Admite que la aplicación establezca las sugerencias de tamaño del fondo de pantalla del sistema."</string>
- <!-- XL -->
- <string name="permdesc_setTime" product="tablet" msgid="7329574196603775554">"Permite que una aplicación cambie la hora de la tableta."</string>
- <string name="permdesc_setTime" product="default" msgid="7787175369529849526">"Permite a una aplicación cambiar la hora del teléfono."</string>
- <!-- XL -->
- <string name="permdesc_setTimeZone" product="tablet" msgid="3851480395450283316">"Permite que una aplicación cambie la zona horaria de la tableta."</string>
- <string name="permdesc_setTimeZone" product="default" msgid="3231143515254577541">"Admite una aplicación que cambia la zona horaria del teléfono."</string>
- <!-- XL -->
- <string name="permdesc_getAccounts" product="tablet" msgid="374861616407073729">"Permite que una aplicación obtenga una la lista de cuentas conocidas por la tableta."</string>
- <string name="permdesc_getAccounts" product="default" msgid="6356501268884684429">"Admite una aplicación que obtiene la lista de cuentas conocidas del teléfono."</string>
- <!-- XL -->
- <string name="permdesc_bluetoothAdmin" product="tablet" msgid="8034248164659819866">"Permite que una aplicación configure el Bluetooth local de la tableta, y descubra y se vincule con dispositivos remotos."</string>
- <string name="permdesc_bluetoothAdmin" product="default" msgid="2555370145147752776">"Admite una aplicación que configura el teléfono Bluetooth local y descubre y se vincula con dispositivos remotos."</string>
- <!-- XL -->
- <string name="permdesc_bluetooth" product="tablet" msgid="4631562404621086816">"Permite que una aplicación vea la configuración de la tableta Bluetooth local, y que realice y acepte conexiones con dispositivos vinculados."</string>
- <string name="permdesc_bluetooth" product="default" msgid="1202135959389935958">"Admite una aplicación que ve la configuración del teléfono Bluetooth local, y realiza y acepta conexiones con dispositivos vinculados."</string>
- <!-- XL -->
- <string name="policydesc_watchLogin" product="tablet" msgid="7927990389488709968">"Supervisar el número de contraseñas incorrectas ingresadas al desbloquear la pantalla, y bloquear la tableta o eliminar todos los datos del teléfono si se ingresan demasiadas contraseñas incorrectas."</string>
- <string name="policydesc_watchLogin" product="default" msgid="4998594853332798741">"Supervisa el número de contraseñas incorrectas ingresadas al desbloquear la pantalla, y bloquee el teléfono o elimine todos los datos del teléfono si se ingresan demasiadas contraseñas incorrectas."</string>
- <!-- XL -->
- <string name="policydesc_wipeData" product="tablet" msgid="7871059407132175855">"Borrar los datos de la tableta sin advertencias, restableciendo la configuración de fábrica"</string>
- <string name="policydesc_wipeData" product="default" msgid="6003127471292136411">"Borrar los datos del teléfono sin advertencias al restablecer la configuración original"</string>
- <!-- XL -->
- <string-array name="phoneTypes">
- <item msgid="7066790683658405096">"Pantalla principal"</item>
- <item msgid="5813675571320075289">"Teléfono móvil"</item>
- <item msgid="1236863745322977021">"Trabajo"</item>
- <item msgid="7018038125868933566">"Fax laboral"</item>
- <item msgid="4280105707643078852">"Fax personal"</item>
- <item msgid="6527083287534782580">"Localizador"</item>
- <item msgid="706618935041239888">"Otro"</item>
- <item msgid="8099625332540070724">"Personalizado"</item>
- </string-array>
- <!-- XL -->
- <string-array name="emailAddressTypes">
- <item msgid="8080673853442355385">"Pantalla principal"</item>
- <item msgid="924798042157989715">"Trabajo"</item>
- <item msgid="1959796935508361158">"Otro"</item>
- <item msgid="756534161520555926">"Personalizado"</item>
- </string-array>
- <!-- XL -->
- <string-array name="postalAddressTypes">
- <item msgid="1166454994471190496">"Pantalla principal"</item>
- <item msgid="3602955376664951787">"Trabajo"</item>
- <item msgid="4646105398231575508">"Otro"</item>
- <item msgid="8191179302220976184">"Personalizado"</item>
- </string-array>
- <!-- XL -->
- <string-array name="imAddressTypes">
- <item msgid="2528436635522549040">"Pantalla principal"</item>
- <item msgid="5834207144511084508">"Trabajo"</item>
- <item msgid="3796683891024584813">"Otro"</item>
- <item msgid="6644316676098098833">"Personalizado"</item>
- </string-array>
- <!-- XL -->
- <string-array name="organizationTypes">
- <item msgid="6571823895277482483">"Trabajo"</item>
- <item msgid="4013674940836786104">"Otro"</item>
- <item msgid="8549998141814637453">"Personalizado"</item>
- </string-array>
- <!-- XL -->
- <string name="phoneTypeHome" msgid="2087652870939635038">"Pantalla principal"</string>
- <!-- XL -->
- <string name="phoneTypeMobile" msgid="7084573626440935140">"Teléfono móvil"</string>
- <!-- XL -->
- <string name="emailTypeHome" msgid="1298773522695936612">"Pantalla principal"</string>
- <!-- XL -->
- <string name="emailTypeMobile" msgid="5515624509217674980">"Teléfono móvil"</string>
- <!-- XL -->
- <string name="postalTypeHome" msgid="7553888805834710738">"Pantalla principal"</string>
- <!-- XL -->
- <string name="imTypeHome" msgid="3732426015472142690">"Pantalla principal"</string>
- <!-- XL -->
- <string name="sipAddressTypeHome" msgid="8212230577724692911">"Pantalla principal"</string>
- <!-- XL -->
- <string name="lockscreen_pattern_instructions" msgid="9171665895877154059">"Extraer el patrón para desbloquear"</string>
- <!-- XL -->
- <string name="lockscreen_battery_short" msgid="891372653127247039">"Segmento <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
- <!-- XL -->
- <string name="lockscreen_missing_sim_message" product="tablet" msgid="3961770350078423154">"No hay tarjeta SIM en la tableta."</string>
- <string name="lockscreen_missing_sim_message" product="default" msgid="5997031739677800758">"No hay tarjeta SIM en el teléfono."</string>
- <!-- XL -->
- <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="2429599468920598896">"Has establecido incorrectamente tu gráfico de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. "\n\n"Vuelve a intentarlo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
- <!-- XL -->
- <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3211267232692817092">"Has establecido incorrectamente tu gráfico de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos más, se te solicitará que desbloquees tu tableta al acceder a Google."\n\n" Vuelve a intentarlo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
- <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="7097890594752816076">"Has establecido incorrectamente tu gráfico de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos, se te solicitará que desbloquees tu teléfono al acceder a Google. "\n\n" Vuelve a intentarlo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
- <!-- XL -->
- <string name="lockscreen_glogin_submit_button" msgid="4760302858316749698">"Acceder"</string>
- <!-- XL -->
- <string name="lockscreen_glogin_invalid_input" msgid="7265806099449246244">"Nombre de usuario o contraseña no válidos."</string>
- <!-- XL -->
- <string name="hour_ampm" msgid="6161399724998500216">"Segmento <xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
- <!-- XL -->
- <string name="hour_cap_ampm" msgid="724197720606114012">"Segmento <xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
- <!-- XL -->
- <string name="double_tap_toast" msgid="2893001600485832537">"Sugerencia: presiona dos veces para acercar y alejar"</string>
- <!-- XL -->
- <string name="autofill_address_name_separator" msgid="5171727678145785075">" Segmento "</string>
- <!-- XL -->
- <string name="permlab_readHistoryBookmarks" msgid="6148149152792104516">"leer historial y favoritos del navegador"</string>
- <!-- XL -->
- <string name="permdesc_readHistoryBookmarks" msgid="7371336472744100059">"Permite a la aplicación leer todas las URL que ha visitado el navegador y todos los favoritos del navegador."</string>
- <!-- XL -->
- <string name="permlab_writeHistoryBookmarks" msgid="1369319390968848231">"escribir historial y favoritos del navegador"</string>
- <!-- XL -->
- <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="3870229397949634482">"Permite que una aplicación modifique el historial de navegación y los favoritos del navegador almacenados en tu tableta. Las aplicaciones maliciosas pueden utilizarlo para borrar o modificar los datos en tu navegador."</string>
- <string name="permdesc_writeHistoryBookmarks" product="default" msgid="6845659334691579933">"Permite a una aplicación modificar el historial y los favoritos del navegador almacenados en tu teléfono. Las aplicaciones maliciosas pueden utilizarlo para borrar o modificar tus datos."</string>
- <!-- XL -->
- <string name="permlab_setAlarm" msgid="8112208516527103653">"fija la alarma en el reloj de alarma"</string>
- <!-- XL -->
- <string name="permdesc_setAlarm" msgid="5454386032150297784">"Permite a la aplicación fijar una alarma en una aplicación de alarma. Es posible que algunas aplicaciones de alarma no implementen esta función."</string>
- <!-- XL -->
- <string name="menu_delete_shortcut_label" msgid="8482704027019632634">"eliminar"</string>
- <!-- XL -->
- <plurals name="num_minutes_ago">
- <item quantity="one" msgid="468685153446407901">"hace 1 minuto"</item>
- <item quantity="other" msgid="211907662145171054">"Hace <xliff:g id="COUNT">%d</xliff:g> minutos"</item>
- </plurals>
- <!-- XL -->
- <plurals name="num_hours_ago">
- <item quantity="one" msgid="2172827344495633666">"hace 1 hora"</item>
- <item quantity="other" msgid="6094391999921908511">"Hace <xliff:g id="COUNT">%d</xliff:g> horas"</item>
- </plurals>
- <!-- XL -->
- <plurals name="num_days_ago">
- <item quantity="one" msgid="3766494702684657165">"ayer"</item>
- <item quantity="other" msgid="5030316952487658828">"Hace <xliff:g id="COUNT">%d</xliff:g> días"</item>
- </plurals>
- <!-- XL -->
- <plurals name="abbrev_num_seconds_ago">
- <item quantity="one" msgid="1441918190525197797">"hace 1 s"</item>
- <item quantity="other" msgid="3958332340802316933">"hace <xliff:g id="COUNT">%d</xliff:g> segundos"</item>
- </plurals>
- <!-- XL -->
- <plurals name="abbrev_num_minutes_ago">
- <item quantity="one" msgid="3404245071272952255">"hace 1 min"</item>
- <item quantity="other" msgid="6004808520903389765">"hace <xliff:g id="COUNT">%d</xliff:g> min"</item>
- </plurals>
- <!-- XL -->
- <plurals name="abbrev_num_hours_ago">
- <item quantity="one" msgid="806010152744475654">"hace 1 hora"</item>
- <item quantity="other" msgid="7553525762196895290">"Hace <xliff:g id="COUNT">%d</xliff:g> horas"</item>
- </plurals>
- <!-- XL -->
- <plurals name="abbrev_num_days_ago">
- <item quantity="one" msgid="5819444260187611238">"ayer"</item>
- <item quantity="other" msgid="1069986768190052012">"Hace <xliff:g id="COUNT">%d</xliff:g> días"</item>
- </plurals>
- <!-- XL -->
- <string name="preposition_for_time" msgid="3606608741888559522">"a la/s <xliff:g id="TIME">%s</xliff:g>"</string>
- <!-- XL -->
- <string name="minutes" msgid="1486240209627391507">"min"</string>
- <!-- XL -->
- <string name="selectAll" msgid="847570914566450966">"Seleccionar todos"</string>
- <!-- XL -->
- <string name="low_internal_storage_view_text" product="tablet" msgid="6497548813789342134">"Está quedando poco espacio de almacenamiento en la tableta."</string>
- <string name="low_internal_storage_view_text" product="default" msgid="2901569701336868928">"Hay poco espacio de almacenamiento en el teléfono."</string>
- <!-- XL -->
- <string name="capital_on" msgid="5705918046896729554">"ENCENDIDO"</string>
- <!-- XL -->
- <string name="wait" msgid="8036803866051401072">"Espera"</string>
- <!-- XL -->
- <string name="heavy_weight_notification" msgid="5762367358298413602">"<xliff:g id="APP">%1$s</xliff:g> se está ejecutando"</string>
- <!-- XL -->
- <string name="ext_media_checking_notification_title" product="nosdcard" msgid="103298639852047758">"Preparando almacenamiento USB"</string>
- <string name="ext_media_checking_notification_title" product="default" msgid="2111086053471573248">"Preparando la tarjeta SD"</string>
- <!-- XL -->
- <string name="ime_action_done" msgid="7200237418945571897">"Listo"</string>
- <!-- XL -->
- <string name="wallpaper_binding_label" msgid="6966627494441714436">"Fondo de pantalla"</string>
- <!-- XL -->
- <string name="websearch" msgid="904596193450917688">"Búsqueda web"</string>
- <!-- XL -->
- <string name="status_bar_notification_info_overflow" msgid="1081154808901480710">"100+"</string>
- <!-- XL -->
- <string name="permlab_accessMtp" msgid="2385215229145694622">"implementar protocolo MTP"</string>
- <!-- XL -->
- <string name="permdesc_accessMtp" msgid="4707854877711083465">"Permite acceso al driver kernel MTP para implementar el protocolo MTP USB."</string>
- <!-- XL -->
- <string name="permlab_mediaStorageWrite" product="default" msgid="5585262071354704256">"modificar/eliminar los contenidos del almacenamientos de medios internos"</string>
- <!-- XL -->
- <string name="permdesc_mediaStorageWrite" product="default" msgid="2372999661142345443">"Permite que una aplicación modifique los contenidos del almacenamiento interno de medios."</string>
- <!-- XL -->
- <string name="autofill_address_summary_name_format" msgid="7531610259426153850">"$1$2$3"</string>
- <!-- XL -->
- <string name="autofill_address_summary_format" msgid="8398158823767723887">"$1$2$3"</string>
- <!-- XL -->
- <string name="gpsNotifTicker" msgid="6612390321359669319">"Solicitud de ubicación de <xliff:g id="NAME">%s</xliff:g>"</string>
- <!-- XL -->
- <string name="gpsNotifTitle" msgid="7533028619350196545">"Solicitud de ubicación"</string>
- <!-- XL -->
- <string name="gpsNotifMessage" msgid="5592972401593755530">"Solicitado por <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
- <!-- XL -->
- <string name="gpsVerifYes" msgid="1511016393202739483">"Sí"</string>
- <!-- XL -->
- <string name="gpsVerifNo" msgid="661731239940896232">"No"</string>
- <!-- XL -->
- <string name="sync_too_many_deletes" msgid="6088394702274114202">"Eliminar el límite excedido"</string>
- <!-- XL -->
- <string name="sync_too_many_deletes_desc" msgid="4794082462774743277">"Existen <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> artículos eliminados para <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, cuenta <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. ¿Qué te gustaría hacer?"</string>
- <!-- XL -->
- <string name="sync_really_delete" msgid="7782215155483034729">"Eliminar artículos."</string>
- <!-- XL -->
- <string name="sync_undo_deletes" msgid="6501390120900825477">"Deshacer eliminaciones."</string>
- <!-- XL -->
- <string name="sync_do_nothing" msgid="612038572646360281">"No hagas nada por el momento."</string>
-</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index d3b1062..71a8b2a 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -610,6 +610,12 @@
<attr name="actionModeCopyDrawable" format="reference" />
<!-- Drawable to use for the Paste action button in Contextual Action Bar -->
<attr name="actionModePasteDrawable" format="reference" />
+ <!-- Drawable to use for the Share action button in WebView selection action modes -->
+ <attr name="actionModeShareDrawable" format="reference" />
+ <!-- Drawable to use for the Find action button in WebView selection action modes -->
+ <attr name="actionModeFindDrawable" format="reference" />
+ <!-- Drawable to use for the Web Search action button in WebView selection action modes -->
+ <attr name="actionModeWebSearchDrawable" format="reference" />
<!-- PopupWindow style to use for action modes when showing as a window overlay. -->
<attr name="actionModePopupWindowStyle" format="reference" />
@@ -723,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..2037191
--- 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
@@ -571,4 +571,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 72f1801..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>
@@ -1611,6 +1611,8 @@
<item name="android:thumb">@android:drawable/scrubber_control_selector_holo</item>
<item name="android:thumbOffset">16dip</item>
<item name="android:focusable">true</item>
+ <item name="android:paddingLeft">16dip</item>
+ <item name="android:paddingRight">16dip</item>
</style>
<style name="Widget.Holo.RatingBar" parent="Widget.RatingBar">
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 82164e5..5f4ea32 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -263,6 +263,9 @@
<item name="actionModeCutDrawable">@android:drawable/ic_menu_cut_dark</item>
<item name="actionModeCopyDrawable">@android:drawable/ic_menu_copy_dark</item>
<item name="actionModePasteDrawable">@android:drawable/ic_menu_paste_dark</item>
+ <item name="actionModeShareDrawable">@android:drawable/ic_menu_share</item>
+ <item name="actionModeFindDrawable">@android:drawable/ic_menu_find</item>
+ <item name="actionModeWebSearchDrawable">@android:drawable/ic_menu_search</item>
<item name="actionBarTabStyle">@style/Widget.ActionBarView_TabView</item>
<item name="actionBarTabBarStyle">@style/Widget.ActionBarView_TabBar</item>
<item name="actionBarTabTextStyle">@style/Widget.ActionBarView_TabText</item>
@@ -282,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>
@@ -383,10 +388,15 @@
<item name="actionModeCutDrawable">@android:drawable/ic_menu_cut_light</item>
<item name="actionModeCopyDrawable">@android:drawable/ic_menu_copy_light</item>
<item name="actionModePasteDrawable">@android:drawable/ic_menu_paste_light</item>
+ <item name="actionModeShareDrawable">@android:drawable/ic_menu_share_holo_light</item>
+ <item name="actionModeFindDrawable">@android:drawable/ic_menu_find_holo_light</item>
+ <item name="actionModeWebSearchDrawable">@android:drawable/ic_menu_search_holo_light</item>
<item name="actionModeBackground">@android:drawable/cab_background_light</item>
<!-- 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>
@@ -994,6 +1004,13 @@
<item name="actionBarSize">56dip</item>
<item name="actionModePopupWindowStyle">@android:style/Widget.Holo.PopupWindow.ActionMode</item>
+ <item name="actionModeCutDrawable">@android:drawable/ic_menu_cut_holo_dark</item>
+ <item name="actionModeCopyDrawable">@android:drawable/ic_menu_copy_holo_dark</item>
+ <item name="actionModePasteDrawable">@android:drawable/ic_menu_paste_holo_dark</item>
+ <item name="actionModeShareDrawable">@android:drawable/ic_menu_share_holo_dark</item>
+ <item name="actionModeFindDrawable">@android:drawable/ic_menu_find_holo_dark</item>
+ <item name="actionModeWebSearchDrawable">@android:drawable/ic_menu_search_holo_dark</item>
+
<item name="dividerVertical">?android:attr/listDivider</item>
<item name="dividerHorizontal">?android:attr/listDivider</item>
<item name="buttonBarStyle">@android:style/Holo.ButtonBar</item>
@@ -1270,6 +1287,13 @@
<item name="actionBarSize">56dip</item>
<item name="actionModePopupWindowStyle">@android:style/Widget.Holo.Light.PopupWindow.ActionMode</item>
+ <item name="actionModeCutDrawable">@android:drawable/ic_menu_cut_holo_light</item>
+ <item name="actionModeCopyDrawable">@android:drawable/ic_menu_copy_holo_light</item>
+ <item name="actionModePasteDrawable">@android:drawable/ic_menu_paste_holo_light</item>
+ <item name="actionModeShareDrawable">@android:drawable/ic_menu_share_holo_light</item>
+ <item name="actionModeFindDrawable">@android:drawable/ic_menu_find_holo_light</item>
+ <item name="actionModeWebSearchDrawable">@android:drawable/ic_menu_search_holo_light</item>
+
<item name="dividerVertical">?android:attr/listDivider</item>
<item name="dividerHorizontal">?android:attr/listDivider</item>
<item name="buttonBarStyle">@android:style/Holo.Light.ButtonBar</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..3f78ce0 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,18 @@
@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 {
+ // create a new test suite
+ suite.setName("WifiOnlyStressTests");
+ String[] methodNames = {"testWifiScanning"};
+ Class<WifiStressTest> testClass = WifiStressTest.class;
+ for (String method: methodNames) {
+ suite.addTest(TestSuite.createTest(testClass, method));
+ }
+ }
return suite;
}
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/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/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java b/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java
index 243ac38..544a967 100644
--- a/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java
+++ b/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java
@@ -23,8 +23,19 @@
public class SystemPropertiesTest extends TestCase {
private static final String KEY = "sys.testkey";
+ private static final String PERSIST_KEY = "persist.sys.testkey";
+
@SmallTest
- public void testLongSequencialProperties() throws Exception {
+ public void testStressPersistPropertyConsistency() throws Exception {
+ for (int i = 0; i < 100; ++i) {
+ SystemProperties.set(PERSIST_KEY, Long.toString(i));
+ long ret = SystemProperties.getLong(PERSIST_KEY, -1);
+ assertEquals(i, ret);
+ }
+ }
+
+ @SmallTest
+ public void testStressMemoryPropertyConsistency() throws Exception {
for (int i = 0; i < 100; ++i) {
SystemProperties.set(KEY, Long.toString(i));
long ret = SystemProperties.getLong(KEY, -1);
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/guide_toc.cs b/docs/html/guide/guide_toc.cs
index b13600c..c258949 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -630,7 +630,7 @@
<span class="zh-TW" style="display:none">準備發佈</span>
</a></li>
<li><a href="<?cs var:toroot ?>guide/publishing/publishing.html">
- <span class="en">Publishing Your Applications</span>
+ <span class="en">Publishing on Android Market</span>
</a></li>
</ul>
</li>
diff --git a/docs/html/guide/publishing/publishing.jd b/docs/html/guide/publishing/publishing.jd
index af1ea74..0cbba53 100644
--- a/docs/html/guide/publishing/publishing.jd
+++ b/docs/html/guide/publishing/publishing.jd
@@ -1,4 +1,4 @@
-page.title=Publishing Your Applications
+page.title=Publishing on Android Market
@jd:body
<div id="qv-wrapper">
@@ -16,22 +16,22 @@
<h2>In this document</h2>
<ol>
-<li><a href="#overview">Publishing on Android Market</a>
- <ol>
- <li><a href="#marketupgrade">Publishing Updates on Android Market</a></li>
- <li><a href="#marketLicensing">Using Android Market Licensing Service</a></li>
- <li><a href="#marketintent">Using Intents to Launch the Market Application</a></li>
- </ol></li>
-<!--
-<li><span style="color:ccc">Publishing on Other Hosted Services</a></li>
-<li><span style="color:ccc">Publishing through a Web Server</a></li>
--->
+<li><a href="#overview">About Android Market</a>
+<li><a href="#marketupgrade">Publishing Updates on Android Market</a></li>
+<li><a href="#marketLicensing">Using Android Market Licensing Service</a></li>
+<li><a href="#marketintent">Linking to Your Apps on Android Market</a>
+ <ol>
+ <li><a href="#OpeningDetails">Opening an app's details page</a></li>
+ <li><a href="#PerformingSearch">Performing a search</a></li>
+ <li><a href="#UriSummary">Summary of URI formats</a></li>
+ </ol>
+</li>
</ol>
<h2>See also</h2>
<ol>
-<li><a href="{@docRoot}guide/publishing/licensing.html">Licensing Your Applications</a></li>
+<li><a href="{@docRoot}guide/publishing/licensing.html">Application Licensing</a></li>
<li><a href="{@docRoot}guide/publishing/preparing.html">Preparing to Publish</a></li>
</ol>
@@ -39,43 +39,45 @@
<img id="rule" src="{@docRoot}assets/images/grad-rule-qv.png">
<div id="qv-sub-rule">
<img src="{@docRoot}assets/images/icon_market.jpg" style="float:left;margin:0;padding:0;">
- <p style="color:#669999;">Interested in publishing your app on Android Market?</p>
- <a id="publish-link" href="http://market.android.com/publish">Go to Android Market »</a>
+ <h2 style="color:#669999;">Interested in publishing your app on Android Market?</h2>
+ <p><a href="http://market.android.com/publish">Go to Android Market</a> to
+create a developer account and upload your application. For more information about the
+required assets, listing details, and options, see <a
+href="http://market.android.com/support/bin/answer.py?answer=113469">Uploading
+applications</a>.</p>
</div>
</div>
</div>
</div>
-<p>Publishing an application means testing it, packaging it appropriately, and making
-it available to users of Android-powered mobile devices for download or sideload.</p>
+<p>If you've followed the steps outlined in <a
+href="{@docRoot}guide/publishing/preparing.html">Preparing to Publish</a>, the result of the process
+is a compiled {@code .apk} file that is signed with your private release key. Your application is
+now ready to be published publicly so users can install it.</p>
-<p>If you've followed the steps outlined in
-<a href="{@docRoot}guide/publishing/preparing.html">Preparing to
-Publish Your Applications</a>, the result of the process is a compiled .apk that
-is signed with your release private key. Inside the .apk, the application is
-properly versioned and any MapView elements reference a Maps API Key that you
-obtained by registering the MD5 fingerprint of the same certificate used to sign
-the .apk. Your application is now ready for publishing. </p>
+<p>You can publish your application and allow users to install it any way you choose, including
+from your own web server. This document provides information about publishing your Android
+application with Android Market.</p>
-<p>The sections below provide information about publishing your Android
-application to mobile device users.</p>
-<h2 id="overview">Publishing on Android Market</h2>
+<h2 id="overview">About Android Market</h2>
-<p>Android Market is a hosted service that makes it easy for users to find and
-download Android applications to their Android-powered devices, and makes it
-easy for developers to publish their applications to Android users.</p>
+<p>Android Market is a service that makes it easy for users to find and download Android
+applications to their Android-powered devices, either from the Android Market application on their
+device or from the Android Market web site (<a
+href="http://market.android.com">market.android.com</a>). As a developer, you can use Android Market
+to distribute your applications to users on all types of Android-powered devices, all around the
+world.</p>
<p>To publish your application on Android Market, you first need to register
-with the service using your Google account and agree to the terms of service.
+with the service using a Google account and agree to the terms of service.
Once you are registered, you can upload your application to the service whenever
-you want, as many times as you want, and then publish it when you are ready.
-Once published, users can see your application, download it, and rate it using
-the Market application installed on their Android-powered devices. </p>
+you want, update it as many times as you want, and then publish it when you are ready.
+Once published, users can see your application, download it, and rate it. </p>
<p>To register as an Android Market developer and get started with publishing,
-visit the Android Market: </p>
+visit the Android Market publisher site: </p>
<p style="margin-left:3em;"><a
href="http://market.android.com/publish">http://market.android.com/publish</a>
@@ -94,22 +96,24 @@
<code>android:versionName</code> attribute in the
<a
href="{@docRoot}guide/topics/manifest/manifest-element.html"><code><manifest></code></a>
-element of its manifest. The server uses the <code>android:versionCode</code> as
+element of its manifest file. The server uses the <code>android:versionCode</code> as
the basis for identifying the application internally and handling updates, and
it displays the <code>android:versionName</code> to users as the application's
version.</li>
<li>Your application must define both an <code>android:icon</code> and an
-<code>android:label</code> attribute in the <code><application></code>
-element of its manifest.</li>
+<code>android:label</code> attribute in the <a
+href="{@docRoot}guide/topics/manifest/application-element.html"><code><application></code></a>
+element of its manifest file.</li>
</ol>
</div>
-<h3 id="marketupgrade">Publishing Updates on Android Market</h3>
+
+<h2 id="marketupgrade">Publishing Updates on Android Market</h2>
<p>At any time after publishing an application on Android Market, you can upload
and publish an update to the same application package. When you publish an
update to an application, users who have already installed the
-application will automatically receive a notification that an update is
+application may receive a notification that an update is
available for the application. They can then choose to update the application
to the latest version.</p>
@@ -117,190 +121,231 @@
the <code>android:versionCode</code> and <code>android:versionName</code>
attributes in the <a
href="{@docRoot}guide/topics/manifest/manifest-element.html"><code><manifest></code></a>
-element of the manifest file. Also, the package name must be the same and the
-.apk must be signed with the same private key. If the package name and signing
+element of the manifest file. Also, the package name must be the same as the existing version and
+the {@code .apk} file must be signed with the same private key. If the package name and signing
certificate do <em>not</em> match those of the existing version, Market will
-consider it a new application and will not offer it to users as an update.</p>
+consider it a new application, publish it as such, and will not offer it to existing users as an
+update.</p>
-<h3 id="marketLicensing">Using Android Market Licensing Service</h3>
+<h2 id="marketLicensing">Using Android Market Licensing Service</h2>
<p>Android Market offers a licensing service that lets you enforce licensing
policies for paid applications that you publish through Android Market. With
-Android Market Licensing, your applications can query Android Market at run time
-to obtain their licensing status for the current user, then allow or disallow
-further use as appropriate. Using the service, you can apply a flexible
-licensing policy on an application-by-application basis — each
+Android Market Licensing, your applications can query Android Market at runtime
+to obtain the licensing status for the current user, then allow or disallow
+further use of the application as appropriate. Using the service, you can apply a flexible
+licensing policy on an application-by-application basis—each
application can enforce its licensing status in the way most appropriate
for it. </p>
<p>Any application that you publish through Android Market can use the Android
-Market Licensing Service. The service uses no dedicated framework APIs, you can
-add licensing to any legacy application that uses a minimum API level of 3 or
+Market Licensing Service. The service uses no dedicated framework APIs, so you can
+add licensing to any application that uses a minimum API Level of 3 or
higher.</p>
<p>For complete information about Android Market Licensing Service and how to
-use it in your application, see <a
-href="{@docRoot}guide/publishing/licensing.html">Licensing Your
-Applications</a>.</p>
+use it in your application, read <a
+href="{@docRoot}guide/publishing/licensing.html">Application Licensing</a>.</p>
-<h3 id="marketintent">Using Intents to Launch the Market Application on
-a Device</h3>
-<p>Android-powered devices include a preinstalled Market application that gives
-users access to the Android Market site. From Market, users can
-browse or search available applications, read ratings and reviews, and
-download/install applications.</p>
+<h2 id="marketintent">Linking to Your Apps on Android Market</h2>
-<p>You can launch the Market application from another Android
-application by sending an Intent to the system. You might want to do
-this, for example, to help the user locate and download an update to an
-installed application, or to let the user know about related
-applications that are available for download. </p>
-
-<p>To launch Market, you send an ACTION_VIEW Intent, passing a Market-handled
-URI string as the Intent data. In most cases, your application would call
-startActivity() to send the ACTION_VIEW Intent with the Market-handled URI.</p>
-
-<p>The URI that you supply with the Intent lets the system route the intent
-properly and also expresses the type of action that you want Market to perform
-after launch. Currently, you can have Market take these actions:</p>
+<p>To help users discover your published applications, you can use two special Android Market URIs
+that direct users to your application's details page or perform a search for all of your published
+applications in Android Market. You can use these URIs to do the following:</p>
<ul>
-<li>Initiate a search for applications on Android Market, based on the query
-parameters that you provide, or </li>
-<li>Load the Details page for a specific application on Android Market, based on
-the application's package name.</li>
+ <li>Create a button in your application or a link on a web page that opens one of your
+application's details page in the Android Market application or web site.</li>
+ <li>Create a button in your application or a link on a web page that searches for all your
+published applications in the Android Market application or web site.</li>
</ul>
-<h4>Initiating a search</h4>
+<p>You can launch the Android Market application or web site in the following ways:</p>
+<ul>
+ <li>Initiate an {@link android.content.Intent} from your application that launches the
+Android Market application on the user's device. The intent must use the {@link
+android.content.Intent#ACTION_VIEW} action, and include intent data with the appropriate
+Android Market URI scheme.</li>
+ <li>Provide a hyperlink on a web page that opens the Android Market web site.</li>
+</ul>
-<p>Your application can initiate a search on Android Market for applications
-that match the query parameters that you provide. To do so, your application
-sends an ACTION_VIEW Intent that includes a URI and query parameters in this
+<p>In both cases, you need to create a URI that indicates either the application you'd like to view
+in Android Market or the search you'd like to perform. The URI is quite similar whether you want
+to open the application or open the web site. The only difference is the URI prefix.</p>
+
+<p>To open the Android Market application on the device, the prefix for the intent's data URI
+is:</p>
+
+<p style="margin-left:2em"><code>market://</code></p>
+
+<p>To open the Android Market web site, the prefix for the link URI is:</p>
+
+<p style="margin-left:2em"><code>http://market.android.com/</code></p>
+
+<p>To complete each URI, you must append a string that specifies either the
+application for which you want to view or the search to execute. The following sections
+describe how to create a complete URI for each case.</p>
+
+<p class="note"><strong>Note:</strong> If you create a link to open the Android Market web site and
+the user selects it from an Android-powered device, the Android Market application will also resolve
+the link so the user can use the native application instead of the web site. Also, because the
+Android Market application also reads the {@code http://} URIs, you can also use them in an intent,
+but you should usually use the {@code market://} URIs for an intent, so that the native application
+is opened by default. You should use {@code http://} URIs only when creating links from a web
+page.</p>
+
+
+<h3 id="OpeningDetails">Opening an app's details page</h3>
+
+<p>As described above, you can open the details page for a specific application either on the
+Android Market application or the Android Market web site. The details page allows the user to see
+the application description, screenshots, reviews and more, and choose to install it.</p>
+
+<p>The format for the URI that opens the details page is:</p>
+
+<p style="margin-left:2em"><code><URI_prefix><b>details?id=</b><package_name></code></p>
+
+<p>The <code><package_name></code> is a placeholder for the target application's fully
+qualified package name, as declared in the <a
+href="{@docRoot}guide/topics/manifest/manifest-element.html#package">{@code
+package}</a> attribute of the <a href="{@docRoot}guide/topics/manifest/manifest-element.html">{@code
+<manifest>}</a> element in the application's manifest file.</p>
+
+
+<h4>Opening details in the Android Market application</h4>
+
+<p>To open the details page in the Android Market application, create an intent with the
+{@link android.content.Intent#ACTION_VIEW} action and include a data URI in this format:</p>
+
+<p style="margin-left:2em"><code>market://details?id=<package_name></code></p>
+
+<p>For example, here's how you can create an intent and open an application's details page in the
+Android Market application:</p>
+
+<pre>
+Intent intent = new Intent(Intent.ACTION_VIEW);
+intent.setData(Uri.parse("market://details?id=com.android.example"));
+startActivity(intent);
+</pre>
+
+
+<h4>Opening details on the Android Market web site</h4>
+
+<p>To open the details page on the Android Market web site, create a link with a URI in this
format:</p>
-<p style="margin-left:2em"><code>market://search?q=<paramtype>:<value></code></p>
+<p style="margin-left:2em">
+ <code>http://market.android.com/details?id=<package_name></code>
+</p>
-<div class="sidebox-wrapper" xstyle="margin-bottom:2em;margin-top:.5em;width:90%;">
- <img id="rule" src="{@docRoot}assets/images/grad-rule-qv.png">
- <div id="qv-sub-rule">
- <img src="{@docRoot}assets/images/icon_market.jpg" style="float:left;margin:0;padding:0;">
- <p style="color:#669999;">Searches on Android Market</p>
-<p>When you initiate a search, Android Market returns results from matches in
-the public metadata supplied by developers in their Android Market profiles or
-application publishing information, but not from the developer's private account
-or from the certificate used to sign the application. </p>
- </div>
-</div>
+<p>For example, here's a link that opens an application's details page on the Android Market web
+site:</p>
-<p>Using this URI format, you can search for applications by:</p>
+<pre>
+<a href="http://market.android.com/details?id=com.android.example">App Link</a>
+</pre>
+
+
+
+<h3 id="PerformingSearch">Performing a search</h3>
+
+<p>To initiate a search in Android Market, the format for the URI is:</p>
+
+<p style="margin-left:2em">
+ <code><URI_prefix><b>search?q=</b><query></code>
+</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 a parameter that performs a search
+based on the publisher name:</p>
<ul>
-<li>Package name</li>
-<li>Developer name</li>
-<li>String match across application name, developer name, and
-description, or </li>
-<li>Any combination of the above</li>
+ <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>
</ul>
-<p>The table at the bottom of this page specifies the <code>paramtypes</code>
-and <code>values</code> that correspond to each of these types of search. </p>
-<p>When you send an intent to initiate a search for applications, Market sends
-the search query to the server and displays the result. To the user, the
-experience is something like this: </p>
+<h4>Searching the Android Market application</h4>
-<ol>
-<li>The user presses a link or button in your application.</li>
-<li>The Market application launches and takes control of the screen, displaying
-a progress indicator labeled "Searching" until it receives the search
-results.</li>
-<li>Market receives the search results and displays them. Depending on the query
-parameters, the search results may include a list of one or more applications.
-</li>
-<li>From the results page, the user can select an app to go to its Details page,
-which offers information about the app and lets the user download/purchase the
-app.</li>
-</ol>
+<p>To perform a search in the Android Market application, create an intent with the
+{@link android.content.Intent#ACTION_VIEW} action and include a data URI in this format:</p>
-<h4>Loading an application's Details page</h4>
+<p style="margin-left:2em"><code>market://search?q=<query></code></p>
-<p>In Android Market, every application has a Details page that provides an
-overview of the application for users. For example, the page includes a short
-description of the app and screen shots of it in use, if supplied by the
-developer, as well as feedback from users and information about the developer.
-The Details page also includes an "Install" button that lets the user trigger
-the download/purchase of the application.</p>
+<p>The query may include the {@code pub:} parameter described above.</p>
-<p>If you want to refer the user to a specific appplication, your application
-can take the user directly to the application's Details page. To do so, your
-application sends an ACTION_VIEW Intent that includes a URI and query parameter
-in this format:</p>
+<p>For example, here's how you can initiate a search in the Android Market application, based on the
+publisher name:</p>
-<p style="margin-left:2em"><code>market://details?id=<packagename></code></p>
+<pre>
+Intent intent = new Intent(Intent.ACTION_VIEW);
+intent.setData(Uri.parse("market://search?q=pub:Your Publisher Name"));
+startActivity(intent);
+</pre>
-<p>In this case, the <code>packagename</code> parameter is target application's
-fully qualified package name, as declared in the <code>package</code> attribute
-of the <code>manifest</code> element in the application's manifest file. For example:</p>
+<p>The search result shows all applications published by the publisher and which are compatible with
+the current device.</p>
-<p style="margin-left:2em"><code>market://details?id=com.example.android.jetboy</code></p>
-<h4>Android Market URIs</h4>
+<h4>Searching the Android Market web site</h4>
-<p>The table below provides a list of URIs and actions currently
-supported by the Market application.</p>
+<p>To perform a search on the Android Market web site, create a link with a URI in this
+format:</p>
-<p>Note that these URIs work only when passed as Intent data — you
-can't currently load the URIs in a web browser, either on a desktop machine or
-on the device. </p>
+<p style="margin-left:2em">
+ <code>http://market.android.com/search?q=<query></code>
+</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>
+
+<pre>
+<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>
+
+<p>The table below provides a summary of the URIs currently supported by the Android Market (both on
+the web and in the Android application), as discussed in the previous sections.</p>
<table>
<tr>
-<th width="25%">For this Result</th>
-<th>Pass this URI with the ACTION_VIEW Intent</th>
-<th width="36%">Comments</th>
-</tr>
-<tr>
-<td>Display the Details screen for a specific application, as identified
-by the app's fully qualified package name.</td>
-<td><code>http://market.android.com/details?id=<packagename></code>
-or<br>
-<code>market://details?id=<packagename></code></td>
-<td>Note that the package name that you specify is <em>not</em> specific to any
-version of an application. Therefore, Market always displays the Details page for the
-latest version of the application.</td>
-</tr>
-<tr>
-<td>Search for an application by its fully qualified Java package name and
-display the result.</td>
-<td><code>http://market.android.com/search?q=pname:<package></code> or<br>
-<code>market://search?q=pname:<package></code></td>
-<td>Searches only the Java package name of applications. Returns only exact
-matches.</td>
+<th>For this result</th>
+<th>Use this URI in a web page link</th>
+<th>Or this URI in an {@link android.content.Intent#ACTION_VIEW} intent</th>
</tr>
<tr>
-<td>Search for applications by developer name and display the results.</td>
-<td><code>http://market.android.com/search?q=pub:<Developer Name></code>
-or<br> <code>market://search?q=pub:<Developer Name></code></td>
-<td>Searches only the "Developer Name" fields of Market public profiles.
-Returns exact matches only. </td>
+<td>Display the details screen for a specific application</td>
+<td><code>http://market.android.com/details?id=<package_name></code>
+<td><code>market://details?id=<package_name></code></td>
</tr>
<tr>
-<td>Search for applications by substring and display the results.</td>
-<td><code>http://market.android.com/search?q=<substring></code> or
-<br><code>market://search?q=<substring></code></td>
-<td>Searches all public fields (application title, developer name, and
-application description) for all applications. Returns exact and partial
-matches.</td>
+<td>Search for applications using a general string query.</td>
+<td><code>http://market.android.com/search?q=<query></code></td>
+<td><code>market://search?q=<query></code></td>
</tr>
<tr>
-<td>Search using multiple query parameters and display the results.</td>
-<td>Example:<p><code>http://market.android.com/search?q=world pname:com.android.hello pub:Android</code></p></td>
-<td>Returns a list of applications meeting all the supplied parameters. </td>
+<td>Search for applications by publisher name</td>
+<td><nobr><code>http://market.android.com/search?q=pub:<publisher_name></code></nobr></td>
+<td><nobr><code>market://search?q=pub:<publisher_name></code></nobr></td>
</tr>
+
</table>
+
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/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/sdk/preview/features.jd b/docs/html/sdk/preview/features.jd
index cd0dea1..d7ecc47 100644
--- a/docs/html/sdk/preview/features.jd
+++ b/docs/html/sdk/preview/features.jd
@@ -1,186 +1,8 @@
-page.title=Introduction to Honeycomb
@jd:body
-<p>Welcome to the Honeycomb preview SDK. Honeycomb is the next major release of the Android
-platform and is optimized for tablet devices. This document provides an introduction to the new
-platform features and APIs available in Honeycomb.</p>
+<script type="text/javascript">
+ document.location=toRoot+"sdk/android-3.0.html"
+</script>
-
-<h2>Fragments</h2>
-
-<div class="figure" style="width:400px">
- <img src="{@docRoot}images/preview_hc/fragments_layout.png" alt="" />
- <p class="img-caption"><strong>Fragment Layout.</strong> An activity with two
-fragments: one with a list view, on the left, and one that displays selected content on the
-right. This demo is available in the samples package.</p>
-</div>
-
-
-<p>A new framework component that allows you to separate distinct elements of an activity into
-self-contained modules that define their own UI and lifecycle—defining what may be
-considered "sub-activities".</p>
-<ul>
- <li>Multiple fragments can be combined in a single activity to build a multi-pane UI in which
-each pane manages its own lifecycle and user inputs</li>
- <li>Fragments are self-contained and can be reused in multiple activities</li>
- <li>Fragments can be added, removed, replaced and animated inside the activity</li>
- <li>Fragment can be added to a back stack managed by the activity, preserving the state of
-fragments as they are changed and allowing the user to navigate backward through the different
-states</li>
- <li>By <a
-href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">providing
-alternative resources</a>, you can mix and match fragments, based
-on the screen size and orientation</li>
- <li>Fragments have direct access to their container activity and can contribute items to the
-activity's Options Menu</li>
-</ul>
-
-<p>For more information, see the <a
-href="{@docRoot}guide/topics/fragments/index.html">Fragments</a> developer guide.</p>
-
-
-<h2>Action Bar</h2>
-
-<p>A replacement for the traditional title bar, which provides users quick access to global
-actions and different navigation modes.</p>
-<ul>
- <li>Provides quick access to items from the Options Menu ("action items") and interactive
-widgets ("action views")</li>
- <li>Includes the application logo in the left corner, which can perform actions when tapped
-and can be replaced with a custom logo</li>
- <li>Provides breadcumbs for navigating backward through fragments</li>
- <li>Offers built in navigation modes, including tabs and a drop-down list</li>
- <li>Can be customized with themes and custom backgrounds</li>
- <li>And more</li>
-</ul>
-
-<img src="{@docRoot}images/preview_hc/actionbar.png" alt="" />
-<p class="img-caption"><strong>Action Bar.</strong> An action bar with a custom logo,
-tabs, and Options Menu. This demo is available in the samples package.</p>
-
-<p>For more information, see the <a
-href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a> developer guide.</p>
-
-
-<h2>System Clipboard</h2>
-
-<p>Applications can copy and paste data (beyond mere text) to and from the system-wide
-clipboard.</p>
-
-<ul>
- <li>Clipped data can be plain text, a URI, or an intent</li>
- <li>The new {@link android.content.ClipData} class represents a complex data type for the
-clipboard</li>
- <li>The new {@link android.content.ClipboardManager} class allows apps to add {@link
-android.content.ClipData} to the clipboard (copy) and read {@link
-android.content.ClipData} from the clipboard (paste)</li>
- <li>The {@link android.content.ContentProvider} class has been extended to generate byte
-streams based on data types added to the clipboard and point to data hosted in a
-content provider</li>
-</ul>
-
-<p>See {@link android.content.ClipData} and {@link android.content.ClipboardManager}
-for more information. You can also see an example implementation of copy/paste in an updated
-version of the NotePad application (available in the samples package).</p>
-
-
-<h2>Drag and Drop</h2>
-
-<p>New APIs to perform drag and drop operations, leveraging the system clipboard APIs to
-transport data.</p>
-
-<ul>
- <li>Any {@link android.view.View} can be used for a drag and drop event and a thumbnail of that
-view is generated and used during the drag</li>
- <li>{@link android.view.ViewGroup}s that can receive the object are notified during hover and drop
-events</li>
- <li>The new {@link android.view.DragEvent} class describes a drag event relating to a view,
-including the item's current coordinates, the type of action (whether the drag has entered the
-view, exited the view, started, dropped, etc.), and provides access to the {@link
-android.content.ClipData} being carried</li>
- <li>The new {@link android.view.View.OnDragListener} interface defines a callback that views
-can register in order to be notified of drag events being dispatched to the view; view's can
-register a drag listener with {@link android.view.View#setOnDragListener setOnDragListener()}</li>
-</ul>
-
-<p>See {@link android.view.DragEvent} and {@link android.view.View.OnDragListener} for more
-information.</p>
-
-
-<h2>New Animations</h2>
-
-<p>An all new animation framework.</p>
-
-<ul>
- <li>A flexible animation system that allows you to animate the properties of any object (View,
-Drawable, Fragment, Object, anything)</li>
-</ul>
-
-<p>See the {@link android.animation} package.</p>
-
-
-<h2>Extended App Widgets</h2>
-
-<p>App widgets can now be more interactive and accept finger gestures.</p>
-
-<ul>
- <li>The complete list of supported widgets for an app widget is now: {@link
-android.widget.AnalogClock}, {@link android.widget.Button}, {@link android.widget.Chronometer},
-{@link android.widget.ImageButton}, {@link android.widget.ImageView}, {@link
-android.widget.ProgressBar}, {@link android.widget.TextView}, {@link
-android.widget.ViewFlipper}, {@link android.widget.AdapterViewFlipper}, {@link
-android.widget.StackView}, {@link android.widget.ListView}, and {@link
-android.widget.GridView}.</li>
-</ul>
-
-
-<h2>Extended Status Bar Notifications</h2>
-
-<p>The {@link android.app.Notification} class has been extended to support more content-rich
-status bar notifications when on xlarge screens.</p>
-
-<ul>
- <li>New {@link android.app.Notification.Builder} class helps you easily create new {@link
-android.app.Notification} objects</li>
- <li>Support for a title in the status bar ticker (in addition to the normal ticker text)</li>
- <li>Support for a large "sender" icon in the notification—a second icon intended for
-social applications to show the contact photo of the person who is the source of the
-notification</li>
- <li>Support for custom layouts in the status bar ticker</li>
- <li>Support for buttons in the expanded notification that deliver custom intents
-(such as to control ongoing music in the background)</li>
-</ul>
-
-
-<h2>Plus Android 2.3</h2>
-
-<p>Honeycomb includes all platform changes introduced for Android 2.3.</p>
-
-<p>To take full advantage of Honeycomb, you should also be aware of the new features
-and APIs introduced for Android 2.3. To learn more, read the <a
-href="{@docRoot}sdk/android-2.3.html">Android 2.3 release notes</a>.</p>
-
-<!--
-<div class="special">
-<p>To set up your preview SDK and start developing apps for Honeycomb, see the <a
-href="{@docRoot}sdk/preview/installing.html">Getting Started</a> guide.</p>
-</div>
--->
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+<p>You should have already been redirected by your browser. Please go to the
+<a href="{@docRoot}sdk/android-3.0.html">Android 3.0 Platform</a>.</p>
\ No newline at end of file
diff --git a/docs/html/sdk/preview/index.jd b/docs/html/sdk/preview/index.jd
index edfa02b..ed8f7e0 100644
--- a/docs/html/sdk/preview/index.jd
+++ b/docs/html/sdk/preview/index.jd
@@ -1,183 +1,2 @@
-page.title=Android 3.0 Preview SDK
+sdk.redirect=true
@jd:body
-
-<p>Android 3.0 is the next major release of the Android platform and is optimized for tablet
-devices. We're offering a Preview SDK so you can get a head-start developing
-applications for it or simply optimize your existing application for upcoming
-tablets.</p>
-
-
-<h3>What is the Preview SDK?</h3>
-
-<p>The Android 3.0 Preview SDK is an early look at the upcoming version of Android 3.0, for
-developers only. </p>
-
-<p>The Preview SDK includes:</p>
-<ul>
- <li>An early Android 3.0 system image for use in the Android emulator</li>
- <li>An Android 3.0 library with non-final APIs</li>
- <li>A new WXGA emulator skin for an extra large Android Virtual Device</li>
- <li>New documentation for Android 3.0, including a complete API reference, new developer guides,
-and an API differences report between Android 3.0 and 2.3.</li>
-</ul>
-
-<div class="note">
-<p><strong>Be aware that:</strong></p>
-<ul>
- <li>The APIs in the Preview SDK are <strong>not final</strong>. Some APIs may change in behavior
-or availability when the final SDK is made available.</li>
- <li>You <strong>cannot</strong> publish an application that's built against the Preview
-SDK—you can only run an application built against the Preview SDK on the Android
-emulator.</li>
- <li>The documentation on <a href="http://developer.android.com">developer.android.com</a>
-does <strong>not</strong> include the Android 3.0 documentation—to read the API reference and
-developer guides for Android 3.0, you must install the Android 3.0 Preview documentation from
-the AVD and SDK Manager.</li>
-</ul>
-</div>
-
-
-<p><b>About emulator performance</b></p>
-
-<p>Because the Android emulator must simulate the ARM instruction set architecture on your
-computer and the WXGA screen is significantly larger than what the emulator
-normally handles, emulator performance is much slower than usual. </p>
-
-<p>In particular, initializing the emulator can be slow and can take several
-minutes, depending on your hardware. When the emulator is booting there is
-limited user feedback, so please be patient and continue waiting until you see
-the home screen appear. </p>
-
-<p>We're working hard to resolve the performance issues in the emulator and it will improve in
-future releases. In the meantime, we wanted to give developers access to new APIs and an basic test
-environment as early as possible. </p>
-
-<p>Keeping in mind that performance on the emulator does not reflect the speed or performance of
-apps on actual devices running Android 3.0, developing and testing on the emulator is still an
-important tool in evaluating your application's appearance and functionality on the new platform.
-</p>
-
-
-
-
-
-<h3>What can I do with the preview?</h3>
-
-<p>The Preview SDK is intended for testing existing applications on the new platform and
-developing new applications with new Android 3.0 APIs.</p>
-
-<p>If you have an existing Android application, you don't <em>have to</em> do anything. Android
-applications are always forward-compatible. If your application is a good citizen of the Android
-APIs, your app should work fine on devices running Android 3.0 without any additional work. However,
-in order to ensure proper performance and provide users a better experience when running your
-application on an Android 3.0 tablet, we recommend that you perform the following:</p>
-
-<ol>
- <li><b>Test your application on Android 3.0</b>
- <p>Simply install the Android 3.0 preview in your Android SDK, create an AVD using the
-Android 3.0 system image, install your application, and run some tests.</p>
- <p>As mentioned above, your application should perform as expected. You might, however,
-discover that your activity layouts are less than ideal on a large screen or some other aspects
-of your application don't behave the way you expect.</p>
- </li>
- <li><b>Inherit the new "Holographic" theme</b>
- <p>Android 3.0 offers an updated set of UI widgets that are redesigned for use on larger screens
-such as tablets and incorporate the new holographic theme. Your existing application can inherit
-the new design simply by setting the <a
-href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code <uses-sdk>}</a>
-element's {@code android:targetSdkVersion} attribute to {@code "Honeycomb"}.</p>
- <p>If you do not update the {@code android:targetSdkVersion} attribute and the {@code
-android:minSdkVersion} is set to "9" or lower, then your application uses the widget designs
-from Android 2.3 and does <em>not</em> inherit the holographic theme.</p>
- <p>In order for your application to match the rest of the system UI, we highly recommend you
-make this change to inherit the new widget styles and system theme. However, beware that doing so
-might conflict with color or text designs you applied to your application based on the previous
-system theme, so you should be sure to inspect your application UI when using the holographic
-theme.</p>
- </li>
- <li><b>Provide alternative layouts for extra large screens</b>
- <p>As discussed in the guide to <a
-href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>, Android
-2.3 and above support the <code>xlarge</code> resource qualifier, which you should use to supply
-alternative layouts for extra large screens.</p>
- <p>By providing alternative layouts for some of your activities when running on extra large
-screens, you can improve the user experience of your application on a tablet without using any
-new APIs.</p>
- <p>For example, here are some things to consider when creating a new layout for tables:</p>
- <ul>
- <li>Landscape layout: The "normal" orientation for tablets is usually landscape (wide), so
-you should be sure that your activities offer an appropriate layout for such a wide viewing
-area.</li>
- <li>Button position: Consider whether the position of the most common buttons in your UI are
-easily accessible while holding a tablet with two hands.</li>
- </ul>
- <p class="note"><strong>Note:</strong> You can add alternative resources for <em>xlarge</em>
-screens without changing your {@code minSdkVersion}. For example, if you add alternative layouts in
-<code>res/layout-xlarge/</code> and your application is compatible with older versions, such
-as Android 1.5—which doesn't support <em>xlarge</em> screens—this layout directory is
-simply ignored by those devices.</p>
- </li>
-</ol>
-
-
-<p>Otherwise, if you want to develop a new application or upgrade your existing application to
-use APIs added in Android 3.0, we encourage you to get started by developing against the Android
-3.0 preview platform. You can get started the same way as you would for any other version of
-Android.</p>
-
-
-<p>To get started—whether testing an existing application or creating a new one—follow
-the procedure in the following section to install the Preview SDK.</p>
-
-
-
-<h3 id="Setup">How do I get it?</h3>
-
-<p>To get the Preview SDK, you can download it using the Android SDK and AVD Manager.</p>
-
-<p>If you're new to Android development, start by <a href="{@docRoot}sdk/index.html">downloading the
-Android SDK starter package</a>.</p>
-
-<p><a href="{@docRoot}sdk/adding-components.html#launching">Launch the Android SDK and AVD
-Manager</a> and install the following:</p>
-<ul>
- <li>SDK Platform Android Honeycomb Preview</li>
- <li>Android SDK Tools, revision 9</li>
- <li>Android SDK Platform-tools, revision 2</li>
- <li>Documentation for Android 'Honeycomb' Preview</li>
- <li>Samples for SDK API Honeycomb Preview</li>
-</ul>
-
-<p class="note"><strong>Note:</strong> Be sure to install the documentation component for the
-Honeycomb Preview SDK. The API reference for the Android 3.0 API is <strong>not</strong> available
-online.</p>
-
-<p>Once you have installed these components, open your SDK directory and navigate to {@code
-docs/sdk/} and open {@code index.html} in your browser. </p>
-
-
-
-<h3 id="Issues">Known issues</h3>
-
-<p>The following known issues occur for Android 3.0 AVDs that are loaded in the emulator:</p>
-
-<ul>
- <li>The emulator displays a rotated portrait screen while in landscape
-orientation. To view the screen correctly in landscape orientation, turn off the auto-rotate setting
-in <strong>Settings > Screen > Auto-rotate screen</strong>. Then use Ctrl-F11 to rotate the
-emulator.</li>
- <li>You cannot take screenshots of an emulator screen. The Device Screen Capture window displays
-<strong>Screen not available</strong>.</li>
- <li>GPS emulation is currently not supported.</li>
- <li>When rotating the emulator screen by pressing Ctrl-F11, the screen turns green momentarily,
-then displays the normal interface.</li>
- <li>The Dev Tools application sometimes crashes when trying to use the Package Browser
-feature.</li>
-</ul>
-
-
-<div class="special">
- <p>For an overview of new features in Android 3.0, read the <a
-href="{@docRoot}sdk/android-3.0-highlights.html">Platform Highlights</a>.</p>
-</div>
-
diff --git a/docs/html/sdk/preview/installing.jd b/docs/html/sdk/preview/installing.jd
index c835c49..94c6f2f 100644
--- a/docs/html/sdk/preview/installing.jd
+++ b/docs/html/sdk/preview/installing.jd
@@ -1,62 +1,8 @@
-page.title=Getting Started with Honeycomb
@jd:body
-<p>First, you need to set up your development environment with the new SDK Tools and preview
-platform:</p>
+<script type="text/javascript">
+ document.location=toRoot+"sdk/installing.html"
+</script>
-<ol>
- <li>Unpack the SDK Tools r8 package you've received.
- <p>If you have an existing Android SDK directory, simply replace your existing {@code
-tools/} directory with the one from the new package and add the {@code platform-tools/}
-directory along side it (at the root of the SDK directory).</p></li>
- <li>Unpack the platform package ({@code android-Froyo}) and place it in your SDK's {@code
-platforms/} directory.</li>
- <li>If you're using Eclipse, also update your Eclipse plugin using the provided archive file.
- <ol>
- <li>Select <strong>Help > Install new software</strong>.</li>
- <li>Click <strong>Add</strong>.</li>
- <li>Click <strong>Archive</strong>.</li>
- <li>Locate and select the archive file. Click <strong>OK</strong>.
- <p>Developer Tools now appear in the Available Software window and you can proceed
-to install the plugin.</p>
- </li>
- </ol>
- </li>
-</ol>
-
-<p class="note"><strong>Note:</strong> Beginning with SDK Tools r8 (the version you've received),
-the {@code adb} tool is now located in the {@code <sdk>/platform-tools/} directory (instead
-of in {@code <sdk>/tools/}). Be sure to update your {@code PATH} environment variable and any
-build/debugging scripts you have.</p>
-
-
-
-<h2 id="Setup">Set Up Your AVD and Application</h2>
-
-<p>With your SDK now set up, follow these steps to start developing an application for
-Honeycomb.</p>
-
-<ol>
-
- <li>Create a new AVD targeted to "Android Froyo (Preview)" and with a custom skin resolution of
-1280 x 800.</li>
-
- <li>Set the build target of your application to "Android Froyo (Preview)".</li>
- <li>Set your manifest file's {@code <uses-sdk>} element to use {@code
-android:minSdkVersion="Froyo"}. For example:
-<pre>
-<manifest>
- <uses-sdk android:minSdkVersion="Froyo" />
- ...
-</manifest>
-</pre>
-<p>"Froyo" is a provisional API Level for the Honeycomb release, used only during the preview
-period. When the APIs are
-finalized and the SDK is released publicly, you must update this with the appropriate API Level
-integer.</p>
-<p class="note"><strong>Note:</strong> By providing your {@code <uses-sdk>} element in the
-manifest file <em>before</em> the {@code <application>} element, your application will
-automatically apply the new Holographic theme.</p>
-</li>
-
-</ol>
+<p>You should have already been redirected by your browser. Please go to
+<a href="{@docRoot}sdk/installing.html">Installing the SDK</a>.</p>
\ No newline at end of file
diff --git a/docs/html/sdk/preview/requirements.jd b/docs/html/sdk/preview/requirements.jd
index 1e6b26b..b5aed80 100644
--- a/docs/html/sdk/preview/requirements.jd
+++ b/docs/html/sdk/preview/requirements.jd
@@ -1,5 +1,8 @@
-sdk.redirect=true
-
@jd:body
+<script type="text/javascript">
+ document.location=toRoot+"sdk/requirements.html"
+</script>
+<p>You should have already been redirected by your browser. Please go to the
+<a href="{@docRoot}sdk/requirements.html">SDK System Requirements</a>.</p>
\ No newline at end of file
diff --git a/docs/html/sdk/preview/upgrading.jd b/docs/html/sdk/preview/upgrading.jd
index 1e6b26b..1c53bdb 100644
--- a/docs/html/sdk/preview/upgrading.jd
+++ b/docs/html/sdk/preview/upgrading.jd
@@ -1,5 +1,8 @@
-sdk.redirect=true
-
@jd:body
+<script type="text/javascript">
+ document.location=toRoot+"sdk/index.html"
+</script>
+<p>You should have already been redirected by your browser. Please go to
+<a href="{@docRoot}sdk/index.html">the Android SDK</a>.</p>
\ No newline at end of file
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/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/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/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/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/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/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/mtp/MtpClient.java b/media/java/android/mtp/MtpClient.java
index c4ee19e..d25dcb9 100644
--- a/media/java/android/mtp/MtpClient.java
+++ b/media/java/android/mtp/MtpClient.java
@@ -16,6 +16,7 @@
package android.mtp;
+import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -29,6 +30,7 @@
import java.io.IOException;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
/**
@@ -40,34 +42,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 +148,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 +163,16 @@
* @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 {
+ MtpDevice mtpDevice = new MtpDevice(usbDevice);
+ if (mtpDevice.open(mUsbManager)) {
+ mDevices.put(usbDevice.getDeviceName(), mtpDevice);
+ return mtpDevice;
+ }
}
}
return null;
@@ -170,7 +192,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 +205,7 @@
* @param listener the listener to unregister
*/
public void removeListener(Listener listener) {
- synchronized (mDeviceList) {
+ synchronized (mDevices) {
mListeners.remove(listener);
}
}
@@ -196,8 +218,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 +231,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/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/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/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/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp
index eb4c68d..03ce202 100644
--- a/media/libstagefright/MP3Extractor.cpp
+++ b/media/libstagefright/MP3Extractor.cpp
@@ -39,10 +39,10 @@
namespace android {
// Everything must match except for
-// protection, bitrate, padding, private bits, mode extension,
+// protection, bitrate, padding, private bits, mode, mode extension,
// copyright bit, original bit and emphasis.
// Yes ... there are things that must indeed match...
-static const uint32_t kMask = 0xfffe0cc0;
+static const uint32_t kMask = 0xfffe0c00;
// static
bool MP3Extractor::get_mp3_frame_size(
diff --git a/media/libstagefright/NuHTTPDataSource.cpp b/media/libstagefright/NuHTTPDataSource.cpp
index dbbf3b4..b24343f 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>
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/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/include/NuHTTPDataSource.h b/media/libstagefright/include/NuHTTPDataSource.h
index 082b589..2569568 100644
--- a/media/libstagefright/include/NuHTTPDataSource.h
+++ b/media/libstagefright/include/NuHTTPDataSource.h
@@ -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.
+ */
+
#ifndef NU_HTTP_DATA_SOURCE_H_
#define NU_HTTP_DATA_SOURCE_H_
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/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/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index d3d1750..fee245f 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,22 @@
android:exported="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>
</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-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/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-es-rUS-xlarge-land/strings.xml b/packages/SystemUI/res/values-es-rUS-xlarge-land/strings.xml
deleted file mode 100644
index 78a4c18..0000000
--- a/packages/SystemUI/res/values-es-rUS-xlarge-land/strings.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- XL -->
- <string name="toast_rotation_locked" msgid="2686639138967158852">"La pantalla está bloqueada en orientación paisaje."</string>
-</resources>
diff --git a/packages/SystemUI/res/values-es-rUS-xlarge-port/strings.xml b/packages/SystemUI/res/values-es-rUS-xlarge-port/strings.xml
deleted file mode 100644
index 9daef6a..0000000
--- a/packages/SystemUI/res/values-es-rUS-xlarge-port/strings.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- XL -->
- <string name="toast_rotation_locked" msgid="4297721709987511908">"La pantalla está bloqueada en orientación retrato."</string>
-</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index ebd48e7..becad6a 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -115,4 +115,11 @@
<!-- 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>
+
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java
index ce0848b..e9db998 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java
@@ -89,14 +89,12 @@
public int compare(InputMethodInfo imi1, InputMethodInfo imi2) {
if (imi2 == null) return 0;
if (imi1 == null) return 1;
- if (mPackageManager != null) {
- CharSequence imiId1 = imi1.loadLabel(mPackageManager) + "/" + imi1.getId();
- CharSequence imiId2 = imi2.loadLabel(mPackageManager) + "/" + imi2.getId();
- if (imiId1 != null && imiId2 != null) {
- return imiId1.toString().compareTo(imiId2.toString());
- }
+ if (mPackageManager == null) {
+ return imi1.getId().compareTo(imi2.getId());
}
- return imi1.getId().compareTo(imi2.getId());
+ CharSequence imiId1 = imi1.loadLabel(mPackageManager) + "/" + imi1.getId();
+ CharSequence imiId2 = imi2.loadLabel(mPackageManager) + "/" + imi2.getId();
+ return imiId1.toString().compareTo(imiId2.toString());
}
}
@@ -267,7 +265,6 @@
Map<InputMethodInfo, List<InputMethodSubtype>> enabledIMIs =
getEnabledInputMethodAndSubtypeList();
- // TODO: Sort by alphabet and mode.
Set<InputMethodInfo> cachedImiSet = enabledIMIs.keySet();
for (InputMethodInfo imi: cachedImiSet) {
List<InputMethodSubtype> subtypes = enabledIMIs.get(imi);
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/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/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..f1784df
--- /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 mAlwaysCheck;
+ 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);
+ mAlwaysCheck = (CheckBox)ap.mView.findViewById(com.android.internal.R.id.alwaysUse);
+ mAlwaysCheck.setText(com.android.internal.R.string.alwaysUse);
+ mAlwaysCheck.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 (mAlwaysCheck.isChecked()) {
+ service.setDevicePackage(mDevice, mPackageName);
+ }
+ }
+ }
+ if (mAccessory != null) {
+ intent.putExtra(UsbManager.EXTRA_ACCESSORY, mAccessory);
+ if (mPermissionGranted) {
+ service.grantAccessoryPermission(mAccessory, mUid);
+ if (mAlwaysCheck.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 70%
rename from services/java/com/android/server/usb/UsbResolverActivity.java
rename to packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java
index e8a09a5..84d73dd 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,7 +54,6 @@
}
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. */
@@ -58,6 +61,27 @@
This is necessary because this activity is needed for the user to allow
the application permission to access the device */
);
+
+ 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 +89,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/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 0606307..487ecff 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -354,8 +354,7 @@
}
#endif
- mThrottleState.lastEventTime = entry->eventTime < currentTime
- ? entry->eventTime : currentTime;
+ mThrottleState.lastEventTime = currentTime;
mThrottleState.lastDeviceId = deviceId;
mThrottleState.lastSource = source;
}
@@ -2246,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;
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index 084264b..3688bfc 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -1036,9 +1036,6 @@
getContext()->fadePointer();
}
- if (policyFlags & POLICY_FLAG_FUNCTION) {
- newMetaState |= AMETA_FUNCTION_ON;
- }
getDispatcher()->notifyKey(when, getDeviceId(), mSources, policyFlags,
down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
@@ -3863,7 +3860,10 @@
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, axis.min, axis.max, axis.flat, axis.fuzz);
+ if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
+ info->addMotionRange(axis.axisInfo.highAxis, axis.min, axis.max, axis.flat, axis.fuzz);
+ }
}
}
@@ -3874,18 +3874,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 +3911,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 +3967,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 +3987,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 +4023,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 +4038,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 +4052,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 +4095,7 @@
}
void JoystickInputMapper::sync(nsecs_t when, bool force) {
- if (!force && !haveAxesChangedSignificantly()) {
+ if (!filterAxes(force)) {
return;
}
@@ -4053,9 +4106,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 +4125,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..b9e3494 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -999,38 +999,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 +1051,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/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp
index 1180b83..f7e1890 100644
--- a/services/input/tests/InputReader_test.cpp
+++ b/services/input/tests/InputReader_test.cpp
@@ -592,7 +592,7 @@
}
virtual status_t mapAxis(int32_t deviceId, int scancode,
- int32_t* outAxis) const {
+ AxisInfo* outAxisInfo) const {
return NAME_NOT_FOUND;
}
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index c48f360..ea38fbb 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -379,6 +379,10 @@
}
}
+ // Done: reset the session timeout clock
+ removeMessages(MSG_RESTORE_TIMEOUT);
+ sendEmptyMessageDelayed(MSG_RESTORE_TIMEOUT, TIMEOUT_RESTORE_INTERVAL);
+
mWakelock.release();
}
break;
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/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 44b8590..9c9d406 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -82,8 +82,8 @@
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
-import java.text.Collator;
import java.util.ArrayList;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -1750,10 +1750,28 @@
hideInputMethodMenuLocked();
- final Map<CharSequence, Pair<InputMethodInfo, Integer>> imMap =
- new TreeMap<CharSequence, Pair<InputMethodInfo, Integer>>(Collator.getInstance());
+ final TreeMap<InputMethodInfo, List<InputMethodSubtype>> sortedImmis =
+ new TreeMap<InputMethodInfo, List<InputMethodSubtype>>(
+ new Comparator<InputMethodInfo>() {
+ @Override
+ public int compare(InputMethodInfo imi1, InputMethodInfo imi2) {
+ if (imi2 == null) return 0;
+ if (imi1 == null) return 1;
+ if (pm == null) {
+ return imi1.getId().compareTo(imi2.getId());
+ }
+ CharSequence imiId1 = imi1.loadLabel(pm) + "/" + imi1.getId();
+ CharSequence imiId2 = imi2.loadLabel(pm) + "/" + imi2.getId();
+ return imiId1.toString().compareTo(imiId2.toString());
+ }
+ });
- for (InputMethodInfo imi: immis.keySet()) {
+ sortedImmis.putAll(immis);
+
+ final ArrayList<Pair<CharSequence, Pair<InputMethodInfo, Integer>>> imList =
+ new ArrayList<Pair<CharSequence, Pair<InputMethodInfo, Integer>>>();
+
+ for (InputMethodInfo imi : sortedImmis.keySet()) {
if (imi == null) continue;
List<InputMethodSubtype> explicitlyOrImplicitlyEnabledSubtypeList = immis.get(imi);
HashSet<String> enabledSubtypeSet = new HashSet<String>();
@@ -1761,40 +1779,45 @@
enabledSubtypeSet.add(String.valueOf(subtype.hashCode()));
}
ArrayList<InputMethodSubtype> subtypes = getSubtypes(imi);
- CharSequence label = imi.loadLabel(pm);
+ final CharSequence label = imi.loadLabel(pm);
if (showSubtypes && enabledSubtypeSet.size() > 0) {
final int subtypeCount = imi.getSubtypeCount();
for (int j = 0; j < subtypeCount; ++j) {
InputMethodSubtype subtype = imi.getSubtypeAt(j);
if (enabledSubtypeSet.contains(String.valueOf(subtype.hashCode()))) {
- CharSequence title;
+ final CharSequence title;
int nameResId = subtype.getNameResId();
String mode = subtype.getMode();
if (nameResId != 0) {
- title = pm.getText(imi.getPackageName(), nameResId,
- imi.getServiceInfo().applicationInfo);
+ title = TextUtils.concat(pm.getText(imi.getPackageName(),
+ nameResId, imi.getServiceInfo().applicationInfo),
+ (TextUtils.isEmpty(label) ? "" : " (" + label + ")"));
} else {
CharSequence language = subtype.getLocale();
// TODO: Use more friendly Title and UI
title = label + "," + (mode == null ? "" : mode) + ","
+ (language == null ? "" : language);
}
- imMap.put(title, new Pair<InputMethodInfo, Integer>(imi, j));
+ imList.add(new Pair<CharSequence, Pair<InputMethodInfo, Integer>>(
+ title, new Pair<InputMethodInfo, Integer>(imi, j)));
}
}
} else {
- imMap.put(label,
- new Pair<InputMethodInfo, Integer>(imi, NOT_A_SUBTYPE_ID));
+ imList.add(new Pair<CharSequence, Pair<InputMethodInfo, Integer>>(
+ label, new Pair<InputMethodInfo, Integer>(imi, NOT_A_SUBTYPE_ID)));
}
}
- final int N = imMap.size();
- mItems = imMap.keySet().toArray(new CharSequence[N]);
+ final int N = imList.size();
+ mItems = new CharSequence[N];
+ for (int i = 0; i < N; ++i) {
+ mItems[i] = imList.get(i).first;
+ }
mIms = new InputMethodInfo[N];
mSubtypeIds = new int[N];
int checkedItem = 0;
for (int i = 0; i < N; ++i) {
- Pair<InputMethodInfo, Integer> value = imMap.get(mItems[i]);
+ Pair<InputMethodInfo, Integer> value = imList.get(i).second;
mIms[i] = value.first;
mSubtypeIds[i] = value.second;
if (mIms[i].getId().equals(lastInputMethodId)) {
@@ -1859,8 +1882,10 @@
});
}
mSwitchingDialog = mDialogBuilder.create();
+ mSwitchingDialog.setCanceledOnTouchOutside(true);
mSwitchingDialog.getWindow().setType(
WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG);
+ mSwitchingDialog.getWindow().getAttributes().setTitle("Select input method");
mSwitchingDialog.show();
}
}
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 461a3e5..04f271d 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -2025,10 +2025,10 @@
final int M = prefs.size();
for (int i=0; i<M; i++) {
PreferredActivity pa = prefs.get(i);
- if (pa.mMatch != match) {
+ if (pa.mPref.mMatch != match) {
continue;
}
- ActivityInfo ai = getActivityInfo(pa.mActivity, flags);
+ ActivityInfo ai = getActivityInfo(pa.mPref.mComponent, flags);
if (DEBUG_PREFERRED) {
Log.v(TAG, "Got preferred activity:");
if (ai != null) {
@@ -2052,7 +2052,7 @@
// If the result set is different from when this
// was created, we need to clear it and re-ask the
// user their preference.
- if (!pa.sameSet(query, priority)) {
+ if (!pa.mPref.sameSet(query, priority)) {
Slog.i(TAG, "Result set changed, dropping preferred activity for "
+ intent + " type " + resolvedType);
mSettings.mPreferredActivities.removeFilter(pa);
@@ -6358,7 +6358,7 @@
// remove from preferred activities.
ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
for (PreferredActivity pa : mSettings.mPreferredActivities.filterSet()) {
- if (pa.mActivity.getPackageName().equals(deletedPs.name)) {
+ if (pa.mPref.mComponent.getPackageName().equals(deletedPs.name)) {
removed.add(pa);
}
}
@@ -6805,7 +6805,7 @@
PreferredActivity pa = it.next();
if (pa.getAction(0).equals(action) && pa.getCategory(0).equals(category)) {
it.remove();
- Log.i(TAG, "Removed preferred activity " + pa.mActivity + ":");
+ Log.i(TAG, "Removed preferred activity " + pa.mPref.mComponent + ":");
filter.dump(new LogPrinter(Log.INFO, TAG), " ");
}
}
@@ -6843,7 +6843,7 @@
Iterator<PreferredActivity> it = mSettings.mPreferredActivities.filterIterator();
while (it.hasNext()) {
PreferredActivity pa = it.next();
- if (pa.mActivity.getPackageName().equals(packageName)) {
+ if (pa.mPref.mComponent.getPackageName().equals(packageName)) {
it.remove();
changed = true;
}
@@ -6860,12 +6860,12 @@
while (it.hasNext()) {
PreferredActivity pa = it.next();
if (packageName == null
- || pa.mActivity.getPackageName().equals(packageName)) {
+ || pa.mPref.mComponent.getPackageName().equals(packageName)) {
if (outFilters != null) {
outFilters.add(new IntentFilter(pa));
}
if (outActivities != null) {
- outActivities.add(pa.mActivity);
+ outActivities.add(pa.mPref.mComponent);
}
}
}
@@ -7717,168 +7717,41 @@
}
}
- static class PreferredActivity extends IntentFilter {
- final int mMatch;
- final String[] mSetPackages;
- final String[] mSetClasses;
- final String[] mSetComponents;
- final ComponentName mActivity;
- final String mShortActivity;
- String mParseError;
+ static class PreferredActivity extends IntentFilter implements PreferredComponent.Callbacks {
+ final PreferredComponent mPref;
PreferredActivity(IntentFilter filter, int match, ComponentName[] set,
ComponentName activity) {
super(filter);
- mMatch = match&IntentFilter.MATCH_CATEGORY_MASK;
- mActivity = activity;
- mShortActivity = activity.flattenToShortString();
- mParseError = null;
- if (set != null) {
- final int N = set.length;
- String[] myPackages = new String[N];
- String[] myClasses = new String[N];
- String[] myComponents = new String[N];
- for (int i=0; i<N; i++) {
- ComponentName cn = set[i];
- if (cn == null) {
- mSetPackages = null;
- mSetClasses = null;
- mSetComponents = null;
- return;
- }
- myPackages[i] = cn.getPackageName().intern();
- myClasses[i] = cn.getClassName().intern();
- myComponents[i] = cn.flattenToShortString().intern();
- }
- mSetPackages = myPackages;
- mSetClasses = myClasses;
- mSetComponents = myComponents;
- } else {
- mSetPackages = null;
- mSetClasses = null;
- mSetComponents = null;
- }
+ mPref = new PreferredComponent(this, match, set, activity);
}
PreferredActivity(XmlPullParser parser) throws XmlPullParserException,
IOException {
- mShortActivity = parser.getAttributeValue(null, "name");
- mActivity = ComponentName.unflattenFromString(mShortActivity);
- if (mActivity == null) {
- mParseError = "Bad activity name " + mShortActivity;
- }
- String matchStr = parser.getAttributeValue(null, "match");
- mMatch = matchStr != null ? Integer.parseInt(matchStr, 16) : 0;
- String setCountStr = parser.getAttributeValue(null, "set");
- int setCount = setCountStr != null ? Integer.parseInt(setCountStr) : 0;
-
- String[] myPackages = setCount > 0 ? new String[setCount] : null;
- String[] myClasses = setCount > 0 ? new String[setCount] : null;
- String[] myComponents = setCount > 0 ? new String[setCount] : null;
-
- int setPos = 0;
-
- int outerDepth = parser.getDepth();
- int type;
- while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
- && (type != XmlPullParser.END_TAG
- || parser.getDepth() > outerDepth)) {
- if (type == XmlPullParser.END_TAG
- || type == XmlPullParser.TEXT) {
- continue;
- }
-
- String tagName = parser.getName();
- //Log.i(TAG, "Parse outerDepth=" + outerDepth + " depth="
- // + parser.getDepth() + " tag=" + tagName);
- if (tagName.equals("set")) {
- String name = parser.getAttributeValue(null, "name");
- if (name == null) {
- if (mParseError == null) {
- mParseError = "No name in set tag in preferred activity "
- + mShortActivity;
- }
- } else if (setPos >= setCount) {
- if (mParseError == null) {
- mParseError = "Too many set tags in preferred activity "
- + mShortActivity;
- }
- } else {
- ComponentName cn = ComponentName.unflattenFromString(name);
- if (cn == null) {
- if (mParseError == null) {
- mParseError = "Bad set name " + name + " in preferred activity "
- + mShortActivity;
- }
- } else {
- myPackages[setPos] = cn.getPackageName();
- myClasses[setPos] = cn.getClassName();
- myComponents[setPos] = name;
- setPos++;
- }
- }
- XmlUtils.skipCurrentTag(parser);
- } else if (tagName.equals("filter")) {
- //Log.i(TAG, "Starting to parse filter...");
- readFromXml(parser);
- //Log.i(TAG, "Finished filter: outerDepth=" + outerDepth + " depth="
- // + parser.getDepth() + " tag=" + parser.getName());
- } else {
- reportSettingsProblem(Log.WARN,
- "Unknown element under <preferred-activities>: "
- + parser.getName());
- XmlUtils.skipCurrentTag(parser);
- }
- }
-
- if (setPos != setCount) {
- if (mParseError == null) {
- mParseError = "Not enough set tags (expected " + setCount
- + " but found " + setPos + ") in " + mShortActivity;
- }
- }
-
- mSetPackages = myPackages;
- mSetClasses = myClasses;
- mSetComponents = myComponents;
+ mPref = new PreferredComponent(this, parser);
}
public void writeToXml(XmlSerializer serializer) throws IOException {
- final int NS = mSetClasses != null ? mSetClasses.length : 0;
- serializer.attribute(null, "name", mShortActivity);
- serializer.attribute(null, "match", Integer.toHexString(mMatch));
- serializer.attribute(null, "set", Integer.toString(NS));
- for (int s=0; s<NS; s++) {
- serializer.startTag(null, "set");
- serializer.attribute(null, "name", mSetComponents[s]);
- serializer.endTag(null, "set");
- }
+ mPref.writeToXml(serializer);
serializer.startTag(null, "filter");
super.writeToXml(serializer);
serializer.endTag(null, "filter");
}
- boolean sameSet(List<ResolveInfo> query, int priority) {
- if (mSetPackages == null) return false;
- final int NQ = query.size();
- final int NS = mSetPackages.length;
- int numMatch = 0;
- for (int i=0; i<NQ; i++) {
- ResolveInfo ri = query.get(i);
- if (ri.priority != priority) continue;
- ActivityInfo ai = ri.activityInfo;
- boolean good = false;
- for (int j=0; j<NS; j++) {
- if (mSetPackages[j].equals(ai.packageName)
- && mSetClasses[j].equals(ai.name)) {
- numMatch++;
- good = true;
- break;
- }
- }
- if (!good) return false;
+ public boolean onReadTag(String tagName, XmlPullParser parser)
+ throws XmlPullParserException, IOException {
+ if (tagName.equals("filter")) {
+ //Log.i(TAG, "Starting to parse filter...");
+ readFromXml(parser);
+ //Log.i(TAG, "Finished filter: outerDepth=" + outerDepth + " depth="
+ // + parser.getDepth() + " tag=" + parser.getName());
+ } else {
+ reportSettingsProblem(Log.WARN,
+ "Unknown element under <preferred-activities>: "
+ + parser.getName());
+ XmlUtils.skipCurrentTag(parser);
}
- return numMatch == NS;
+ return true;
}
}
@@ -8161,24 +8034,12 @@
new IntentResolver<PreferredActivity, PreferredActivity>() {
@Override
protected String packageForFilter(PreferredActivity filter) {
- return filter.mActivity.getPackageName();
+ return filter.mPref.mComponent.getPackageName();
}
@Override
protected void dumpFilter(PrintWriter out, String prefix,
PreferredActivity filter) {
- out.print(prefix); out.print(
- Integer.toHexString(System.identityHashCode(filter)));
- out.print(' ');
- out.print(filter.mActivity.flattenToShortString());
- out.print(" match=0x");
- out.println( Integer.toHexString(filter.mMatch));
- if (filter.mSetComponents != null) {
- out.print(prefix); out.println(" Selected from:");
- for (int i=0; i<filter.mSetComponents.length; i++) {
- out.print(prefix); out.print(" ");
- out.println(filter.mSetComponents[i]);
- }
- }
+ filter.mPref.dump(out, prefix, filter);
}
};
private final HashMap<String, SharedUserSetting> mSharedUsers =
@@ -10010,12 +9871,12 @@
String tagName = parser.getName();
if (tagName.equals("item")) {
PreferredActivity pa = new PreferredActivity(parser);
- if (pa.mParseError == null) {
+ if (pa.mPref.getParseError() == null) {
mPreferredActivities.addFilter(pa);
} else {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: <preferred-activity> "
- + pa.mParseError + " at "
+ + pa.mPref.getParseError() + " at "
+ parser.getPositionDescription());
}
} else {
diff --git a/services/java/com/android/server/PreferredComponent.java b/services/java/com/android/server/PreferredComponent.java
new file mode 100644
index 0000000..718b05d
--- /dev/null
+++ b/services/java/com/android/server/PreferredComponent.java
@@ -0,0 +1,219 @@
+/*
+ * 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.server;
+
+import com.android.internal.util.XmlUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import android.content.ComponentName;
+import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ResolveInfo;
+import android.util.Slog;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.List;
+
+public class PreferredComponent {
+ public final int mMatch;
+ public final ComponentName mComponent;
+
+ private final String[] mSetPackages;
+ private final String[] mSetClasses;
+ private final String[] mSetComponents;
+ private final String mShortComponent;
+ private String mParseError;
+
+ private final Callbacks mCallbacks;
+
+ public interface Callbacks {
+ public boolean onReadTag(String tagName, XmlPullParser parser)
+ throws XmlPullParserException, IOException;
+ }
+
+ public PreferredComponent(Callbacks callbacks, int match, ComponentName[] set,
+ ComponentName component) {
+ mCallbacks = callbacks;
+ mMatch = match&IntentFilter.MATCH_CATEGORY_MASK;
+ mComponent = component;
+ mShortComponent = component.flattenToShortString();
+ mParseError = null;
+ if (set != null) {
+ final int N = set.length;
+ String[] myPackages = new String[N];
+ String[] myClasses = new String[N];
+ String[] myComponents = new String[N];
+ for (int i=0; i<N; i++) {
+ ComponentName cn = set[i];
+ if (cn == null) {
+ mSetPackages = null;
+ mSetClasses = null;
+ mSetComponents = null;
+ return;
+ }
+ myPackages[i] = cn.getPackageName().intern();
+ myClasses[i] = cn.getClassName().intern();
+ myComponents[i] = cn.flattenToShortString().intern();
+ }
+ mSetPackages = myPackages;
+ mSetClasses = myClasses;
+ mSetComponents = myComponents;
+ } else {
+ mSetPackages = null;
+ mSetClasses = null;
+ mSetComponents = null;
+ }
+ }
+
+ public PreferredComponent(Callbacks callbacks, XmlPullParser parser)
+ throws XmlPullParserException, IOException {
+ mCallbacks = callbacks;
+ mShortComponent = parser.getAttributeValue(null, "name");
+ mComponent = ComponentName.unflattenFromString(mShortComponent);
+ if (mComponent == null) {
+ mParseError = "Bad activity name " + mShortComponent;
+ }
+ String matchStr = parser.getAttributeValue(null, "match");
+ mMatch = matchStr != null ? Integer.parseInt(matchStr, 16) : 0;
+ String setCountStr = parser.getAttributeValue(null, "set");
+ int setCount = setCountStr != null ? Integer.parseInt(setCountStr) : 0;
+
+ String[] myPackages = setCount > 0 ? new String[setCount] : null;
+ String[] myClasses = setCount > 0 ? new String[setCount] : null;
+ String[] myComponents = setCount > 0 ? new String[setCount] : null;
+
+ int setPos = 0;
+
+ int outerDepth = parser.getDepth();
+ int type;
+ while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG
+ || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG
+ || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ String tagName = parser.getName();
+ //Log.i(TAG, "Parse outerDepth=" + outerDepth + " depth="
+ // + parser.getDepth() + " tag=" + tagName);
+ if (tagName.equals("set")) {
+ String name = parser.getAttributeValue(null, "name");
+ if (name == null) {
+ if (mParseError == null) {
+ mParseError = "No name in set tag in preferred activity "
+ + mShortComponent;
+ }
+ } else if (setPos >= setCount) {
+ if (mParseError == null) {
+ mParseError = "Too many set tags in preferred activity "
+ + mShortComponent;
+ }
+ } else {
+ ComponentName cn = ComponentName.unflattenFromString(name);
+ if (cn == null) {
+ if (mParseError == null) {
+ mParseError = "Bad set name " + name + " in preferred activity "
+ + mShortComponent;
+ }
+ } else {
+ myPackages[setPos] = cn.getPackageName();
+ myClasses[setPos] = cn.getClassName();
+ myComponents[setPos] = name;
+ setPos++;
+ }
+ }
+ XmlUtils.skipCurrentTag(parser);
+ } else if (!mCallbacks.onReadTag(tagName, parser)) {
+ Slog.w("PreferredComponent", "Unknown element: " + parser.getName());
+ XmlUtils.skipCurrentTag(parser);
+ }
+ }
+
+ if (setPos != setCount) {
+ if (mParseError == null) {
+ mParseError = "Not enough set tags (expected " + setCount
+ + " but found " + setPos + ") in " + mShortComponent;
+ }
+ }
+
+ mSetPackages = myPackages;
+ mSetClasses = myClasses;
+ mSetComponents = myComponents;
+ }
+
+ public String getParseError() {
+ return mParseError;
+ }
+
+ public void writeToXml(XmlSerializer serializer) throws IOException {
+ final int NS = mSetClasses != null ? mSetClasses.length : 0;
+ serializer.attribute(null, "name", mShortComponent);
+ if (mMatch != 0) {
+ serializer.attribute(null, "match", Integer.toHexString(mMatch));
+ }
+ serializer.attribute(null, "set", Integer.toString(NS));
+ for (int s=0; s<NS; s++) {
+ serializer.startTag(null, "set");
+ serializer.attribute(null, "name", mSetComponents[s]);
+ serializer.endTag(null, "set");
+ }
+ }
+
+ public boolean sameSet(List<ResolveInfo> query, int priority) {
+ if (mSetPackages == null) return false;
+ final int NQ = query.size();
+ final int NS = mSetPackages.length;
+ int numMatch = 0;
+ for (int i=0; i<NQ; i++) {
+ ResolveInfo ri = query.get(i);
+ if (ri.priority != priority) continue;
+ ActivityInfo ai = ri.activityInfo;
+ boolean good = false;
+ for (int j=0; j<NS; j++) {
+ if (mSetPackages[j].equals(ai.packageName)
+ && mSetClasses[j].equals(ai.name)) {
+ numMatch++;
+ good = true;
+ break;
+ }
+ }
+ if (!good) return false;
+ }
+ return numMatch == NS;
+ }
+
+ public void dump(PrintWriter out, String prefix, Object ident) {
+ out.print(prefix); out.print(
+ Integer.toHexString(System.identityHashCode(ident)));
+ out.print(' ');
+ out.print(mComponent.flattenToShortString());
+ out.print(" match=0x");
+ out.println( Integer.toHexString(mMatch));
+ if (mSetComponents != null) {
+ out.print(prefix); out.println(" Selected from:");
+ for (int i=0; i<mSetComponents.length; i++) {
+ out.print(prefix); out.print(" ");
+ out.println(mSetComponents[i]);
+ }
+ }
+ }
+}
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/CoreSettingsObserver.java b/services/java/com/android/server/am/CoreSettingsObserver.java
index 25db84a..585cf2b 100644
--- a/services/java/com/android/server/am/CoreSettingsObserver.java
+++ b/services/java/com/android/server/am/CoreSettingsObserver.java
@@ -52,7 +52,7 @@
super(activityManagerService.mHandler);
mActivityManagerService = activityManagerService;
beginObserveCoreSettings();
- populateCoreSettings(mCoreSettings);
+ sendCoreSettings();
}
public Bundle getCoreSettingsLocked() {
@@ -62,11 +62,15 @@
@Override
public void onChange(boolean selfChange) {
synchronized (mActivityManagerService) {
- populateCoreSettings(mCoreSettings);
- mActivityManagerService.onCoreSettingsChange(mCoreSettings);
+ sendCoreSettings();
}
}
+ private void sendCoreSettings() {
+ populateCoreSettings(mCoreSettings);
+ mActivityManagerService.onCoreSettingsChange(mCoreSettings);
+ }
+
private void beginObserveCoreSettings() {
for (String setting : sCoreSettingToTypeMap.keySet()) {
Uri uri = Settings.Secure.getUriFor(setting);
diff --git a/services/java/com/android/server/usb/UsbDeviceSettingsManager.java b/services/java/com/android/server/usb/UsbDeviceSettingsManager.java
index 2f22fe1..29e6f94 100644
--- a/services/java/com/android/server/usb/UsbDeviceSettingsManager.java
+++ b/services/java/com/android/server/usb/UsbDeviceSettingsManager.java
@@ -16,11 +16,13 @@
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.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
@@ -602,50 +604,20 @@
}
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) {
@@ -656,49 +628,86 @@
}
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));
}
+ resolveActivity(intent, matches, defaultPackage, null, accessory);
+ }
+
+ 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) 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;
+ 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;
+ int uid = rInfo.activityInfo.applicationInfo.uid;
+ // grant permission
+ if (device != null) {
+ grantDevicePermission(device, uid);
+ } else if (accessory != null) {
+ grantAccessoryPermission(accessory, uid);
}
}
}
- Intent intent = new Intent(mContext, UsbResolverActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ 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;
+ }
+ }
+ }
- 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");
+ if (defaultRI != null) {
+ // 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 {
+ long identity = Binder.clearCallingIdentity();
+
+ // start UsbResolverActivity so user can choose an activity
+ Intent resolverIntent = new Intent();
+ resolverIntent.setClassName("com.android.systemui",
+ "com.android.systemui.usb.UsbResolverActivity");
+ resolverIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ resolverIntent.putExtra(Intent.EXTRA_INTENT, intent);
+ resolverIntent.putParcelableArrayListExtra("rlist", matches);
+ try {
+ mContext.startActivity(resolverIntent);
+ } catch (ActivityNotFoundException e) {
+ Log.e(TAG, "unable to start UsbResolverActivity");
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
}
@@ -709,40 +718,121 @@
mContext.sendBroadcast(intent);
}
- public void checkPermission(UsbDevice device) {
- if (device == null) return;
+ public boolean hasPermission(UsbDevice device) {
synchronized (mLock) {
- ArrayList<DeviceFilter> filterList = mDevicePermissionMap.get(Binder.getCallingUid());
+ 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;
+ return true;
}
}
}
}
- throw new SecurityException("User has not given permission to device " + device);
+ return false;
}
- public void checkPermission(UsbAccessory accessory) {
- if (accessory == null) return;
+ public boolean hasPermission(UsbAccessory accessory) {
synchronized (mLock) {
- ArrayList<AccessoryFilter> filterList = mAccessoryPermissionMap.get(Binder.getCallingUid());
+ 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;
+ return true;
}
}
}
}
- throw new SecurityException("User has not given permission to accessory " + accessory);
+ return false;
+ }
+
+ 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 (!hasPermission(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 = mContext.getPackageManager().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) {
diff --git a/services/java/com/android/server/usb/UsbService.java b/services/java/com/android/server/usb/UsbService.java
index 8170c61..d0a2492 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;
@@ -454,6 +455,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);
diff --git a/services/java/com/android/server/wm/InputManager.java b/services/java/com/android/server/wm/InputManager.java
index fc32d5a..ca1da95 100644
--- a/services/java/com/android/server/wm/InputManager.java
+++ b/services/java/com/android/server/wm/InputManager.java
@@ -549,7 +549,7 @@
} catch (NumberFormatException e) {
}
if (result < 1) {
- result = 60;
+ result = 55;
}
return result;
}
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index eed41a0..8ccfbba 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -4791,13 +4791,17 @@
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);
@@ -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..1c72709 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
}
@@ -1227,8 +1221,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,77 +1238,82 @@
// 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");
@@ -1337,28 +1335,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/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/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..0b10727 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -209,9 +209,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;
@@ -397,7 +394,7 @@
Settings.Secure.DATA_ROAMING, enabled ? 1 : 0);
if (mPhone.getServiceState().getRoaming()) {
if (enabled) {
- mRetryMgr.resetRetryCount();
+ resetAllRetryCounts();
}
sendMessage(obtainMessage(EVENT_ROAMING_ON));
}
@@ -449,7 +446,7 @@
case EVENT_ROAMING_OFF:
if (getDataOnRoamingEnabled() == false) {
- mRetryMgr.resetRetryCount();
+ resetAllRetryCounts();
}
onRoamingOff();
break;
@@ -883,7 +880,7 @@
}
if (prevEnabled != getAnyDataEnabled()) {
if (!prevEnabled) {
- mRetryMgr.resetRetryCount();
+ resetAllRetryCounts();
onTrySetupData(Phone.REASON_DATA_ENABLED);
} else {
cleanUpAllConnections();
@@ -917,7 +914,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 +922,10 @@
}
}
}
+
+ protected void resetAllRetryCounts() {
+ for (DataConnection dc : mDataConnections.values()) {
+ dc.resetRetryCount();
+ }
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index 1d194d0..970cf12 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -1396,33 +1396,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 +2067,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/cdma/CDMALTEPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
index 300670f..89d7174 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
@@ -54,13 +54,16 @@
public CDMALTEPhone(Context context, CommandsInterface ci, PhoneNotifier notifier,
boolean unitTestMode) {
super(context, ci, notifier, false);
- mSST = new CdmaLteServiceStateTracker(this);
- init(context, notifier);
mSIMRecords = new SIMRecords(this);
mSimCard = new SimCard(this, LOG_TAG, DBG);
}
+ @Override
+ protected void initSST() {
+ mSST = new CdmaLteServiceStateTracker(this);
+ }
+
public void dispose() {
synchronized (PhoneProxy.lockForRadioTechnologyChange) {
super.dispose();
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index 3772dac..dd5091c 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -142,17 +142,21 @@
// Constructors
public CDMAPhone(Context context, CommandsInterface ci, PhoneNotifier notifier) {
super(notifier, context, ci, false);
- mSST = new CdmaServiceStateTracker (this);
+ initSST();
init(context, notifier);
}
public CDMAPhone(Context context, CommandsInterface ci, PhoneNotifier notifier,
boolean unitTestMode) {
super(notifier, context, ci, unitTestMode);
- mSST = new CdmaServiceStateTracker (this);
+ initSST();
init(context, notifier);
}
+ protected void initSST() {
+ mSST = new CdmaServiceStateTracker(this);
+ }
+
protected void init(Context context, PhoneNotifier notifier) {
mCM.setPhoneType(Phone.PHONE_TYPE_CDMA);
mCT = new CdmaCallTracker(this);
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..fa04e0f 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);
@@ -1883,7 +1885,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/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 {
/**