summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.xml63
-rw-r--r--core/java/android/app/ContextImpl.java14
-rw-r--r--core/java/android/content/SharedPreferences.java24
-rw-r--r--core/java/android/net/LinkProperties.aidl (renamed from core/java/android/net/NetworkProperties.aidl)2
-rw-r--r--core/java/android/net/LinkProperties.java (renamed from core/java/android/net/NetworkProperties.java)64
-rw-r--r--core/java/android/net/MobileDataStateTracker.java22
-rw-r--r--core/java/android/net/NetworkStateTracker.java4
-rw-r--r--core/java/android/net/ProxyProperties.java23
-rw-r--r--core/java/android/preference/Preference.java2
-rw-r--r--core/java/android/provider/CallLog.java11
-rw-r--r--core/java/android/provider/ContactsContract.java16
-rw-r--r--core/java/android/server/BluetoothService.java2
-rw-r--r--core/java/android/view/IWindowManager.aidl5
-rw-r--r--core/java/android/view/InputDevice.aidl20
-rwxr-xr-xcore/java/android/view/InputDevice.java219
-rw-r--r--core/java/android/widget/AdapterView.java15
-rw-r--r--core/java/com/android/internal/widget/PointerLocationView.java406
-rw-r--r--include/ui/EventHub.h8
-rw-r--r--include/ui/Input.h4
-rw-r--r--include/ui/InputReader.h157
-rw-r--r--libs/ui/EventHub.cpp9
-rw-r--r--libs/ui/InputDispatcher.cpp22
-rw-r--r--libs/ui/InputReader.cpp1046
-rw-r--r--media/libstagefright/rtsp/ARTPConnection.cpp8
-rw-r--r--media/libstagefright/rtsp/ARTPSession.cpp1
-rw-r--r--media/libstagefright/rtsp/MyHandler.h107
-rw-r--r--native/include/android/input.h2
-rw-r--r--packages/SystemUI/proguard.flags1
-rwxr-xr-xpackages/SystemUI/res/drawable/status_bar_recent.xml21
-rw-r--r--packages/SystemUI/res/layout-xlarge/status_bar.xml11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java10
-rw-r--r--services/java/com/android/server/BootReceiver.java2
-rw-r--r--services/java/com/android/server/ConnectivityService.java17
-rw-r--r--services/java/com/android/server/InputManager.java64
-rw-r--r--services/java/com/android/server/TelephonyRegistry.java18
-rw-r--r--services/java/com/android/server/WindowManagerService.java8
-rw-r--r--services/jni/com_android_server_InputManager.cpp179
-rw-r--r--telephony/java/android/telephony/PhoneNumberUtils.java46
-rw-r--r--telephony/java/com/android/internal/telephony/DataConnection.java33
-rw-r--r--telephony/java/com/android/internal/telephony/DataConnectionTracker.java14
-rw-r--r--telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java8
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl4
-rw-r--r--telephony/java/com/android/internal/telephony/Phone.java8
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneBase.java6
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneProxy.java6
-rw-r--r--telephony/java/com/android/internal/telephony/SipPhoneNotifier.java8
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java2
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java4
-rwxr-xr-xtelephony/java/com/android/internal/telephony/sip/SipPhoneBase.java4
-rw-r--r--telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java16
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java6
-rw-r--r--wifi/java/android/net/wifi/WifiStateMachine.java30
-rw-r--r--wifi/java/android/net/wifi/WifiStateTracker.java22
54 files changed, 2180 insertions, 646 deletions
diff --git a/api/current.xml b/api/current.xml
index 2d7c02e2a048..8549080621dc 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -51424,7 +51424,7 @@
<parameter name="key" type="java.lang.String">
</parameter>
</method>
-<method name="startCommit"
+<method name="apply"
return="void"
abstract="true"
native="false"
@@ -186729,14 +186729,19 @@
deprecated="not deprecated"
visibility="public"
>
-<constructor name="InputDevice"
- type="android.view.InputDevice"
+<implements name="android.os.Parcelable">
+</implements>
+<method name="describeContents"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
-</constructor>
+</method>
<method name="getDevice"
return="android.view.InputDevice"
abstract="false"
@@ -186750,6 +186755,28 @@
<parameter name="id" type="int">
</parameter>
</method>
+<method name="getDeviceIds"
+ return="int[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getId"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getKeyCharacterMap"
return="android.view.KeyCharacterMap"
abstract="false"
@@ -186782,7 +186809,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="range" type="int">
+<parameter name="rangeType" type="int">
</parameter>
</method>
<method name="getName"
@@ -186807,8 +186834,8 @@
visibility="public"
>
</method>
-<method name="hasKey"
- return="boolean"
+<method name="writeToParcel"
+ return="void"
abstract="false"
native="false"
synchronized="false"
@@ -186817,9 +186844,21 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="keyCode" type="int">
+<parameter name="out" type="android.os.Parcel">
+</parameter>
+<parameter name="flags" type="int">
</parameter>
</method>
+<field name="CREATOR"
+ type="android.os.Parcelable.Creator"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="KEYBOARD_TYPE_ALPHABETIC"
type="int"
transient="false"
@@ -187148,14 +187187,6 @@
deprecated="not deprecated"
visibility="public"
>
-<constructor name="InputDevice.MotionRange"
- type="android.view.InputDevice.MotionRange"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</constructor>
<method name="getFlat"
return="float"
abstract="false"
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 775c9f2ab99d..00d769f9a85f 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -124,7 +124,6 @@ import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
-import java.util.concurrent.atomic.AtomicBoolean;
class ReceiverRestrictedContext extends ContextWrapper {
ReceiverRestrictedContext(Context base) {
@@ -2852,8 +2851,6 @@ class ContextImpl extends Context {
private final Map<String, Object> mModified = Maps.newHashMap();
private boolean mClear = false;
- private AtomicBoolean mCommitInFlight = new AtomicBoolean(false);
-
public Editor putString(String key, String value) {
synchronized (this) {
mModified.put(key, value);
@@ -2905,11 +2902,7 @@ class ContextImpl extends Context {
}
}
- public void startCommit() {
- if (!mCommitInFlight.compareAndSet(false, true)) {
- throw new IllegalStateException("can't call startCommit() twice");
- }
-
+ public void apply() {
final MemoryCommitResult mcr = commitToMemory();
final Runnable awaitCommit = new Runnable() {
public void run() {
@@ -2925,7 +2918,6 @@ class ContextImpl extends Context {
Runnable postWriteRunnable = new Runnable() {
public void run() {
awaitCommit.run();
- mCommitInFlight.set(false);
QueuedWork.remove(awaitCommit);
}
};
@@ -3049,13 +3041,13 @@ class ContextImpl extends Context {
* that they're enqueued.
*
* @param postWriteRunnable if non-null, we're being called
- * from startCommit() and this is the runnable to run after
+ * from apply() and this is the runnable to run after
* the write proceeds. if null (from a regular commit()),
* then we're allowed to do this disk write on the main
* thread (which in addition to reducing allocations and
* creating a background thread, this has the advantage that
* we catch them in userdebug StrictMode reports to convert
- * them where possible to startCommit...)
+ * them where possible to apply() ...)
*/
private void enqueueDiskWrite(final MemoryCommitResult mcr,
final Runnable postWriteRunnable) {
diff --git a/core/java/android/content/SharedPreferences.java b/core/java/android/content/SharedPreferences.java
index 23ed62c0aaf0..c0788f53dd2a 100644
--- a/core/java/android/content/SharedPreferences.java
+++ b/core/java/android/content/SharedPreferences.java
@@ -55,13 +55,13 @@ public interface SharedPreferences {
/**
* Interface used for modifying values in a {@link SharedPreferences}
* object. All changes you make in an editor are batched, and not copied
- * back to the original {@link SharedPreferences} or persistent storage
- * until you call {@link #commit}.
+ * back to the original {@link SharedPreferences} until you call {@link #commit}
+ * or {@link #apply}
*/
public interface Editor {
/**
* Set a String value in the preferences editor, to be written back once
- * {@link #commit} is called.
+ * {@link #commit} or {@link #apply} are called.
*
* @param key The name of the preference to modify.
* @param value The new value for the preference.
@@ -84,7 +84,7 @@ public interface SharedPreferences {
/**
* Set an int value in the preferences editor, to be written back once
- * {@link #commit} is called.
+ * {@link #commit} or {@link #apply} are called.
*
* @param key The name of the preference to modify.
* @param value The new value for the preference.
@@ -96,7 +96,7 @@ public interface SharedPreferences {
/**
* Set a long value in the preferences editor, to be written back once
- * {@link #commit} is called.
+ * {@link #commit} or {@link #apply} are called.
*
* @param key The name of the preference to modify.
* @param value The new value for the preference.
@@ -108,7 +108,7 @@ public interface SharedPreferences {
/**
* Set a float value in the preferences editor, to be written back once
- * {@link #commit} is called.
+ * {@link #commit} or {@link #apply} are called.
*
* @param key The name of the preference to modify.
* @param value The new value for the preference.
@@ -120,7 +120,7 @@ public interface SharedPreferences {
/**
* Set a boolean value in the preferences editor, to be written back
- * once {@link #commit} is called.
+ * once {@link #commit} or {@link #apply} are called.
*
* @param key The name of the preference to modify.
* @param value The new value for the preference.
@@ -171,7 +171,7 @@ public interface SharedPreferences {
*
* <p>If you don't care about the return value and you're
* using this from your application's main thread, consider
- * using {@link #startCommit} instead.
+ * using {@link #apply} instead.
*
* @return Returns true if the new values were successfully written
* to persistent storage.
@@ -185,16 +185,16 @@ public interface SharedPreferences {
* in the SharedPreferences.
*
* <p>Note that when two editors are modifying preferences at the same
- * time, the last one to call commit wins.
+ * time, the last one to call apply wins.
*
* <p>Unlike {@link #commit}, which writes its preferences out
- * to persistent storage synchronously, {@link #startCommit}
+ * to persistent storage synchronously, {@link #apply}
* commits its changes to the in-memory
* {@link SharedPreferences} immediately but starts an
* asynchronous commit to disk and you won't be notified of
* any failures. If another editor on this
* {@link SharedPreferences} does a regular {@link #commit}
- * while a {@link #startCommit} is still outstanding, the
+ * while a {@link #apply} is still outstanding, the
* {@link #commit} will block until all async commits are
* completed as well as the commit itself.
*
@@ -202,7 +202,7 @@ public interface SharedPreferences {
* the base class will wait for any async commits to finish in
* its {@link android.app.Activity#onPause}.</p>
*/
- void startCommit();
+ void apply();
}
/**
diff --git a/core/java/android/net/NetworkProperties.aidl b/core/java/android/net/LinkProperties.aidl
index 07aac6ec101f..73c798804146 100644
--- a/core/java/android/net/NetworkProperties.aidl
+++ b/core/java/android/net/LinkProperties.aidl
@@ -18,5 +18,5 @@
package android.net;
-parcelable NetworkProperties;
+parcelable LinkProperties;
diff --git a/core/java/android/net/NetworkProperties.java b/core/java/android/net/LinkProperties.java
index 03c0a2eb5e85..24aebfcd2feb 100644
--- a/core/java/android/net/NetworkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -16,6 +16,7 @@
package android.net;
+import android.net.ProxyProperties;
import android.os.Parcelable;
import android.os.Parcel;
import android.util.Log;
@@ -26,14 +27,14 @@ import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
/**
- * Describes the properties of a network interface or single address
- * of an interface.
+ * Describes the properties of a network link.
* TODO - consider adding optional fields like Apn and ApnType
* @hide
*/
-public class NetworkProperties implements Parcelable {
+public class LinkProperties implements Parcelable {
private NetworkInterface mIface;
private Collection<InetAddress> mAddresses;
@@ -41,49 +42,60 @@ public class NetworkProperties implements Parcelable {
private InetAddress mGateway;
private ProxyProperties mHttpProxy;
- public NetworkProperties() {
+ public LinkProperties() {
clear();
}
- public synchronized void setInterface(NetworkInterface iface) {
+ // copy constructor instead of clone
+ public LinkProperties(LinkProperties source) {
+ if (source != null) {
+ mIface = source.getInterface();
+ mAddresses = source.getAddresses();
+ mDnses = source.getDnses();
+ mGateway = source.getGateway();
+ mHttpProxy = new ProxyProperties(source.getHttpProxy());
+ }
+ }
+
+ public void setInterface(NetworkInterface iface) {
mIface = iface;
}
- public synchronized NetworkInterface getInterface() {
+ public NetworkInterface getInterface() {
return mIface;
}
- public synchronized String getInterfaceName() {
+ public String getInterfaceName() {
return (mIface == null ? null : mIface.getName());
}
- public synchronized void addAddress(InetAddress address) {
+ public void addAddress(InetAddress address) {
mAddresses.add(address);
}
- public synchronized Collection<InetAddress> getAddresses() {
- return mAddresses;
+ public Collection<InetAddress> getAddresses() {
+ return Collections.unmodifiableCollection(mAddresses);
}
- public synchronized void addDns(InetAddress dns) {
+ public void addDns(InetAddress dns) {
mDnses.add(dns);
}
- public synchronized Collection<InetAddress> getDnses() {
- return mDnses;
+ public Collection<InetAddress> getDnses() {
+ return Collections.unmodifiableCollection(mDnses);
}
- public synchronized void setGateway(InetAddress gateway) {
+ public void setGateway(InetAddress gateway) {
mGateway = gateway;
}
- public synchronized InetAddress getGateway() {
+ public InetAddress getGateway() {
return mGateway;
}
- public synchronized void setHttpProxy(ProxyProperties proxy) {
+ public void setHttpProxy(ProxyProperties proxy) {
mHttpProxy = proxy;
}
- public synchronized ProxyProperties getHttpProxy() {
+ public ProxyProperties getHttpProxy() {
return mHttpProxy;
}
- public synchronized void clear() {
+ public void clear() {
mIface = null;
mAddresses = new ArrayList<InetAddress>();
mDnses = new ArrayList<InetAddress>();
@@ -100,7 +112,7 @@ public class NetworkProperties implements Parcelable {
}
@Override
- public synchronized String toString() {
+ public String toString() {
String ifaceName = (mIface == null ? "" : "InterfaceName: " + mIface.getName() + " ");
String ip = "IpAddresses: [";
@@ -121,7 +133,7 @@ public class NetworkProperties implements Parcelable {
* Implement the Parcelable interface.
* @hide
*/
- public synchronized void writeToParcel(Parcel dest, int flags) {
+ public void writeToParcel(Parcel dest, int flags) {
dest.writeString(getInterfaceName());
dest.writeInt(mAddresses.size());
//TODO: explore an easy alternative to preserve hostname
@@ -151,10 +163,10 @@ public class NetworkProperties implements Parcelable {
* Implement the Parcelable interface.
* @hide
*/
- public static final Creator<NetworkProperties> CREATOR =
- new Creator<NetworkProperties>() {
- public NetworkProperties createFromParcel(Parcel in) {
- NetworkProperties netProp = new NetworkProperties();
+ public static final Creator<LinkProperties> CREATOR =
+ new Creator<LinkProperties>() {
+ public LinkProperties createFromParcel(Parcel in) {
+ LinkProperties netProp = new LinkProperties();
String iface = in.readString();
if (iface != null) {
try {
@@ -186,8 +198,8 @@ public class NetworkProperties implements Parcelable {
return netProp;
}
- public NetworkProperties[] newArray(int size) {
- return new NetworkProperties[size];
+ public LinkProperties[] newArray(int size) {
+ return new LinkProperties[size];
}
};
}
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index 6dfd3bc8aad1..0498fff41733 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -16,8 +16,6 @@
package android.net;
-import java.net.InetAddress;
-
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -32,7 +30,7 @@ import com.android.internal.telephony.Phone;
import com.android.internal.telephony.TelephonyIntents;
import android.net.NetworkInfo.DetailedState;
import android.net.NetworkInfo;
-import android.net.NetworkProperties;
+import android.net.LinkProperties;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.text.TextUtils;
@@ -58,7 +56,7 @@ public class MobileDataStateTracker implements NetworkStateTracker {
private boolean mTeardownRequested = false;
private Handler mTarget;
private Context mContext;
- private NetworkProperties mNetworkProperties;
+ private LinkProperties mLinkProperties;
private boolean mPrivateDnsRouteSet = false;
private int mDefaultGatewayAddr = 0;
private boolean mDefaultRouteSet = false;
@@ -213,8 +211,8 @@ public class MobileDataStateTracker implements NetworkStateTracker {
+ e);
}
}
- if (doReset && mNetworkProperties != null) {
- String iface = mNetworkProperties.getInterfaceName();
+ if (doReset && mLinkProperties != null) {
+ String iface = mLinkProperties.getInterfaceName();
if (iface != null) NetworkUtils.resetConnections(iface);
}
// TODO - check this
@@ -233,11 +231,11 @@ public class MobileDataStateTracker implements NetworkStateTracker {
setDetailedState(DetailedState.SUSPENDED, reason, apnName);
break;
case CONNECTED:
- mNetworkProperties = intent.getParcelableExtra(
- Phone.DATA_NETWORK_PROPERTIES_KEY);
- if (mNetworkProperties == null) {
+ mLinkProperties = intent.getParcelableExtra(
+ Phone.DATA_LINK_PROPERTIES_KEY);
+ if (mLinkProperties == null) {
Log.d(TAG,
- "CONNECTED event did not supply network properties.");
+ "CONNECTED event did not supply link properties.");
}
setDetailedState(DetailedState.CONNECTED, reason, apnName);
break;
@@ -563,7 +561,7 @@ public class MobileDataStateTracker implements NetworkStateTracker {
}
}
- public NetworkProperties getNetworkProperties() {
- return mNetworkProperties;
+ public LinkProperties getLinkProperties() {
+ return new LinkProperties(mLinkProperties);
}
}
diff --git a/core/java/android/net/NetworkStateTracker.java b/core/java/android/net/NetworkStateTracker.java
index 0048a2e88193..420992b3bf16 100644
--- a/core/java/android/net/NetworkStateTracker.java
+++ b/core/java/android/net/NetworkStateTracker.java
@@ -91,9 +91,9 @@ public interface NetworkStateTracker {
public NetworkInfo getNetworkInfo();
/**
- * Fetch NetworkProperties for the network
+ * Fetch LinkProperties for the network
*/
- public NetworkProperties getNetworkProperties();
+ public LinkProperties getLinkProperties();
/**
* Return the system properties name associated with the tcp buffer sizes
diff --git a/core/java/android/net/ProxyProperties.java b/core/java/android/net/ProxyProperties.java
index 207fb5134a85..ba27221ed134 100644
--- a/core/java/android/net/ProxyProperties.java
+++ b/core/java/android/net/ProxyProperties.java
@@ -36,24 +36,33 @@ public class ProxyProperties implements Parcelable {
public ProxyProperties() {
}
- public synchronized InetAddress getAddress() {
+ // copy constructor instead of clone
+ public ProxyProperties(ProxyProperties source) {
+ if (source != null) {
+ mProxy = source.getAddress();
+ mPort = source.getPort();
+ mExclusionList = new String(source.getExclusionList());
+ }
+ }
+
+ public InetAddress getAddress() {
return mProxy;
}
- public synchronized void setAddress(InetAddress proxy) {
+ public void setAddress(InetAddress proxy) {
mProxy = proxy;
}
- public synchronized int getPort() {
+ public int getPort() {
return mPort;
}
- public synchronized void setPort(int port) {
+ public void setPort(int port) {
mPort = port;
}
- public synchronized String getExclusionList() {
+ public String getExclusionList() {
return mExclusionList;
}
- public synchronized void setExclusionList(String exclusionList) {
+ public void setExclusionList(String exclusionList) {
mExclusionList = exclusionList;
}
@@ -77,7 +86,7 @@ public class ProxyProperties implements Parcelable {
* Implement the Parcelable interface.
* @hide
*/
- public synchronized void writeToParcel(Parcel dest, int flags) {
+ public void writeToParcel(Parcel dest, int flags) {
if (mProxy != null) {
dest.writeByte((byte)1);
dest.writeString(mProxy.getHostName());
diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java
index 418fe1015cd4..17b2e82d09f9 100644
--- a/core/java/android/preference/Preference.java
+++ b/core/java/android/preference/Preference.java
@@ -1242,7 +1242,7 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis
private void tryCommit(SharedPreferences.Editor editor) {
if (mPreferenceManager.shouldCommit()) {
- editor.startCommit();
+ editor.apply();
}
}
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index d52632b98542..bf051f58a286 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -88,6 +88,17 @@ public class CallLog {
public static final String NUMBER = "number";
/**
+ * The ISO 3166-1 two letters country code of the country where the
+ * user received or made the call.
+ * <P>
+ * Type: TEXT
+ * </P>
+ *
+ * @hide
+ */
+ public static final String COUNTRY_ISO = "countryiso";
+
+ /**
* The date the call occured, in milliseconds since the epoch
* <P>Type: INTEGER (long)</P>
*/
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index b87e0ec0116d..9f9a4d462e2e 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -3301,6 +3301,14 @@ public final class ContactsContract {
* <P>Type: TEXT</P>
*/
public static final String LABEL = "label";
+
+ /**
+ * The phone number's E164 representation.
+ * <P>Type: TEXT</P>
+ *
+ * @hide
+ */
+ public static final String NORMALIZED_NUMBER = "normalized_number";
}
/**
@@ -4153,6 +4161,14 @@ public final class ContactsContract {
public static final String NUMBER = DATA;
/**
+ * The phone number's E164 representation.
+ * <P>Type: TEXT</P>
+ *
+ * @hide
+ */
+ public static final String NORMALIZED_NUMBER = DATA4;
+
+ /**
* @deprecated use {@link #getTypeLabel(Resources, int, CharSequence)} instead.
* @hide
*/
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index b732675c6c13..fa5f156eefe7 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -2138,7 +2138,7 @@ public class BluetoothService extends IBluetooth.Stub {
mContext.getSharedPreferences(SHARED_PREFERENCES_NAME,
mContext.MODE_PRIVATE).edit();
editor.putBoolean(SHARED_PREFERENCE_DOCK_ADDRESS + mDockAddress, true);
- editor.startCommit();
+ editor.apply();
}
}
}
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index e86e3bf3bcba..d4dd05c19adc 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -29,6 +29,7 @@ import android.view.KeyEvent;
import android.view.InputEvent;
import android.view.MotionEvent;
import android.view.InputChannel;
+import android.view.InputDevice;
/**
* System private interface to the window manager.
@@ -125,6 +126,10 @@ interface IWindowManager
// Report whether the hardware supports the given keys; returns true if successful
boolean hasKeys(in int[] keycodes, inout boolean[] keyExists);
+ // Get input device information.
+ InputDevice getInputDevice(int deviceId);
+ int[] getInputDeviceIds();
+
// For testing
void setInTouchMode(boolean showFocus);
diff --git a/core/java/android/view/InputDevice.aidl b/core/java/android/view/InputDevice.aidl
new file mode 100644
index 000000000000..dbc40c131642
--- /dev/null
+++ b/core/java/android/view/InputDevice.aidl
@@ -0,0 +1,20 @@
+/* //device/java/android/android.view.InputDevice.aidl
+**
+** 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.
+*/
+
+package android.view;
+
+parcelable InputDevice;
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index d5b2121ea3dd..fb47b9c7b7f3 100755
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -16,6 +16,12 @@
package android.view;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+
/**
* Describes the capabilities of a particular input device.
* <p>
@@ -32,12 +38,14 @@ package android.view;
* the appropriate interpretation.
* </p>
*/
-public final class InputDevice {
+public final class InputDevice implements Parcelable {
private int mId;
private String mName;
private int mSources;
private int mKeyboardType;
+ private MotionRange[] mMotionRanges;
+
/**
* A mask for input source classes.
*
@@ -246,6 +254,8 @@ public final class InputDevice {
*/
public static final int MOTION_RANGE_ORIENTATION = 8;
+ private static final int MOTION_RANGE_LAST = MOTION_RANGE_ORIENTATION;
+
/**
* There is no keyboard.
*/
@@ -261,6 +271,11 @@ public final class InputDevice {
* The keyboard supports a complement of alphabetic keys.
*/
public static final int KEYBOARD_TYPE_ALPHABETIC = 2;
+
+ // Called by native code.
+ private InputDevice() {
+ mMotionRanges = new MotionRange[MOTION_RANGE_LAST + 1];
+ }
/**
* Gets information about the input device with the specified id.
@@ -268,8 +283,35 @@ public final class InputDevice {
* @return The input device or null if not found.
*/
public static InputDevice getDevice(int id) {
- // TODO
- return null;
+ IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
+ try {
+ return wm.getInputDevice(id);
+ } catch (RemoteException ex) {
+ throw new RuntimeException(
+ "Could not get input device information from Window Manager.", ex);
+ }
+ }
+
+ /**
+ * Gets the ids of all input devices in the system.
+ * @return The input device ids.
+ */
+ public static int[] getDeviceIds() {
+ IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
+ try {
+ return wm.getInputDeviceIds();
+ } catch (RemoteException ex) {
+ throw new RuntimeException(
+ "Could not get input device ids from Window Manager.", ex);
+ }
+ }
+
+ /**
+ * Gets the input device id.
+ * @return The input device id.
+ */
+ public int getId() {
+ return mId;
}
/**
@@ -307,23 +349,23 @@ public final class InputDevice {
/**
* Gets information about the range of values for a particular {@link MotionEvent}
* coordinate.
- * @param range The motion range constant.
+ * @param rangeType The motion range constant.
* @return The range of values, or null if the requested coordinate is not
* supported by the device.
*/
- public MotionRange getMotionRange(int range) {
- // TODO
- return null;
+ public MotionRange getMotionRange(int rangeType) {
+ if (rangeType < 0 || rangeType > MOTION_RANGE_LAST) {
+ throw new IllegalArgumentException("Requested range is out of bounds.");
+ }
+
+ return mMotionRanges[rangeType];
}
- /**
- * Returns true if the device supports a particular button or key.
- * @param keyCode The key code.
- * @return True if the device supports the key.
- */
- public boolean hasKey(int keyCode) {
- // TODO
- return false;
+ private void addMotionRange(int rangeType, float min, float max, float flat, float fuzz) {
+ if (rangeType >= 0 && rangeType <= MOTION_RANGE_LAST) {
+ MotionRange range = new MotionRange(min, max, flat, fuzz);
+ mMotionRanges[rangeType] = range;
+ }
}
/**
@@ -331,13 +373,24 @@ public final class InputDevice {
* coordinate.
*/
public static final class MotionRange {
+ private float mMin;
+ private float mMax;
+ private float mFlat;
+ private float mFuzz;
+
+ private MotionRange(float min, float max, float flat, float fuzz) {
+ mMin = min;
+ mMax = max;
+ mFlat = flat;
+ mFuzz = fuzz;
+ }
+
/**
* Gets the minimum value for the coordinate.
* @return The minimum value.
*/
public float getMin() {
- // TODO
- return 0;
+ return mMin;
}
/**
@@ -345,8 +398,7 @@ public final class InputDevice {
* @return The minimum value.
*/
public float getMax() {
- // TODO
- return 0;
+ return mMax;
}
/**
@@ -354,8 +406,7 @@ public final class InputDevice {
* @return The range of values.
*/
public float getRange() {
- // TODO
- return 0;
+ return mMax - mMin;
}
/**
@@ -365,8 +416,7 @@ public final class InputDevice {
* @return The extent of the center flat position.
*/
public float getFlat() {
- // TODO
- return 0;
+ return mFlat;
}
/**
@@ -376,8 +426,127 @@ public final class InputDevice {
* @return The error tolerance.
*/
public float getFuzz() {
- // TODO
- return 0;
+ return mFuzz;
+ }
+ }
+
+ public static final Parcelable.Creator<InputDevice> CREATOR
+ = new Parcelable.Creator<InputDevice>() {
+ public InputDevice createFromParcel(Parcel in) {
+ InputDevice result = new InputDevice();
+ result.readFromParcel(in);
+ return result;
+ }
+
+ public InputDevice[] newArray(int size) {
+ return new InputDevice[size];
+ }
+ };
+
+ private void readFromParcel(Parcel in) {
+ mId = in.readInt();
+ mName = in.readString();
+ mSources = in.readInt();
+ mKeyboardType = in.readInt();
+
+ for (;;) {
+ int rangeType = in.readInt();
+ if (rangeType < 0) {
+ break;
+ }
+
+ addMotionRange(rangeType,
+ in.readFloat(), in.readFloat(), in.readFloat(), in.readFloat());
+ }
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeInt(mId);
+ out.writeString(mName);
+ out.writeInt(mSources);
+ out.writeInt(mKeyboardType);
+
+ for (int i = 0; i <= MOTION_RANGE_LAST; i++) {
+ MotionRange range = mMotionRanges[i];
+ if (range != null) {
+ out.writeInt(i);
+ out.writeFloat(range.mMin);
+ out.writeFloat(range.mMax);
+ out.writeFloat(range.mFlat);
+ out.writeFloat(range.mFuzz);
+ }
+ }
+ out.writeInt(-1);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder description = new StringBuilder();
+ description.append("Input Device ").append(mId).append(": ").append(mName).append("\n");
+
+ description.append(" Keyboard Type: ");
+ switch (mKeyboardType) {
+ case KEYBOARD_TYPE_NONE:
+ description.append("none");
+ break;
+ case KEYBOARD_TYPE_NON_ALPHABETIC:
+ description.append("non-alphabetic");
+ break;
+ case KEYBOARD_TYPE_ALPHABETIC:
+ description.append("alphabetic");
+ break;
+ }
+ description.append("\n");
+
+ description.append(" Sources:");
+ appendSourceDescriptionIfApplicable(description, SOURCE_KEYBOARD, "keyboard");
+ appendSourceDescriptionIfApplicable(description, SOURCE_DPAD, "dpad");
+ appendSourceDescriptionIfApplicable(description, SOURCE_GAMEPAD, "gamepad");
+ appendSourceDescriptionIfApplicable(description, SOURCE_TOUCHSCREEN, "touchscreen");
+ appendSourceDescriptionIfApplicable(description, SOURCE_MOUSE, "mouse");
+ appendSourceDescriptionIfApplicable(description, SOURCE_TRACKBALL, "trackball");
+ appendSourceDescriptionIfApplicable(description, SOURCE_TOUCHPAD, "touchpad");
+ appendSourceDescriptionIfApplicable(description, SOURCE_JOYSTICK_LEFT, "joystick_left");
+ appendSourceDescriptionIfApplicable(description, SOURCE_JOYSTICK_RIGHT, "joystick_right");
+ description.append("\n");
+
+ appendRangeDescriptionIfApplicable(description, MOTION_RANGE_X, "x");
+ appendRangeDescriptionIfApplicable(description, MOTION_RANGE_Y, "y");
+ appendRangeDescriptionIfApplicable(description, MOTION_RANGE_PRESSURE, "pressure");
+ appendRangeDescriptionIfApplicable(description, MOTION_RANGE_SIZE, "size");
+ appendRangeDescriptionIfApplicable(description, MOTION_RANGE_TOUCH_MAJOR, "touchMajor");
+ appendRangeDescriptionIfApplicable(description, MOTION_RANGE_TOUCH_MINOR, "touchMinor");
+ appendRangeDescriptionIfApplicable(description, MOTION_RANGE_TOOL_MAJOR, "toolMajor");
+ appendRangeDescriptionIfApplicable(description, MOTION_RANGE_TOOL_MINOR, "toolMinor");
+ appendRangeDescriptionIfApplicable(description, MOTION_RANGE_ORIENTATION, "orientation");
+
+ return description.toString();
+ }
+
+ private void appendSourceDescriptionIfApplicable(StringBuilder description, int source,
+ String sourceName) {
+ if ((mSources & source) == source) {
+ description.append(" ");
+ description.append(sourceName);
+ }
+ }
+
+ private void appendRangeDescriptionIfApplicable(StringBuilder description,
+ int rangeType, String rangeName) {
+ MotionRange range = mMotionRanges[rangeType];
+ if (range != null) {
+ description.append(" Range[").append(rangeName);
+ description.append("]: min=").append(range.mMin);
+ description.append(" max=").append(range.mMax);
+ description.append(" flat=").append(range.mFlat);
+ description.append(" fuzz=").append(range.mFuzz);
+ description.append("\n");
}
}
}
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index e20fee5b38d4..ab7542079a90 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -808,7 +808,6 @@ public abstract class AdapterView<T extends Adapter> extends ViewGroup {
mNextSelectedPosition = INVALID_POSITION;
mNextSelectedRowId = INVALID_ROW_ID;
mNeedSync = false;
- checkSelectionChanged();
checkFocus();
requestLayout();
@@ -819,13 +818,21 @@ public abstract class AdapterView<T extends Adapter> extends ViewGroup {
}
}
- private class SelectionNotifier extends Handler implements Runnable {
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ removeCallbacks(mSelectionNotifier);
+ }
+
+ private class SelectionNotifier implements Runnable {
public void run() {
if (mDataChanged) {
// Data has changed between when this SelectionNotifier
// was posted and now. We need to wait until the AdapterView
// has been synched to the new data.
- post(this);
+ if (getAdapter() != null) {
+ post(this);
+ }
} else {
fireOnSelected();
}
@@ -842,7 +849,7 @@ public abstract class AdapterView<T extends Adapter> extends ViewGroup {
if (mSelectionNotifier == null) {
mSelectionNotifier = new SelectionNotifier();
}
- mSelectionNotifier.post(mSelectionNotifier);
+ post(mSelectionNotifier);
} else {
fireOnSelected();
}
diff --git a/core/java/com/android/internal/widget/PointerLocationView.java b/core/java/com/android/internal/widget/PointerLocationView.java
index d5a99798fa18..939f1182f1fa 100644
--- a/core/java/com/android/internal/widget/PointerLocationView.java
+++ b/core/java/com/android/internal/widget/PointerLocationView.java
@@ -19,8 +19,10 @@ package com.android.internal.widget;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
+import android.graphics.RectF;
import android.graphics.Paint.FontMetricsInt;
import android.util.Log;
+import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
@@ -29,17 +31,45 @@ import android.view.ViewConfiguration;
import java.util.ArrayList;
public class PointerLocationView extends View {
+ private static final String TAG = "Pointer";
+
public static class PointerState {
- private final ArrayList<Float> mXs = new ArrayList<Float>();
- private final ArrayList<Float> mYs = new ArrayList<Float>();
+ // Trace of previous points.
+ private float[] mTraceX = new float[32];
+ private float[] mTraceY = new float[32];
+ private int mTraceCount;
+
+ // True if the pointer is down.
private boolean mCurDown;
- private int mCurX;
- private int mCurY;
- private float mCurPressure;
- private float mCurSize;
- private int mCurWidth;
+
+ // Most recent coordinates.
+ private MotionEvent.PointerCoords mCoords = new MotionEvent.PointerCoords();
+
+ // Most recent velocity.
private float mXVelocity;
private float mYVelocity;
+
+ public void clearTrace() {
+ mTraceCount = 0;
+ }
+
+ public void addTrace(float x, float y) {
+ int traceCapacity = mTraceX.length;
+ if (mTraceCount == traceCapacity) {
+ traceCapacity *= 2;
+ float[] newTraceX = new float[traceCapacity];
+ System.arraycopy(mTraceX, 0, newTraceX, 0, mTraceCount);
+ mTraceX = newTraceX;
+
+ float[] newTraceY = new float[traceCapacity];
+ System.arraycopy(mTraceY, 0, newTraceY, 0, mTraceCount);
+ mTraceY = newTraceY;
+ }
+
+ mTraceX[mTraceCount] = x;
+ mTraceY[mTraceCount] = y;
+ mTraceCount += 1;
+ }
}
private final ViewConfiguration mVC;
@@ -54,11 +84,12 @@ public class PointerLocationView extends View {
private boolean mCurDown;
private int mCurNumPointers;
private int mMaxNumPointers;
- private final ArrayList<PointerState> mPointers
- = new ArrayList<PointerState>();
+ private final ArrayList<PointerState> mPointers = new ArrayList<PointerState>();
private final VelocityTracker mVelocity;
+ private final FasterStringBuilder mText = new FasterStringBuilder();
+
private boolean mPrintCoords = true;
public PointerLocationView(Context c) {
@@ -94,6 +125,18 @@ public class PointerLocationView extends View {
mPointers.add(ps);
mVelocity = VelocityTracker.obtain();
+
+ logInputDeviceCapabilities();
+ }
+
+ private void logInputDeviceCapabilities() {
+ int[] deviceIds = InputDevice.getDeviceIds();
+ for (int i = 0; i < deviceIds.length; i++) {
+ InputDevice device = InputDevice.getDevice(deviceIds[i]);
+ if (device != null) {
+ Log.i(TAG, device.toString());
+ }
+ }
}
public void setPrintCoords(boolean state) {
@@ -113,6 +156,21 @@ public class PointerLocationView extends View {
+ " bottom=" + mTextMetrics.bottom);
}
}
+
+ // Draw an oval. When angle is 0 radians, orients the major axis vertically,
+ // angles less than or greater than 0 radians rotate the major axis left or right.
+ private RectF mReusableOvalRect = new RectF();
+ private void drawOval(Canvas canvas, float x, float y, float major, float minor,
+ float angle, Paint paint) {
+ canvas.save(Canvas.MATRIX_SAVE_FLAG);
+ canvas.rotate((float) (angle * 180 / Math.PI), x, y);
+ mReusableOvalRect.left = x - minor / 2;
+ mReusableOvalRect.right = x + minor / 2;
+ mReusableOvalRect.top = y - major / 2;
+ mReusableOvalRect.bottom = y + major / 2;
+ canvas.drawOval(mReusableOvalRect, paint);
+ canvas.restore();
+ }
@Override
protected void onDraw(Canvas canvas) {
@@ -124,76 +182,80 @@ public class PointerLocationView extends View {
final int NP = mPointers.size();
+ // Labels
if (NP > 0) {
final PointerState ps = mPointers.get(0);
canvas.drawRect(0, 0, itemW-1, bottom,mTextBackgroundPaint);
- canvas.drawText("P: " + mCurNumPointers + " / " + mMaxNumPointers,
- 1, base, mTextPaint);
+ canvas.drawText(mText.clear()
+ .append("P: ").append(mCurNumPointers)
+ .append(" / ").append(mMaxNumPointers)
+ .toString(), 1, base, mTextPaint);
- final int N = ps.mXs.size();
+ final int N = ps.mTraceCount;
if ((mCurDown && ps.mCurDown) || N == 0) {
canvas.drawRect(itemW, 0, (itemW * 2) - 1, bottom, mTextBackgroundPaint);
- canvas.drawText("X: " + ps.mCurX, 1 + itemW, base, mTextPaint);
+ canvas.drawText(mText.clear()
+ .append("X: ").append(ps.mCoords.x, 1)
+ .toString(), 1 + itemW, base, mTextPaint);
canvas.drawRect(itemW * 2, 0, (itemW * 3) - 1, bottom, mTextBackgroundPaint);
- canvas.drawText("Y: " + ps.mCurY, 1 + itemW * 2, base, mTextPaint);
+ canvas.drawText(mText.clear()
+ .append("Y: ").append(ps.mCoords.y, 1)
+ .toString(), 1 + itemW * 2, base, mTextPaint);
} else {
- float dx = ps.mXs.get(N-1) - ps.mXs.get(0);
- float dy = ps.mYs.get(N-1) - ps.mYs.get(0);
+ float dx = ps.mTraceX[N - 1] - ps.mTraceX[0];
+ float dy = ps.mTraceY[N - 1] - ps.mTraceY[0];
canvas.drawRect(itemW, 0, (itemW * 2) - 1, bottom,
Math.abs(dx) < mVC.getScaledTouchSlop()
? mTextBackgroundPaint : mTextLevelPaint);
- canvas.drawText("dX: " + String.format("%.1f", dx), 1 + itemW, base, mTextPaint);
+ canvas.drawText(mText.clear()
+ .append("dX: ").append(dx, 1)
+ .toString(), 1 + itemW, base, mTextPaint);
canvas.drawRect(itemW * 2, 0, (itemW * 3) - 1, bottom,
Math.abs(dy) < mVC.getScaledTouchSlop()
? mTextBackgroundPaint : mTextLevelPaint);
- canvas.drawText("dY: " + String.format("%.1f", dy), 1 + itemW * 2, base, mTextPaint);
+ canvas.drawText(mText.clear()
+ .append("dY: ").append(dy, 1)
+ .toString(), 1 + itemW * 2, base, mTextPaint);
}
canvas.drawRect(itemW * 3, 0, (itemW * 4) - 1, bottom, mTextBackgroundPaint);
- int velocity = (int) (ps.mXVelocity * 1000);
- canvas.drawText("Xv: " + velocity, 1 + itemW * 3, base, mTextPaint);
+ canvas.drawText(mText.clear()
+ .append("Xv: ").append(ps.mXVelocity, 3)
+ .toString(), 1 + itemW * 3, base, mTextPaint);
canvas.drawRect(itemW * 4, 0, (itemW * 5) - 1, bottom, mTextBackgroundPaint);
- velocity = (int) (ps.mYVelocity * 1000);
- canvas.drawText("Yv: " + velocity, 1 + itemW * 4, base, mTextPaint);
+ canvas.drawText(mText.clear()
+ .append("Yv: ").append(ps.mYVelocity, 3)
+ .toString(), 1 + itemW * 4, base, mTextPaint);
canvas.drawRect(itemW * 5, 0, (itemW * 6) - 1, bottom, mTextBackgroundPaint);
- canvas.drawRect(itemW * 5, 0, (itemW * 5) + (ps.mCurPressure * itemW) - 1,
+ canvas.drawRect(itemW * 5, 0, (itemW * 5) + (ps.mCoords.pressure * itemW) - 1,
bottom, mTextLevelPaint);
- canvas.drawText("Prs: " + String.format("%.2f", ps.mCurPressure), 1 + itemW * 5,
- base, mTextPaint);
+ canvas.drawText(mText.clear()
+ .append("Prs: ").append(ps.mCoords.pressure, 2)
+ .toString(), 1 + itemW * 5, base, mTextPaint);
canvas.drawRect(itemW * 6, 0, w, bottom, mTextBackgroundPaint);
- canvas.drawRect(itemW * 6, 0, (itemW * 6) + (ps.mCurSize * itemW) - 1,
+ canvas.drawRect(itemW * 6, 0, (itemW * 6) + (ps.mCoords.size * itemW) - 1,
bottom, mTextLevelPaint);
- canvas.drawText("Size: " + String.format("%.2f", ps.mCurSize), 1 + itemW * 6,
- base, mTextPaint);
+ canvas.drawText(mText.clear()
+ .append("Size: ").append(ps.mCoords.size, 2)
+ .toString(), 1 + itemW * 6, base, mTextPaint);
}
- for (int p=0; p<NP; p++) {
+ // Pointer trace.
+ for (int p = 0; p < NP; p++) {
final PointerState ps = mPointers.get(p);
- if (mCurDown && ps.mCurDown) {
- canvas.drawLine(0, (int)ps.mCurY, getWidth(), (int)ps.mCurY, mTargetPaint);
- canvas.drawLine((int)ps.mCurX, 0, (int)ps.mCurX, getHeight(), mTargetPaint);
- int pressureLevel = (int)(ps.mCurPressure*255);
- mPaint.setARGB(255, pressureLevel, 128, 255-pressureLevel);
- canvas.drawPoint(ps.mCurX, ps.mCurY, mPaint);
- canvas.drawCircle(ps.mCurX, ps.mCurY, ps.mCurWidth, mPaint);
- }
- }
-
- for (int p=0; p<NP; p++) {
- final PointerState ps = mPointers.get(p);
-
- final int N = ps.mXs.size();
- float lastX=0, lastY=0;
+ // Draw path.
+ final int N = ps.mTraceCount;
+ float lastX = 0, lastY = 0;
boolean haveLast = false;
boolean drawn = false;
mPaint.setARGB(255, 128, 255, 255);
- for (int i=0; i<N; i++) {
- float x = ps.mXs.get(i);
- float y = ps.mYs.get(i);
+ for (int i=0; i < N; i++) {
+ float x = ps.mTraceX[i];
+ float y = ps.mTraceY[i];
if (Float.isNaN(x)) {
haveLast = false;
continue;
@@ -208,21 +270,57 @@ public class PointerLocationView extends View {
haveLast = true;
}
+ // Draw velocity vector.
if (drawn) {
mPaint.setARGB(255, 255, 64, 128);
- float xVel = ps.mXVelocity * (1000/60);
- float yVel = ps.mYVelocity * (1000/60);
- canvas.drawLine(lastX, lastY, lastX+xVel, lastY+yVel, mPaint);
+ float xVel = ps.mXVelocity * (1000 / 60);
+ float yVel = ps.mYVelocity * (1000 / 60);
+ canvas.drawLine(lastX, lastY, lastX + xVel, lastY + yVel, mPaint);
+ }
+
+ if (mCurDown && ps.mCurDown) {
+ // Draw crosshairs.
+ canvas.drawLine(0, ps.mCoords.y, getWidth(), ps.mCoords.y, mTargetPaint);
+ canvas.drawLine(ps.mCoords.x, 0, ps.mCoords.x, getHeight(), mTargetPaint);
+
+ // Draw current point.
+ int pressureLevel = (int)(ps.mCoords.pressure * 255);
+ mPaint.setARGB(255, pressureLevel, 255, 255 - pressureLevel);
+ canvas.drawPoint(ps.mCoords.x, ps.mCoords.y, mPaint);
+
+ // Draw current touch ellipse.
+ mPaint.setARGB(255, pressureLevel, 255 - pressureLevel, 128);
+ drawOval(canvas, ps.mCoords.x, ps.mCoords.y, ps.mCoords.touchMajor,
+ ps.mCoords.touchMinor, ps.mCoords.orientation, mPaint);
+
+ // Draw current tool ellipse.
+ mPaint.setARGB(255, pressureLevel, 128, 255 - pressureLevel);
+ drawOval(canvas, ps.mCoords.x, ps.mCoords.y, ps.mCoords.toolMajor,
+ ps.mCoords.toolMinor, ps.mCoords.orientation, mPaint);
}
}
}
}
+
+ private void logPointerCoords(MotionEvent.PointerCoords coords, int id) {
+ Log.i(TAG, mText.clear()
+ .append("Pointer ").append(id + 1)
+ .append(": (").append(coords.x, 3).append(", ").append(coords.y, 3)
+ .append(") Pressure=").append(coords.pressure, 3)
+ .append(" Size=").append(coords.size, 3)
+ .append(" TouchMajor=").append(coords.touchMajor, 3)
+ .append(" TouchMinor=").append(coords.touchMinor, 3)
+ .append(" ToolMajor=").append(coords.toolMajor, 3)
+ .append(" ToolMinor=").append(coords.toolMinor, 3)
+ .append(" Orientation=").append((float)(coords.orientation * 180 / Math.PI), 1)
+ .append("deg").toString());
+ }
public void addTouchEvent(MotionEvent event) {
synchronized (mPointers) {
int action = event.getAction();
- //Log.i("Pointer", "Motion: action=0x" + Integer.toHexString(action)
+ //Log.i(TAG, "Motion: action=0x" + Integer.toHexString(action)
// + " pointers=" + event.getPointerCount());
int NP = mPointers.size();
@@ -235,35 +333,33 @@ public class PointerLocationView extends View {
//} else {
// mRect.setEmpty();
//}
- if (action == MotionEvent.ACTION_DOWN) {
- mVelocity.clear();
-
- for (int p=0; p<NP; p++) {
- final PointerState ps = mPointers.get(p);
- ps.mXs.clear();
- ps.mYs.clear();
- ps.mCurDown = false;
- }
- mPointers.get(0).mCurDown = true;
- mMaxNumPointers = 0;
- if (mPrintCoords) {
- Log.i("Pointer", "Pointer 1: DOWN");
+ if (action == MotionEvent.ACTION_DOWN
+ || (action & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN) {
+ final int index = (action & MotionEvent.ACTION_POINTER_INDEX_MASK)
+ >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; // will be 0 for down
+ if (action == MotionEvent.ACTION_DOWN) {
+ for (int p=0; p<NP; p++) {
+ final PointerState ps = mPointers.get(p);
+ ps.clearTrace();
+ ps.mCurDown = false;
+ }
+ mCurDown = true;
+ mMaxNumPointers = 0;
+ mVelocity.clear();
}
- }
-
- if ((action&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN) {
- final int index = (action&MotionEvent.ACTION_POINTER_INDEX_MASK)
- >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+
final int id = event.getPointerId(index);
while (NP <= id) {
PointerState ps = new PointerState();
mPointers.add(ps);
NP++;
}
+
final PointerState ps = mPointers.get(id);
ps.mCurDown = true;
if (mPrintCoords) {
- Log.i("Pointer", "Pointer " + (id+1) + ": DOWN");
+ Log.i(TAG, mText.clear().append("Pointer ")
+ .append(id + 1).append(": DOWN").toString());
}
}
@@ -284,58 +380,38 @@ public class PointerLocationView extends View {
final PointerState ps = mPointers.get(id);
final int N = event.getHistorySize();
for (int j=0; j<N; j++) {
+ event.getHistoricalPointerCoords(i, j, ps.mCoords);
if (mPrintCoords) {
- Log.i("Pointer", "Pointer " + (id+1) + ": ("
- + event.getHistoricalX(i, j)
- + ", " + event.getHistoricalY(i, j) + ")"
- + " Prs=" + event.getHistoricalPressure(i, j)
- + " Size=" + event.getHistoricalSize(i, j));
+ logPointerCoords(ps.mCoords, id);
}
- ps.mXs.add(event.getHistoricalX(i, j));
- ps.mYs.add(event.getHistoricalY(i, j));
+ ps.addTrace(event.getHistoricalX(i, j), event.getHistoricalY(i, j));
}
+ event.getPointerCoords(i, ps.mCoords);
if (mPrintCoords) {
- Log.i("Pointer", "Pointer " + (id+1) + ": ("
- + event.getX(i) + ", " + event.getY(i) + ")"
- + " Prs=" + event.getPressure(i)
- + " Size=" + event.getSize(i));
+ logPointerCoords(ps.mCoords, id);
}
- ps.mXs.add(event.getX(i));
- ps.mYs.add(event.getY(i));
- ps.mCurX = (int)event.getX(i);
- ps.mCurY = (int)event.getY(i);
- //Log.i("Pointer", "Pointer #" + p + ": (" + ps.mCurX
- // + "," + ps.mCurY + ")");
- ps.mCurPressure = event.getPressure(i);
- ps.mCurSize = event.getSize(i);
- ps.mCurWidth = (int)(ps.mCurSize*(getWidth()/3));
+ ps.addTrace(ps.mCoords.x, ps.mCoords.y);
ps.mXVelocity = mVelocity.getXVelocity(id);
ps.mYVelocity = mVelocity.getYVelocity(id);
}
- if ((action&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP) {
- final int index = (action&MotionEvent.ACTION_POINTER_INDEX_MASK)
- >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+ if (action == MotionEvent.ACTION_UP
+ || (action & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP) {
+ final int index = (action & MotionEvent.ACTION_POINTER_INDEX_MASK)
+ >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; // will be 0 for UP
+
final int id = event.getPointerId(index);
final PointerState ps = mPointers.get(id);
- ps.mXs.add(Float.NaN);
- ps.mYs.add(Float.NaN);
ps.mCurDown = false;
if (mPrintCoords) {
- Log.i("Pointer", "Pointer " + (id+1) + ": UP");
+ Log.i(TAG, mText.clear().append("Pointer ")
+ .append(id + 1).append(": UP").toString());
}
- }
-
- if (action == MotionEvent.ACTION_UP) {
- for (int i=0; i<NI; i++) {
- final int id = event.getPointerId(i);
- final PointerState ps = mPointers.get(id);
- if (ps.mCurDown) {
- ps.mCurDown = false;
- if (mPrintCoords) {
- Log.i("Pointer", "Pointer " + (id+1) + ": UP");
- }
- }
+
+ if (action == MotionEvent.ACTION_UP) {
+ mCurDown = false;
+ } else {
+ ps.addTrace(Float.NaN, Float.NaN);
}
}
@@ -356,8 +432,120 @@ public class PointerLocationView extends View {
@Override
public boolean onTrackballEvent(MotionEvent event) {
- Log.i("Pointer", "Trackball: " + event);
+ Log.i(TAG, "Trackball: " + event);
return super.onTrackballEvent(event);
}
+ // HACK
+ // A quick and dirty string builder implementation optimized for GC.
+ // Using the basic StringBuilder implementation causes the application grind to a halt when
+ // more than a couple of pointers are down due to the number of temporary objects allocated
+ // while formatting strings for drawing or logging.
+ private static final class FasterStringBuilder {
+ private char[] mChars;
+ private int mLength;
+
+ public FasterStringBuilder() {
+ mChars = new char[64];
+ }
+
+ public FasterStringBuilder clear() {
+ mLength = 0;
+ return this;
+ }
+
+ public FasterStringBuilder append(String value) {
+ final int valueLength = value.length();
+ final int index = reserve(valueLength);
+ value.getChars(0, valueLength, mChars, index);
+ mLength += valueLength;
+ return this;
+ }
+
+ public FasterStringBuilder append(int value) {
+ return append(value, 0);
+ }
+
+ public FasterStringBuilder append(int value, int zeroPadWidth) {
+ final boolean negative = value < 0;
+ if (negative) {
+ value = - value;
+ if (value < 0) {
+ append("-2147483648");
+ return this;
+ }
+ }
+
+ int index = reserve(11);
+ final char[] chars = mChars;
+
+ if (value == 0) {
+ chars[index++] = '0';
+ mLength += 1;
+ return this;
+ }
+
+ if (negative) {
+ chars[index++] = '-';
+ }
+
+ int divisor = 1000000000;
+ int numberWidth = 10;
+ while (value < divisor) {
+ divisor /= 10;
+ numberWidth -= 1;
+ if (numberWidth < zeroPadWidth) {
+ chars[index++] = '0';
+ }
+ }
+
+ do {
+ int digit = value / divisor;
+ value -= digit * divisor;
+ divisor /= 10;
+ chars[index++] = (char) (digit + '0');
+ } while (divisor != 0);
+
+ mLength = index;
+ return this;
+ }
+
+ public FasterStringBuilder append(float value, int precision) {
+ int scale = 1;
+ for (int i = 0; i < precision; i++) {
+ scale *= 10;
+ }
+ value = (float) (Math.rint(value * scale) / scale);
+
+ append((int) value);
+
+ if (precision != 0) {
+ append(".");
+ value = Math.abs(value);
+ value -= Math.floor(value);
+ append((int) (value * scale), precision);
+ }
+
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return new String(mChars, 0, mLength);
+ }
+
+ private int reserve(int length) {
+ final int oldLength = mLength;
+ final int newLength = mLength + length;
+ final char[] oldChars = mChars;
+ final int oldCapacity = oldChars.length;
+ if (newLength > oldCapacity) {
+ final int newCapacity = oldCapacity * 2;
+ final char[] newChars = new char[newCapacity];
+ System.arraycopy(oldChars, 0, newChars, 0, oldLength);
+ mChars = newChars;
+ }
+ return oldLength;
+ }
+ }
}
diff --git a/include/ui/EventHub.h b/include/ui/EventHub.h
index 3d428563359f..25d5afbf905e 100644
--- a/include/ui/EventHub.h
+++ b/include/ui/EventHub.h
@@ -82,6 +82,14 @@ struct RawAbsoluteAxisInfo {
int32_t fuzz; // error tolerance, eg. fuzz == 4 means value is +/- 4 due to noise
inline int32_t getRange() { return maxValue - minValue; }
+
+ inline void clear() {
+ valid = false;
+ minValue = 0;
+ maxValue = 0;
+ flat = 0;
+ fuzz = 0;
+ }
};
/*
diff --git a/include/ui/Input.h b/include/ui/Input.h
index 2385973e6926..49347d3f8916 100644
--- a/include/ui/Input.h
+++ b/include/ui/Input.h
@@ -453,6 +453,10 @@ public:
inline void setKeyboardType(int32_t keyboardType) { mKeyboardType = keyboardType; }
inline int32_t getKeyboardType() const { return mKeyboardType; }
+ inline const KeyedVector<int32_t, MotionRange> getMotionRanges() const {
+ return mMotionRanges;
+ }
+
private:
int32_t mId;
String8 mName;
diff --git a/include/ui/InputReader.h b/include/ui/InputReader.h
index 56d27651528a..7a089a45a1af 100644
--- a/include/ui/InputReader.h
+++ b/include/ui/InputReader.h
@@ -35,6 +35,34 @@ namespace android {
class InputDevice;
class InputMapper;
+/* Describes a virtual key. */
+struct VirtualKeyDefinition {
+ int32_t scanCode;
+
+ // configured position data, specified in display coords
+ int32_t centerX;
+ int32_t centerY;
+ int32_t width;
+ int32_t height;
+};
+
+
+/* Specifies input device calibration settings. */
+class InputDeviceCalibration {
+public:
+ InputDeviceCalibration();
+
+ void clear();
+ void addProperty(const String8& key, const String8& value);
+
+ bool tryGetProperty(const String8& key, String8& outValue) const;
+ bool tryGetProperty(const String8& key, int32_t& outValue) const;
+ bool tryGetProperty(const String8& key, float& outValue) const;
+
+private:
+ KeyedVector<String8, String8> mProperties;
+};
+
/*
* Input reader policy interface.
@@ -73,17 +101,6 @@ public:
ACTION_APP_SWITCH_COMING = 0x00000002,
};
- /* Describes a virtual key. */
- struct VirtualKeyDefinition {
- int32_t scanCode;
-
- // configured position data, specified in display coords
- int32_t centerX;
- int32_t centerY;
- int32_t width;
- int32_t height;
- };
-
/* Gets information about the display with the specified id.
* Returns true if the display info is available, false otherwise.
*/
@@ -135,6 +152,10 @@ public:
virtual void getVirtualKeyDefinitions(const String8& deviceName,
Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions) = 0;
+ /* Gets the calibration for an input device. */
+ virtual void getInputDeviceCalibration(const String8& deviceName,
+ InputDeviceCalibration& outCalibration) = 0;
+
/* Gets the excluded device names for the platform. */
virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) = 0;
};
@@ -327,6 +348,10 @@ public:
int32_t getMetaState();
+ inline const InputDeviceCalibration& getCalibration() {
+ return mCalibration;
+ }
+
private:
InputReaderContext* mContext;
int32_t mId;
@@ -338,6 +363,8 @@ private:
typedef int32_t (InputMapper::*GetStateFunc)(uint32_t sourceMask, int32_t code);
int32_t getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc);
+
+ InputDeviceCalibration mCalibration;
};
@@ -538,12 +565,12 @@ protected:
}
};
+ // Raw data for a single pointer.
struct PointerData {
uint32_t id;
int32_t x;
int32_t y;
int32_t pressure;
- int32_t size;
int32_t touchMajor;
int32_t touchMinor;
int32_t toolMajor;
@@ -551,6 +578,7 @@ protected:
int32_t orientation;
};
+ // Raw data for a collection of pointers including a pointer id mapping table.
struct TouchData {
uint32_t pointerCount;
PointerData pointers[MAX_POINTERS];
@@ -584,18 +612,82 @@ protected:
bool useAveragingTouchFilter;
} mParameters;
- // Raw axis information.
- struct Axes {
+ // Immutable calibration parameters in parsed form.
+ struct Calibration {
+ // Touch Area
+ enum TouchAreaCalibration {
+ TOUCH_AREA_CALIBRATION_DEFAULT,
+ TOUCH_AREA_CALIBRATION_NONE,
+ TOUCH_AREA_CALIBRATION_GEOMETRIC,
+ TOUCH_AREA_CALIBRATION_PRESSURE,
+ };
+
+ TouchAreaCalibration touchAreaCalibration;
+
+ // Tool Area
+ enum ToolAreaCalibration {
+ TOOL_AREA_CALIBRATION_DEFAULT,
+ TOOL_AREA_CALIBRATION_NONE,
+ TOOL_AREA_CALIBRATION_GEOMETRIC,
+ TOOL_AREA_CALIBRATION_LINEAR,
+ };
+
+ ToolAreaCalibration toolAreaCalibration;
+ bool haveToolAreaLinearScale;
+ float toolAreaLinearScale;
+ bool haveToolAreaLinearBias;
+ float toolAreaLinearBias;
+ bool haveToolAreaIsSummed;
+ int32_t toolAreaIsSummed;
+
+ // Pressure
+ enum PressureCalibration {
+ PRESSURE_CALIBRATION_DEFAULT,
+ PRESSURE_CALIBRATION_NONE,
+ PRESSURE_CALIBRATION_PHYSICAL,
+ PRESSURE_CALIBRATION_AMPLITUDE,
+ };
+ enum PressureSource {
+ PRESSURE_SOURCE_DEFAULT,
+ PRESSURE_SOURCE_PRESSURE,
+ PRESSURE_SOURCE_TOUCH,
+ };
+
+ PressureCalibration pressureCalibration;
+ PressureSource pressureSource;
+ bool havePressureScale;
+ float pressureScale;
+
+ // Size
+ enum SizeCalibration {
+ SIZE_CALIBRATION_DEFAULT,
+ SIZE_CALIBRATION_NONE,
+ SIZE_CALIBRATION_NORMALIZED,
+ };
+
+ SizeCalibration sizeCalibration;
+
+ // Orientation
+ enum OrientationCalibration {
+ ORIENTATION_CALIBRATION_DEFAULT,
+ ORIENTATION_CALIBRATION_NONE,
+ ORIENTATION_CALIBRATION_INTERPOLATED,
+ };
+
+ OrientationCalibration orientationCalibration;
+ } mCalibration;
+
+ // Raw axis information from the driver.
+ struct RawAxes {
RawAbsoluteAxisInfo x;
RawAbsoluteAxisInfo y;
RawAbsoluteAxisInfo pressure;
- RawAbsoluteAxisInfo size;
RawAbsoluteAxisInfo touchMajor;
RawAbsoluteAxisInfo touchMinor;
RawAbsoluteAxisInfo toolMajor;
RawAbsoluteAxisInfo toolMinor;
RawAbsoluteAxisInfo orientation;
- } mAxes;
+ } mRawAxes;
// Current and previous touch sample data.
TouchData mCurrentTouch;
@@ -620,10 +712,13 @@ protected:
float yScale;
float yPrecision;
- int32_t pressureOrigin;
+ float geometricScale;
+
+ float toolAreaLinearScale;
+ float toolAreaLinearBias;
+
float pressureScale;
- int32_t sizeOrigin;
float sizeScale;
float orientationScale;
@@ -632,12 +727,22 @@ protected:
struct OrientedRanges {
InputDeviceInfo::MotionRange x;
InputDeviceInfo::MotionRange y;
+
+ bool havePressure;
InputDeviceInfo::MotionRange pressure;
+
+ bool haveSize;
InputDeviceInfo::MotionRange size;
+
+ bool haveTouchArea;
InputDeviceInfo::MotionRange touchMajor;
InputDeviceInfo::MotionRange touchMinor;
+
+ bool haveToolArea;
InputDeviceInfo::MotionRange toolMajor;
InputDeviceInfo::MotionRange toolMinor;
+
+ bool haveOrientation;
InputDeviceInfo::MotionRange orientation;
} orientedRanges;
@@ -653,9 +758,14 @@ protected:
} currentVirtualKey;
} mLocked;
- virtual void configureAxes();
+ virtual void configureParameters();
+ virtual void configureRawAxes();
+ virtual void logRawAxes();
virtual bool configureSurfaceLocked();
virtual void configureVirtualKeysLocked();
+ virtual void parseCalibration();
+ virtual void resolveCalibration();
+ virtual void logCalibration();
enum TouchResult {
// Dispatch the touch normally.
@@ -713,7 +823,8 @@ private:
TouchResult consumeOffScreenTouches(nsecs_t when, uint32_t policyFlags);
void dispatchTouches(nsecs_t when, uint32_t policyFlags);
void dispatchTouch(nsecs_t when, uint32_t policyFlags, TouchData* touch,
- BitSet32 idBits, uint32_t changedId, int32_t motionEventAction);
+ BitSet32 idBits, uint32_t changedId, uint32_t pointerCount,
+ int32_t motionEventAction);
void applyPolicyAndDispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
int32_t keyEventAction, int32_t keyEventFlags,
@@ -738,7 +849,7 @@ public:
virtual void process(const RawEvent* rawEvent);
protected:
- virtual void configureAxes();
+ virtual void configureRawAxes();
private:
struct Accumulator {
@@ -767,7 +878,7 @@ private:
int32_t mX;
int32_t mY;
int32_t mPressure;
- int32_t mSize;
+ int32_t mToolWidth;
void initialize();
@@ -784,7 +895,7 @@ public:
virtual void process(const RawEvent* rawEvent);
protected:
- virtual void configureAxes();
+ virtual void configureRawAxes();
private:
struct Accumulator {
diff --git a/libs/ui/EventHub.cpp b/libs/ui/EventHub.cpp
index 891661d690ac..1d38b4ba8ff0 100644
--- a/libs/ui/EventHub.cpp
+++ b/libs/ui/EventHub.cpp
@@ -139,11 +139,7 @@ uint32_t EventHub::getDeviceClasses(int32_t deviceId) const
status_t EventHub::getAbsoluteAxisInfo(int32_t deviceId, int axis,
RawAbsoluteAxisInfo* outAxisInfo) const {
- outAxisInfo->valid = false;
- outAxisInfo->minValue = 0;
- outAxisInfo->maxValue = 0;
- outAxisInfo->flat = 0;
- outAxisInfo->fuzz = 0;
+ outAxisInfo->clear();
AutoMutex _l(mLock);
device_t* device = getDevice(deviceId);
@@ -709,8 +705,7 @@ int EventHub::open_device(const char *deviceName)
LOGV("Getting absolute controllers...");
if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask) >= 0) {
// Is this a new modern multi-touch driver?
- if (test_bit(ABS_MT_TOUCH_MAJOR, abs_bitmask)
- && test_bit(ABS_MT_POSITION_X, abs_bitmask)
+ if (test_bit(ABS_MT_POSITION_X, abs_bitmask)
&& test_bit(ABS_MT_POSITION_Y, abs_bitmask)) {
device->classes |= INPUT_DEVICE_CLASS_TOUCHSCREEN | INPUT_DEVICE_CLASS_TOUCHSCREEN_MT;
diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp
index e35050cb6e4c..886c7856debb 100644
--- a/libs/ui/InputDispatcher.cpp
+++ b/libs/ui/InputDispatcher.cpp
@@ -405,12 +405,15 @@ void InputDispatcher::processMotionLockedInterruptible(
sampleCount += 1;
}
for (uint32_t i = 0; i < entry->pointerCount; i++) {
- LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f",
+ LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
+ "touchMajor=%f, touchMinor=%d, toolMajor=%f, toolMinor=%f, "
+ "orientation=%f",
i, entry->pointerIds[i],
- sample->pointerCoords[i].x,
- sample->pointerCoords[i].y,
- sample->pointerCoords[i].pressure,
- sample->pointerCoords[i].size);
+ sample->pointerCoords[i].x, sample->pointerCoords[i].y,
+ sample->pointerCoords[i].pressure, sample->pointerCoords[i].size,
+ sample->pointerCoords[i].touchMajor, sample->pointerCoords[i].touchMinor,
+ sample->pointerCoords[i].toolMajor, sample->pointerCoords[i].toolMinor,
+ sample->pointerCoords[i].orientation);
}
// Keep in mind that due to batching, it is possible for the number of samples actually
@@ -1080,9 +1083,14 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t
eventTime, deviceId, source, policyFlags, action, metaState, edgeFlags,
xPrecision, yPrecision, downTime);
for (uint32_t i = 0; i < pointerCount; i++) {
- LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f",
+ LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
+ "touchMajor=%f, touchMinor=%d, toolMajor=%f, toolMinor=%f, "
+ "orientation=%f",
i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
- pointerCoords[i].pressure, pointerCoords[i].size);
+ pointerCoords[i].pressure, pointerCoords[i].size,
+ pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
+ pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
+ pointerCoords[i].orientation);
}
#endif
diff --git a/libs/ui/InputReader.cpp b/libs/ui/InputReader.cpp
index 6f042ec7e8e4..8ffb48debe8f 100644
--- a/libs/ui/InputReader.cpp
+++ b/libs/ui/InputReader.cpp
@@ -26,11 +26,14 @@
#include <ui/InputReader.h>
#include <stddef.h>
+#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>
#include <math.h>
+#define INDENT " "
+
namespace android {
// --- Static Functions ---
@@ -52,6 +55,14 @@ inline static void swap(T& a, T& b) {
b = temp;
}
+inline static float avg(float x, float y) {
+ return (x + y) / 2;
+}
+
+inline static float pythag(float x, float y) {
+ return sqrtf(x * x + y * y);
+}
+
int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState) {
int32_t mask;
@@ -116,6 +127,64 @@ static inline bool sourcesMatchMask(uint32_t sources, uint32_t sourceMask) {
}
+// --- InputDeviceCalibration ---
+
+InputDeviceCalibration::InputDeviceCalibration() {
+}
+
+void InputDeviceCalibration::clear() {
+ mProperties.clear();
+}
+
+void InputDeviceCalibration::addProperty(const String8& key, const String8& value) {
+ mProperties.add(key, value);
+}
+
+bool InputDeviceCalibration::tryGetProperty(const String8& key, String8& outValue) const {
+ ssize_t index = mProperties.indexOfKey(key);
+ if (index < 0) {
+ return false;
+ }
+
+ outValue = mProperties.valueAt(index);
+ return true;
+}
+
+bool InputDeviceCalibration::tryGetProperty(const String8& key, int32_t& outValue) const {
+ String8 stringValue;
+ if (! tryGetProperty(key, stringValue) || stringValue.length() == 0) {
+ return false;
+ }
+
+ char* end;
+ int value = strtol(stringValue.string(), & end, 10);
+ if (*end != '\0') {
+ LOGW("Input device calibration key '%s' has invalid value '%s'. Expected an integer.",
+ key.string(), stringValue.string());
+ return false;
+ }
+ outValue = value;
+ return true;
+}
+
+bool InputDeviceCalibration::tryGetProperty(const String8& key, float& outValue) const {
+ String8 stringValue;
+ if (! tryGetProperty(key, stringValue) || stringValue.length() == 0) {
+ return false;
+ }
+
+ char* end;
+ float value = strtof(stringValue.string(), & end);
+ if (*end != '\0') {
+ LOGW("Input device calibration key '%s' has invalid value '%s'. Expected a float.",
+ key.string(), stringValue.string());
+ return false;
+ }
+ outValue = value;
+ return true;
+}
+
+
// --- InputReader ---
InputReader::InputReader(const sp<EventHubInterface>& eventHub,
@@ -167,9 +236,18 @@ void InputReader::addDevice(nsecs_t when, int32_t deviceId) {
String8 name = mEventHub->getDeviceName(deviceId);
uint32_t classes = mEventHub->getDeviceClasses(deviceId);
+ // Write a log message about the added device as a heading for subsequent log messages.
+ LOGI("Device added: id=0x%x, name=%s", deviceId, name.string());
+
InputDevice* device = createDevice(deviceId, name, classes);
device->configure();
+ if (device->isIgnored()) {
+ LOGI(INDENT "Sources: none (device is ignored)");
+ } else {
+ LOGI(INDENT "Sources: 0x%08x", device->getSources());
+ }
+
bool added = false;
{ // acquire device registry writer lock
RWLock::AutoWLock _wl(mDeviceRegistryLock);
@@ -187,14 +265,6 @@ void InputReader::addDevice(nsecs_t when, int32_t deviceId) {
return;
}
- if (device->isIgnored()) {
- LOGI("Device added: id=0x%x, name=%s (ignored non-input device)",
- deviceId, name.string());
- } else {
- LOGI("Device added: id=0x%x, name=%s, sources=%08x",
- deviceId, name.string(), device->getSources());
- }
-
handleConfigurationChanged(when);
}
@@ -217,8 +287,7 @@ void InputReader::removeDevice(nsecs_t when, int32_t deviceId) {
return;
}
- device->reset();
-
+ // Write a log message about the removed device as a heading for subsequent log messages.
if (device->isIgnored()) {
LOGI("Device removed: id=0x%x, name=%s (ignored non-input device)",
device->getId(), device->getName().string());
@@ -227,6 +296,8 @@ void InputReader::removeDevice(nsecs_t when, int32_t deviceId) {
device->getId(), device->getName().string(), device->getSources());
}
+ device->reset();
+
delete device;
handleConfigurationChanged(when);
@@ -537,6 +608,10 @@ void InputDevice::addMapper(InputMapper* mapper) {
}
void InputDevice::configure() {
+ if (! isIgnored()) {
+ mContext->getPolicy()->getInputDeviceCalibration(mName, mCalibration);
+ }
+
mSources = 0;
size_t numMappers = mMappers.size();
@@ -1121,13 +1196,35 @@ void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
info->addMotionRange(AINPUT_MOTION_RANGE_X, mLocked.orientedRanges.x);
info->addMotionRange(AINPUT_MOTION_RANGE_Y, mLocked.orientedRanges.y);
- info->addMotionRange(AINPUT_MOTION_RANGE_PRESSURE, mLocked.orientedRanges.pressure);
- info->addMotionRange(AINPUT_MOTION_RANGE_SIZE, mLocked.orientedRanges.size);
- info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MAJOR, mLocked.orientedRanges.touchMajor);
- info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MINOR, mLocked.orientedRanges.touchMinor);
- info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MAJOR, mLocked.orientedRanges.toolMajor);
- info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MINOR, mLocked.orientedRanges.toolMinor);
- info->addMotionRange(AINPUT_MOTION_RANGE_ORIENTATION, mLocked.orientedRanges.orientation);
+
+ if (mLocked.orientedRanges.havePressure) {
+ info->addMotionRange(AINPUT_MOTION_RANGE_PRESSURE,
+ mLocked.orientedRanges.pressure);
+ }
+
+ if (mLocked.orientedRanges.haveSize) {
+ info->addMotionRange(AINPUT_MOTION_RANGE_SIZE,
+ mLocked.orientedRanges.size);
+ }
+
+ if (mLocked.orientedRanges.haveTouchArea) {
+ info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MAJOR,
+ mLocked.orientedRanges.touchMajor);
+ info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MINOR,
+ mLocked.orientedRanges.touchMinor);
+ }
+
+ if (mLocked.orientedRanges.haveToolArea) {
+ info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MAJOR,
+ mLocked.orientedRanges.toolMajor);
+ info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MINOR,
+ mLocked.orientedRanges.toolMinor);
+ }
+
+ if (mLocked.orientedRanges.haveOrientation) {
+ info->addMotionRange(AINPUT_MOTION_RANGE_ORIENTATION,
+ mLocked.orientedRanges.orientation);
+ }
} // release lock
}
@@ -1144,77 +1241,72 @@ void TouchInputMapper::initializeLocked() {
mJumpyTouchFilter.jumpyPointsDropped = 0;
mLocked.currentVirtualKey.down = false;
+
+ mLocked.orientedRanges.havePressure = false;
+ mLocked.orientedRanges.haveSize = false;
+ mLocked.orientedRanges.haveTouchArea = false;
+ mLocked.orientedRanges.haveToolArea = false;
+ mLocked.orientedRanges.haveOrientation = false;
+}
+
+static void logAxisInfo(RawAbsoluteAxisInfo axis, const char* name) {
+ if (axis.valid) {
+ LOGI(INDENT "Raw %s axis: min=%d, max=%d, flat=%d, fuzz=%d",
+ name, axis.minValue, axis.maxValue, axis.flat, axis.fuzz);
+ } else {
+ LOGI(INDENT "Raw %s axis: unknown range", name);
+ }
}
void TouchInputMapper::configure() {
InputMapper::configure();
// Configure basic parameters.
- mParameters.useBadTouchFilter = getPolicy()->filterTouchEvents();
- mParameters.useAveragingTouchFilter = getPolicy()->filterTouchEvents();
- mParameters.useJumpyTouchFilter = getPolicy()->filterJumpyTouchEvents();
+ configureParameters();
// Configure absolute axis information.
- configureAxes();
+ configureRawAxes();
+ logRawAxes();
+
+ // Prepare input device calibration.
+ parseCalibration();
+ resolveCalibration();
+ logCalibration();
{ // acquire lock
AutoMutex _l(mLock);
- // Configure pressure factors.
- if (mAxes.pressure.valid) {
- mLocked.pressureOrigin = mAxes.pressure.minValue;
- mLocked.pressureScale = 1.0f / mAxes.pressure.getRange();
- } else {
- mLocked.pressureOrigin = 0;
- mLocked.pressureScale = 1.0f;
- }
-
- mLocked.orientedRanges.pressure.min = 0.0f;
- mLocked.orientedRanges.pressure.max = 1.0f;
- mLocked.orientedRanges.pressure.flat = 0.0f;
- mLocked.orientedRanges.pressure.fuzz = mLocked.pressureScale;
-
- // Configure size factors.
- if (mAxes.size.valid) {
- mLocked.sizeOrigin = mAxes.size.minValue;
- mLocked.sizeScale = 1.0f / mAxes.size.getRange();
- } else {
- mLocked.sizeOrigin = 0;
- mLocked.sizeScale = 1.0f;
- }
-
- mLocked.orientedRanges.size.min = 0.0f;
- mLocked.orientedRanges.size.max = 1.0f;
- mLocked.orientedRanges.size.flat = 0.0f;
- mLocked.orientedRanges.size.fuzz = mLocked.sizeScale;
-
- // Configure orientation factors.
- if (mAxes.orientation.valid && mAxes.orientation.maxValue > 0) {
- mLocked.orientationScale = float(M_PI_2) / mAxes.orientation.maxValue;
- } else {
- mLocked.orientationScale = 0.0f;
- }
-
- mLocked.orientedRanges.orientation.min = - M_PI_2;
- mLocked.orientedRanges.orientation.max = M_PI_2;
- mLocked.orientedRanges.orientation.flat = 0;
- mLocked.orientedRanges.orientation.fuzz = mLocked.orientationScale;
-
- // Configure surface dimensions and orientation.
+ // Configure surface dimensions and orientation.
configureSurfaceLocked();
} // release lock
}
-void TouchInputMapper::configureAxes() {
- mAxes.x.valid = false;
- mAxes.y.valid = false;
- mAxes.pressure.valid = false;
- mAxes.size.valid = false;
- mAxes.touchMajor.valid = false;
- mAxes.touchMinor.valid = false;
- mAxes.toolMajor.valid = false;
- mAxes.toolMinor.valid = false;
- mAxes.orientation.valid = false;
+void TouchInputMapper::configureParameters() {
+ mParameters.useBadTouchFilter = getPolicy()->filterTouchEvents();
+ mParameters.useAveragingTouchFilter = getPolicy()->filterTouchEvents();
+ mParameters.useJumpyTouchFilter = getPolicy()->filterJumpyTouchEvents();
+}
+
+void TouchInputMapper::configureRawAxes() {
+ mRawAxes.x.clear();
+ mRawAxes.y.clear();
+ mRawAxes.pressure.clear();
+ mRawAxes.touchMajor.clear();
+ mRawAxes.touchMinor.clear();
+ mRawAxes.toolMajor.clear();
+ mRawAxes.toolMinor.clear();
+ mRawAxes.orientation.clear();
+}
+
+void TouchInputMapper::logRawAxes() {
+ logAxisInfo(mRawAxes.x, "x");
+ logAxisInfo(mRawAxes.y, "y");
+ logAxisInfo(mRawAxes.pressure, "pressure");
+ logAxisInfo(mRawAxes.touchMajor, "touchMajor");
+ logAxisInfo(mRawAxes.touchMinor, "touchMinor");
+ logAxisInfo(mRawAxes.toolMajor, "toolMajor");
+ logAxisInfo(mRawAxes.toolMinor, "toolMinor");
+ logAxisInfo(mRawAxes.orientation, "orientation");
}
bool TouchInputMapper::configureSurfaceLocked() {
@@ -1228,8 +1320,8 @@ bool TouchInputMapper::configureSurfaceLocked() {
}
} else {
orientation = InputReaderPolicyInterface::ROTATION_0;
- width = mAxes.x.getRange();
- height = mAxes.y.getRange();
+ width = mRawAxes.x.getRange();
+ height = mRawAxes.y.getRange();
}
bool orientationChanged = mLocked.surfaceOrientation != orientation;
@@ -1239,24 +1331,24 @@ bool TouchInputMapper::configureSurfaceLocked() {
bool sizeChanged = mLocked.surfaceWidth != width || mLocked.surfaceHeight != height;
if (sizeChanged) {
+ LOGI("Device configured: id=0x%x, name=%s (display size was changed)",
+ getDeviceId(), getDeviceName().string());
+
mLocked.surfaceWidth = width;
mLocked.surfaceHeight = height;
- // Compute size-dependent translation and scaling factors and place virtual keys.
- if (mAxes.x.valid && mAxes.y.valid) {
- mLocked.xOrigin = mAxes.x.minValue;
- mLocked.yOrigin = mAxes.y.minValue;
-
- LOGI("Device configured: id=0x%x, name=%s (display size was changed)",
- getDeviceId(), getDeviceName().string());
-
- mLocked.xScale = float(width) / mAxes.x.getRange();
- mLocked.yScale = float(height) / mAxes.y.getRange();
+ // Configure X and Y factors.
+ if (mRawAxes.x.valid && mRawAxes.y.valid) {
+ mLocked.xOrigin = mRawAxes.x.minValue;
+ mLocked.yOrigin = mRawAxes.y.minValue;
+ mLocked.xScale = float(width) / mRawAxes.x.getRange();
+ mLocked.yScale = float(height) / mRawAxes.y.getRange();
mLocked.xPrecision = 1.0f / mLocked.xScale;
mLocked.yPrecision = 1.0f / mLocked.yScale;
configureVirtualKeysLocked();
} else {
+ LOGW(INDENT "Touch device did not report support for X or Y axis!");
mLocked.xOrigin = 0;
mLocked.yOrigin = 0;
mLocked.xScale = 1.0f;
@@ -1265,22 +1357,112 @@ bool TouchInputMapper::configureSurfaceLocked() {
mLocked.yPrecision = 1.0f;
}
- // Configure touch and tool area ranges.
- float diagonal = sqrt(float(width * width + height * height));
- float diagonalFuzz = sqrt(mLocked.xScale * mLocked.xScale
- + mLocked.yScale * mLocked.yScale);
+ // Scale factor for terms that are not oriented in a particular axis.
+ // If the pixels are square then xScale == yScale otherwise we fake it
+ // by choosing an average.
+ mLocked.geometricScale = avg(mLocked.xScale, mLocked.yScale);
+
+ // Size of diagonal axis.
+ float diagonalSize = pythag(width, height);
+
+ // TouchMajor and TouchMinor factors.
+ if (mCalibration.touchAreaCalibration != Calibration::TOUCH_AREA_CALIBRATION_NONE) {
+ mLocked.orientedRanges.haveTouchArea = true;
+ mLocked.orientedRanges.touchMajor.min = 0;
+ mLocked.orientedRanges.touchMajor.max = diagonalSize;
+ mLocked.orientedRanges.touchMajor.flat = 0;
+ mLocked.orientedRanges.touchMajor.fuzz = 0;
+ mLocked.orientedRanges.touchMinor = mLocked.orientedRanges.touchMajor;
+ }
+
+ // ToolMajor and ToolMinor factors.
+ if (mCalibration.toolAreaCalibration != Calibration::TOOL_AREA_CALIBRATION_NONE) {
+ mLocked.toolAreaLinearScale = 0;
+ mLocked.toolAreaLinearBias = 0;
+ if (mCalibration.toolAreaCalibration == Calibration::TOOL_AREA_CALIBRATION_LINEAR) {
+ if (mCalibration.haveToolAreaLinearScale) {
+ mLocked.toolAreaLinearScale = mCalibration.toolAreaLinearScale;
+ } else if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) {
+ mLocked.toolAreaLinearScale = float(min(width, height))
+ / mRawAxes.toolMajor.maxValue;
+ }
+
+ if (mCalibration.haveToolAreaLinearBias) {
+ mLocked.toolAreaLinearBias = mCalibration.toolAreaLinearBias;
+ }
+ }
+
+ mLocked.orientedRanges.haveToolArea = true;
+ mLocked.orientedRanges.toolMajor.min = 0;
+ mLocked.orientedRanges.toolMajor.max = diagonalSize;
+ mLocked.orientedRanges.toolMajor.flat = 0;
+ mLocked.orientedRanges.toolMajor.fuzz = 0;
+ mLocked.orientedRanges.toolMinor = mLocked.orientedRanges.toolMajor;
+ }
+
+ // Pressure factors.
+ if (mCalibration.pressureCalibration != Calibration::PRESSURE_CALIBRATION_NONE) {
+ RawAbsoluteAxisInfo rawPressureAxis;
+ switch (mCalibration.pressureSource) {
+ case Calibration::PRESSURE_SOURCE_PRESSURE:
+ rawPressureAxis = mRawAxes.pressure;
+ break;
+ case Calibration::PRESSURE_SOURCE_TOUCH:
+ rawPressureAxis = mRawAxes.touchMajor;
+ break;
+ default:
+ rawPressureAxis.clear();
+ }
+
+ mLocked.pressureScale = 0;
+ if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_PHYSICAL
+ || mCalibration.pressureCalibration
+ == Calibration::PRESSURE_CALIBRATION_AMPLITUDE) {
+ if (mCalibration.havePressureScale) {
+ mLocked.pressureScale = mCalibration.pressureScale;
+ } else if (rawPressureAxis.valid && rawPressureAxis.maxValue != 0) {
+ mLocked.pressureScale = 1.0f / rawPressureAxis.maxValue;
+ }
+ }
+
+ mLocked.orientedRanges.havePressure = true;
+ mLocked.orientedRanges.pressure.min = 0;
+ mLocked.orientedRanges.pressure.max = 1.0;
+ mLocked.orientedRanges.pressure.flat = 0;
+ mLocked.orientedRanges.pressure.fuzz = 0;
+ }
+
+ // Size factors.
+ if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) {
+ mLocked.sizeScale = 0;
+ if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_NORMALIZED) {
+ if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) {
+ mLocked.sizeScale = 1.0f / mRawAxes.toolMajor.maxValue;
+ }
+ }
- InputDeviceInfo::MotionRange area;
- area.min = 0.0f;
- area.max = diagonal;
- area.flat = 0.0f;
- area.fuzz = diagonalFuzz;
+ mLocked.orientedRanges.haveSize = true;
+ mLocked.orientedRanges.size.min = 0;
+ mLocked.orientedRanges.size.max = 1.0;
+ mLocked.orientedRanges.size.flat = 0;
+ mLocked.orientedRanges.size.fuzz = 0;
+ }
- mLocked.orientedRanges.touchMajor = area;
- mLocked.orientedRanges.touchMinor = area;
+ // Orientation
+ if (mCalibration.orientationCalibration != Calibration::ORIENTATION_CALIBRATION_NONE) {
+ mLocked.orientationScale = 0;
+ if (mCalibration.orientationCalibration
+ == Calibration::ORIENTATION_CALIBRATION_INTERPOLATED) {
+ if (mRawAxes.orientation.valid && mRawAxes.orientation.maxValue != 0) {
+ mLocked.orientationScale = float(M_PI_2) / mRawAxes.orientation.maxValue;
+ }
+ }
- mLocked.orientedRanges.toolMajor = area;
- mLocked.orientedRanges.toolMinor = area;
+ mLocked.orientedRanges.orientation.min = - M_PI_2;
+ mLocked.orientedRanges.orientation.max = M_PI_2;
+ mLocked.orientedRanges.orientation.flat = 0;
+ mLocked.orientedRanges.orientation.fuzz = 0;
+ }
}
if (orientationChanged || sizeChanged) {
@@ -1322,10 +1504,10 @@ bool TouchInputMapper::configureSurfaceLocked() {
}
void TouchInputMapper::configureVirtualKeysLocked() {
- assert(mAxes.x.valid && mAxes.y.valid);
+ assert(mRawAxes.x.valid && mRawAxes.y.valid);
// Note: getVirtualKeyDefinitions is non-reentrant so we can continue holding the lock.
- Vector<InputReaderPolicyInterface::VirtualKeyDefinition> virtualKeyDefinitions;
+ Vector<VirtualKeyDefinition> virtualKeyDefinitions;
getPolicy()->getVirtualKeyDefinitions(getDeviceName(), virtualKeyDefinitions);
mLocked.virtualKeys.clear();
@@ -1336,13 +1518,13 @@ void TouchInputMapper::configureVirtualKeysLocked() {
mLocked.virtualKeys.setCapacity(virtualKeyDefinitions.size());
- int32_t touchScreenLeft = mAxes.x.minValue;
- int32_t touchScreenTop = mAxes.y.minValue;
- int32_t touchScreenWidth = mAxes.x.getRange();
- int32_t touchScreenHeight = mAxes.y.getRange();
+ int32_t touchScreenLeft = mRawAxes.x.minValue;
+ int32_t touchScreenTop = mRawAxes.y.minValue;
+ int32_t touchScreenWidth = mRawAxes.x.getRange();
+ int32_t touchScreenHeight = mRawAxes.y.getRange();
for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) {
- const InputReaderPolicyInterface::VirtualKeyDefinition& virtualKeyDefinition =
+ const VirtualKeyDefinition& virtualKeyDefinition =
virtualKeyDefinitions[i];
mLocked.virtualKeys.add();
@@ -1353,7 +1535,8 @@ void TouchInputMapper::configureVirtualKeysLocked() {
uint32_t flags;
if (getEventHub()->scancodeToKeycode(getDeviceId(), virtualKey.scanCode,
& keyCode, & flags)) {
- LOGW(" VirtualKey %d: could not obtain key code, ignoring", virtualKey.scanCode);
+ LOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring",
+ virtualKey.scanCode);
mLocked.virtualKeys.pop(); // drop the key
continue;
}
@@ -1374,12 +1557,316 @@ void TouchInputMapper::configureVirtualKeysLocked() {
virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight)
* touchScreenHeight / mLocked.surfaceHeight + touchScreenTop;
- LOGI(" VirtualKey %d: keyCode=%d hitLeft=%d hitRight=%d hitTop=%d hitBottom=%d",
+ LOGI(INDENT "VirtualKey %d: keyCode=%d hitLeft=%d hitRight=%d hitTop=%d hitBottom=%d",
virtualKey.scanCode, virtualKey.keyCode,
virtualKey.hitLeft, virtualKey.hitRight, virtualKey.hitTop, virtualKey.hitBottom);
}
}
+void TouchInputMapper::parseCalibration() {
+ const InputDeviceCalibration& in = getDevice()->getCalibration();
+ Calibration& out = mCalibration;
+
+ // Touch Area
+ out.touchAreaCalibration = Calibration::TOUCH_AREA_CALIBRATION_DEFAULT;
+ String8 touchAreaCalibrationString;
+ if (in.tryGetProperty(String8("touch.touchArea.calibration"), touchAreaCalibrationString)) {
+ if (touchAreaCalibrationString == "none") {
+ out.touchAreaCalibration = Calibration::TOUCH_AREA_CALIBRATION_NONE;
+ } else if (touchAreaCalibrationString == "geometric") {
+ out.touchAreaCalibration = Calibration::TOUCH_AREA_CALIBRATION_GEOMETRIC;
+ } else if (touchAreaCalibrationString == "pressure") {
+ out.touchAreaCalibration = Calibration::TOUCH_AREA_CALIBRATION_PRESSURE;
+ } else if (touchAreaCalibrationString != "default") {
+ LOGW("Invalid value for touch.touchArea.calibration: '%s'",
+ touchAreaCalibrationString.string());
+ }
+ }
+
+ // Tool Area
+ out.toolAreaCalibration = Calibration::TOOL_AREA_CALIBRATION_DEFAULT;
+ String8 toolAreaCalibrationString;
+ if (in.tryGetProperty(String8("tool.toolArea.calibration"), toolAreaCalibrationString)) {
+ if (toolAreaCalibrationString == "none") {
+ out.toolAreaCalibration = Calibration::TOOL_AREA_CALIBRATION_NONE;
+ } else if (toolAreaCalibrationString == "geometric") {
+ out.toolAreaCalibration = Calibration::TOOL_AREA_CALIBRATION_GEOMETRIC;
+ } else if (toolAreaCalibrationString == "linear") {
+ out.toolAreaCalibration = Calibration::TOOL_AREA_CALIBRATION_LINEAR;
+ } else if (toolAreaCalibrationString != "default") {
+ LOGW("Invalid value for tool.toolArea.calibration: '%s'",
+ toolAreaCalibrationString.string());
+ }
+ }
+
+ out.haveToolAreaLinearScale = in.tryGetProperty(String8("touch.toolArea.linearScale"),
+ out.toolAreaLinearScale);
+ out.haveToolAreaLinearBias = in.tryGetProperty(String8("touch.toolArea.linearBias"),
+ out.toolAreaLinearBias);
+ out.haveToolAreaIsSummed = in.tryGetProperty(String8("touch.toolArea.isSummed"),
+ out.toolAreaIsSummed);
+
+ // Pressure
+ out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_DEFAULT;
+ String8 pressureCalibrationString;
+ if (in.tryGetProperty(String8("tool.pressure.calibration"), pressureCalibrationString)) {
+ if (pressureCalibrationString == "none") {
+ out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
+ } else if (pressureCalibrationString == "physical") {
+ out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL;
+ } else if (pressureCalibrationString == "amplitude") {
+ out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE;
+ } else if (pressureCalibrationString != "default") {
+ LOGW("Invalid value for tool.pressure.calibration: '%s'",
+ pressureCalibrationString.string());
+ }
+ }
+
+ out.pressureSource = Calibration::PRESSURE_SOURCE_DEFAULT;
+ String8 pressureSourceString;
+ if (in.tryGetProperty(String8("touch.pressure.source"), pressureSourceString)) {
+ if (pressureSourceString == "pressure") {
+ out.pressureSource = Calibration::PRESSURE_SOURCE_PRESSURE;
+ } else if (pressureSourceString == "touch") {
+ out.pressureSource = Calibration::PRESSURE_SOURCE_TOUCH;
+ } else if (pressureSourceString != "default") {
+ LOGW("Invalid value for touch.pressure.source: '%s'",
+ pressureSourceString.string());
+ }
+ }
+
+ out.havePressureScale = in.tryGetProperty(String8("touch.pressure.scale"),
+ out.pressureScale);
+
+ // Size
+ out.sizeCalibration = Calibration::SIZE_CALIBRATION_DEFAULT;
+ String8 sizeCalibrationString;
+ if (in.tryGetProperty(String8("tool.size.calibration"), sizeCalibrationString)) {
+ if (sizeCalibrationString == "none") {
+ out.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
+ } else if (sizeCalibrationString == "normalized") {
+ out.sizeCalibration = Calibration::SIZE_CALIBRATION_NORMALIZED;
+ } else if (sizeCalibrationString != "default") {
+ LOGW("Invalid value for tool.size.calibration: '%s'",
+ sizeCalibrationString.string());
+ }
+ }
+
+ // Orientation
+ out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_DEFAULT;
+ String8 orientationCalibrationString;
+ if (in.tryGetProperty(String8("tool.orientation.calibration"), orientationCalibrationString)) {
+ if (orientationCalibrationString == "none") {
+ out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
+ } else if (orientationCalibrationString == "interpolated") {
+ out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
+ } else if (orientationCalibrationString != "default") {
+ LOGW("Invalid value for tool.orientation.calibration: '%s'",
+ orientationCalibrationString.string());
+ }
+ }
+}
+
+void TouchInputMapper::resolveCalibration() {
+ // Pressure
+ switch (mCalibration.pressureSource) {
+ case Calibration::PRESSURE_SOURCE_DEFAULT:
+ if (mRawAxes.pressure.valid) {
+ mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_PRESSURE;
+ } else if (mRawAxes.touchMajor.valid) {
+ mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_TOUCH;
+ }
+ break;
+
+ case Calibration::PRESSURE_SOURCE_PRESSURE:
+ if (! mRawAxes.pressure.valid) {
+ LOGW("Calibration property touch.pressure.source is 'pressure' but "
+ "the pressure axis is not available.");
+ }
+ break;
+
+ case Calibration::PRESSURE_SOURCE_TOUCH:
+ if (! mRawAxes.touchMajor.valid) {
+ LOGW("Calibration property touch.pressure.source is 'touch' but "
+ "the touchMajor axis is not available.");
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ switch (mCalibration.pressureCalibration) {
+ case Calibration::PRESSURE_CALIBRATION_DEFAULT:
+ if (mCalibration.pressureSource != Calibration::PRESSURE_SOURCE_DEFAULT) {
+ mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE;
+ } else {
+ mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ // Tool Area
+ switch (mCalibration.toolAreaCalibration) {
+ case Calibration::TOOL_AREA_CALIBRATION_DEFAULT:
+ if (mRawAxes.toolMajor.valid) {
+ mCalibration.toolAreaCalibration = Calibration::TOOL_AREA_CALIBRATION_LINEAR;
+ } else {
+ mCalibration.toolAreaCalibration = Calibration::TOOL_AREA_CALIBRATION_NONE;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ // Touch Area
+ switch (mCalibration.touchAreaCalibration) {
+ case Calibration::TOUCH_AREA_CALIBRATION_DEFAULT:
+ if (mCalibration.pressureCalibration != Calibration::PRESSURE_CALIBRATION_NONE
+ && mCalibration.toolAreaCalibration != Calibration::TOOL_AREA_CALIBRATION_NONE) {
+ mCalibration.touchAreaCalibration = Calibration::TOUCH_AREA_CALIBRATION_PRESSURE;
+ } else {
+ mCalibration.touchAreaCalibration = Calibration::TOUCH_AREA_CALIBRATION_NONE;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ // Size
+ switch (mCalibration.sizeCalibration) {
+ case Calibration::SIZE_CALIBRATION_DEFAULT:
+ if (mRawAxes.toolMajor.valid) {
+ mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NORMALIZED;
+ } else {
+ mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ // Orientation
+ switch (mCalibration.orientationCalibration) {
+ case Calibration::ORIENTATION_CALIBRATION_DEFAULT:
+ if (mRawAxes.orientation.valid) {
+ mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
+ } else {
+ mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void TouchInputMapper::logCalibration() {
+ // Touch Area
+ switch (mCalibration.touchAreaCalibration) {
+ case Calibration::TOUCH_AREA_CALIBRATION_NONE:
+ LOGI(INDENT " touch.touchArea.calibration: none");
+ break;
+ case Calibration::TOUCH_AREA_CALIBRATION_GEOMETRIC:
+ LOGI(INDENT " touch.touchArea.calibration: geometric");
+ break;
+ case Calibration::TOUCH_AREA_CALIBRATION_PRESSURE:
+ LOGI(INDENT " touch.touchArea.calibration: pressure");
+ break;
+ default:
+ assert(false);
+ }
+
+ // Tool Area
+ switch (mCalibration.toolAreaCalibration) {
+ case Calibration::TOOL_AREA_CALIBRATION_NONE:
+ LOGI(INDENT " touch.toolArea.calibration: none");
+ break;
+ case Calibration::TOOL_AREA_CALIBRATION_GEOMETRIC:
+ LOGI(INDENT " touch.toolArea.calibration: geometric");
+ break;
+ case Calibration::TOOL_AREA_CALIBRATION_LINEAR:
+ LOGI(INDENT " touch.toolArea.calibration: linear");
+ break;
+ default:
+ assert(false);
+ }
+
+ if (mCalibration.haveToolAreaLinearScale) {
+ LOGI(INDENT " touch.toolArea.linearScale: %f", mCalibration.toolAreaLinearScale);
+ }
+
+ if (mCalibration.haveToolAreaLinearBias) {
+ LOGI(INDENT " touch.toolArea.linearBias: %f", mCalibration.toolAreaLinearBias);
+ }
+
+ if (mCalibration.haveToolAreaIsSummed) {
+ LOGI(INDENT " touch.toolArea.isSummed: %d", mCalibration.toolAreaIsSummed);
+ }
+
+ // Pressure
+ switch (mCalibration.pressureCalibration) {
+ case Calibration::PRESSURE_CALIBRATION_NONE:
+ LOGI(INDENT " touch.pressure.calibration: none");
+ break;
+ case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
+ LOGI(INDENT " touch.pressure.calibration: physical");
+ break;
+ case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
+ LOGI(INDENT " touch.pressure.calibration: amplitude");
+ break;
+ default:
+ assert(false);
+ }
+
+ switch (mCalibration.pressureSource) {
+ case Calibration::PRESSURE_SOURCE_PRESSURE:
+ LOGI(INDENT " touch.pressure.source: pressure");
+ break;
+ case Calibration::PRESSURE_SOURCE_TOUCH:
+ LOGI(INDENT " touch.pressure.source: touch");
+ break;
+ case Calibration::PRESSURE_SOURCE_DEFAULT:
+ break;
+ default:
+ assert(false);
+ }
+
+ if (mCalibration.havePressureScale) {
+ LOGI(INDENT " touch.pressure.scale: %f", mCalibration.pressureScale);
+ }
+
+ // Size
+ switch (mCalibration.sizeCalibration) {
+ case Calibration::SIZE_CALIBRATION_NONE:
+ LOGI(INDENT " touch.size.calibration: none");
+ break;
+ case Calibration::SIZE_CALIBRATION_NORMALIZED:
+ LOGI(INDENT " touch.size.calibration: normalized");
+ break;
+ default:
+ assert(false);
+ }
+
+ // Orientation
+ switch (mCalibration.orientationCalibration) {
+ case Calibration::ORIENTATION_CALIBRATION_NONE:
+ LOGI(INDENT " touch.orientation.calibration: none");
+ break;
+ case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
+ LOGI(INDENT " touch.orientation.calibration: interpolated");
+ break;
+ default:
+ assert(false);
+ }
+}
+
void TouchInputMapper::reset() {
// Synthesize touch up event if touch is currently down.
// This will also take care of finishing virtual key processing if needed.
@@ -1584,13 +2071,14 @@ void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
// The dispatcher takes care of batching moves so we don't have to deal with that here.
int32_t motionEventAction = AMOTION_EVENT_ACTION_MOVE;
dispatchTouch(when, policyFlags, & mCurrentTouch,
- currentIdBits, -1, motionEventAction);
+ currentIdBits, -1, currentPointerCount, motionEventAction);
} else {
// There may be pointers going up and pointers going down at the same time when pointer
// ids are reported by the device driver.
BitSet32 upIdBits(lastIdBits.value & ~ currentIdBits.value);
BitSet32 downIdBits(currentIdBits.value & ~ lastIdBits.value);
BitSet32 activeIdBits(lastIdBits.value);
+ uint32_t pointerCount = lastPointerCount;
while (! upIdBits.isEmpty()) {
uint32_t upId = upIdBits.firstMarkedBit();
@@ -1606,7 +2094,8 @@ void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
}
dispatchTouch(when, policyFlags, & mLastTouch,
- oldActiveIdBits, upId, motionEventAction);
+ oldActiveIdBits, upId, pointerCount, motionEventAction);
+ pointerCount -= 1;
}
while (! downIdBits.isEmpty()) {
@@ -1623,16 +2112,16 @@ void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
motionEventAction = AMOTION_EVENT_ACTION_POINTER_DOWN;
}
+ pointerCount += 1;
dispatchTouch(when, policyFlags, & mCurrentTouch,
- activeIdBits, downId, motionEventAction);
+ activeIdBits, downId, pointerCount, motionEventAction);
}
}
}
void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags,
- TouchData* touch, BitSet32 idBits, uint32_t changedId,
+ TouchData* touch, BitSet32 idBits, uint32_t changedId, uint32_t pointerCount,
int32_t motionEventAction) {
- uint32_t pointerCount = 0;
int32_t pointerIds[MAX_POINTERS];
PointerCoords pointerCoords[MAX_POINTERS];
int32_t motionEventEdgeFlags = 0;
@@ -1643,36 +2132,130 @@ void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags,
// Walk through the the active pointers and map touch screen coordinates (TouchData) into
// display coordinates (PointerCoords) and adjust for display orientation.
- while (! idBits.isEmpty()) {
+ for (uint32_t outIndex = 0; ! idBits.isEmpty(); outIndex++) {
uint32_t id = idBits.firstMarkedBit();
idBits.clearBit(id);
- uint32_t index = touch->idToIndex[id];
-
- float x = float(touch->pointers[index].x - mLocked.xOrigin) * mLocked.xScale;
- float y = float(touch->pointers[index].y - mLocked.yOrigin) * mLocked.yScale;
- float pressure = float(touch->pointers[index].pressure - mLocked.pressureOrigin)
- * mLocked.pressureScale;
- float size = float(touch->pointers[index].size - mLocked.sizeOrigin)
- * mLocked.sizeScale;
-
- float orientation = float(touch->pointers[index].orientation)
- * mLocked.orientationScale;
-
- float touchMajor, touchMinor, toolMajor, toolMinor;
- if (abs(orientation) <= M_PI_4) {
- // Nominally vertical orientation: scale major axis by Y, and scale minor axis by X.
- touchMajor = float(touch->pointers[index].touchMajor) * mLocked.yScale;
- touchMinor = float(touch->pointers[index].touchMinor) * mLocked.xScale;
- toolMajor = float(touch->pointers[index].toolMajor) * mLocked.yScale;
- toolMinor = float(touch->pointers[index].toolMinor) * mLocked.xScale;
- } else {
- // Nominally horizontal orientation: scale major axis by X, and scale minor axis by Y.
- touchMajor = float(touch->pointers[index].touchMajor) * mLocked.xScale;
- touchMinor = float(touch->pointers[index].touchMinor) * mLocked.yScale;
- toolMajor = float(touch->pointers[index].toolMajor) * mLocked.xScale;
- toolMinor = float(touch->pointers[index].toolMinor) * mLocked.yScale;
+ uint32_t inIndex = touch->idToIndex[id];
+
+ const PointerData& in = touch->pointers[inIndex];
+
+ // X and Y
+ float x = float(in.x - mLocked.xOrigin) * mLocked.xScale;
+ float y = float(in.y - mLocked.yOrigin) * mLocked.yScale;
+
+ // ToolMajor and ToolMinor
+ float toolMajor, toolMinor;
+ switch (mCalibration.toolAreaCalibration) {
+ case Calibration::TOOL_AREA_CALIBRATION_GEOMETRIC:
+ toolMajor = in.toolMajor * mLocked.geometricScale;
+ if (mRawAxes.toolMinor.valid) {
+ toolMinor = in.toolMinor * mLocked.geometricScale;
+ } else {
+ toolMinor = toolMajor;
+ }
+ break;
+ case Calibration::TOOL_AREA_CALIBRATION_LINEAR:
+ toolMajor = in.toolMajor != 0
+ ? in.toolMajor * mLocked.toolAreaLinearScale + mLocked.toolAreaLinearBias
+ : 0;
+ if (mRawAxes.toolMinor.valid) {
+ toolMinor = in.toolMinor != 0
+ ? in.toolMinor * mLocked.toolAreaLinearScale
+ + mLocked.toolAreaLinearBias
+ : 0;
+ } else {
+ toolMinor = toolMajor;
+ }
+ break;
+ default:
+ toolMajor = 0;
+ toolMinor = 0;
+ break;
+ }
+
+ if (mCalibration.haveToolAreaIsSummed && mCalibration.toolAreaIsSummed) {
+ toolMajor /= pointerCount;
+ toolMinor /= pointerCount;
+ }
+
+ // Pressure
+ float rawPressure;
+ switch (mCalibration.pressureSource) {
+ case Calibration::PRESSURE_SOURCE_PRESSURE:
+ rawPressure = in.pressure;
+ break;
+ case Calibration::PRESSURE_SOURCE_TOUCH:
+ rawPressure = in.touchMajor;
+ break;
+ default:
+ rawPressure = 0;
+ }
+
+ float pressure;
+ switch (mCalibration.pressureCalibration) {
+ case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
+ case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
+ pressure = rawPressure * mLocked.pressureScale;
+ break;
+ default:
+ pressure = 1;
+ break;
+ }
+
+ // TouchMajor and TouchMinor
+ float touchMajor, touchMinor;
+ switch (mCalibration.touchAreaCalibration) {
+ case Calibration::TOUCH_AREA_CALIBRATION_GEOMETRIC:
+ touchMajor = in.touchMajor * mLocked.geometricScale;
+ if (mRawAxes.touchMinor.valid) {
+ touchMinor = in.touchMinor * mLocked.geometricScale;
+ } else {
+ touchMinor = touchMajor;
+ }
+ break;
+ case Calibration::TOUCH_AREA_CALIBRATION_PRESSURE:
+ touchMajor = toolMajor * pressure;
+ touchMinor = toolMinor * pressure;
+ break;
+ default:
+ touchMajor = 0;
+ touchMinor = 0;
+ break;
+ }
+
+ if (touchMajor > toolMajor) {
+ touchMajor = toolMajor;
+ }
+ if (touchMinor > toolMinor) {
+ touchMinor = toolMinor;
+ }
+
+ // Size
+ float size;
+ switch (mCalibration.sizeCalibration) {
+ case Calibration::SIZE_CALIBRATION_NORMALIZED: {
+ float rawSize = mRawAxes.toolMinor.valid
+ ? avg(in.toolMajor, in.toolMinor)
+ : in.toolMajor;
+ size = rawSize * mLocked.sizeScale;
+ break;
+ }
+ default:
+ size = 0;
+ break;
}
+ // Orientation
+ float orientation;
+ switch (mCalibration.orientationCalibration) {
+ case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
+ orientation = in.orientation * mLocked.orientationScale;
+ break;
+ default:
+ orientation = 0;
+ }
+
+ // Adjust coords for orientation.
switch (mLocked.surfaceOrientation) {
case InputReaderPolicyInterface::ROTATION_90: {
float xTemp = x;
@@ -1702,23 +2285,23 @@ void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags,
}
}
- pointerIds[pointerCount] = int32_t(id);
+ // Write output coords.
+ PointerCoords& out = pointerCoords[outIndex];
+ out.x = x;
+ out.y = y;
+ out.pressure = pressure;
+ out.size = size;
+ out.touchMajor = touchMajor;
+ out.touchMinor = touchMinor;
+ out.toolMajor = toolMajor;
+ out.toolMinor = toolMinor;
+ out.orientation = orientation;
- pointerCoords[pointerCount].x = x;
- pointerCoords[pointerCount].y = y;
- pointerCoords[pointerCount].pressure = pressure;
- pointerCoords[pointerCount].size = size;
- pointerCoords[pointerCount].touchMajor = touchMajor;
- pointerCoords[pointerCount].touchMinor = touchMinor;
- pointerCoords[pointerCount].toolMajor = toolMajor;
- pointerCoords[pointerCount].toolMinor = toolMinor;
- pointerCoords[pointerCount].orientation = orientation;
+ pointerIds[outIndex] = int32_t(id);
if (id == changedId) {
- motionEventAction |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
+ motionEventAction |= outIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
}
-
- pointerCount += 1;
}
// Check edge flags by looking only at the first pointer since the flags are
@@ -1747,9 +2330,9 @@ void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags,
}
bool TouchInputMapper::isPointInsideSurfaceLocked(int32_t x, int32_t y) {
- if (mAxes.x.valid && mAxes.y.valid) {
- return x >= mAxes.x.minValue && x <= mAxes.x.maxValue
- && y >= mAxes.y.minValue && y <= mAxes.y.maxValue;
+ if (mRawAxes.x.valid && mRawAxes.y.valid) {
+ return x >= mRawAxes.x.minValue && x <= mRawAxes.x.maxValue
+ && y >= mRawAxes.y.minValue && y <= mRawAxes.y.maxValue;
}
return true;
}
@@ -1960,7 +2543,7 @@ void TouchInputMapper::calculatePointerIds() {
* then drop it. */
bool TouchInputMapper::applyBadTouchFilter() {
// This hack requires valid axis parameters.
- if (! mAxes.y.valid) {
+ if (! mRawAxes.y.valid) {
return false;
}
@@ -1982,7 +2565,7 @@ bool TouchInputMapper::applyBadTouchFilter() {
// the long size of the screen to be bad. This was a magic value
// determined by looking at the maximum distance it is feasible
// to actually move in one sample.
- int32_t maxDeltaY = mAxes.y.getRange() * 7 / 16;
+ int32_t maxDeltaY = mRawAxes.y.getRange() * 7 / 16;
// XXX The original code in InputDevice.java included commented out
// code for testing the X axis. Note that when we drop a point
@@ -2044,7 +2627,7 @@ bool TouchInputMapper::applyBadTouchFilter() {
*/
bool TouchInputMapper::applyJumpyTouchFilter() {
// This hack requires valid axis parameters.
- if (! mAxes.y.valid) {
+ if (! mRawAxes.y.valid) {
return false;
}
@@ -2104,7 +2687,7 @@ bool TouchInputMapper::applyJumpyTouchFilter() {
}
if (mJumpyTouchFilter.jumpyPointsDropped < JUMPY_DROP_LIMIT) {
- int jumpyEpsilon = mAxes.y.getRange() / JUMPY_EPSILON_DIVISOR;
+ int jumpyEpsilon = mRawAxes.y.getRange() / JUMPY_EPSILON_DIVISOR;
// We only replace the single worst jumpy point as characterized by pointer distance
// in a single axis.
@@ -2209,7 +2792,18 @@ void TouchInputMapper::applyAveragingTouchFilter() {
uint32_t id = mCurrentTouch.pointers[currentIndex].id;
int32_t x = mCurrentTouch.pointers[currentIndex].x;
int32_t y = mCurrentTouch.pointers[currentIndex].y;
- int32_t pressure = mCurrentTouch.pointers[currentIndex].pressure;
+ int32_t pressure;
+ switch (mCalibration.pressureSource) {
+ case Calibration::PRESSURE_SOURCE_PRESSURE:
+ pressure = mCurrentTouch.pointers[currentIndex].pressure;
+ break;
+ case Calibration::PRESSURE_SOURCE_TOUCH:
+ pressure = mCurrentTouch.pointers[currentIndex].touchMajor;
+ break;
+ default:
+ pressure = 1;
+ break;
+ }
if (mLastTouch.idBits.hasBit(id)) {
// Pointer was down before and is still down now.
@@ -2274,17 +2868,19 @@ void TouchInputMapper::applyAveragingTouchFilter() {
}
}
- averagedX /= totalPressure;
- averagedY /= totalPressure;
+ if (totalPressure != 0) {
+ averagedX /= totalPressure;
+ averagedY /= totalPressure;
#if DEBUG_HACKS
- LOGD("AveragingTouchFilter: Pointer id %d - "
- "totalPressure=%d, averagedX=%d, averagedY=%d", id, totalPressure,
- averagedX, averagedY);
+ LOGD("AveragingTouchFilter: Pointer id %d - "
+ "totalPressure=%d, averagedX=%d, averagedY=%d", id, totalPressure,
+ averagedX, averagedY);
#endif
- mCurrentTouch.pointers[currentIndex].x = averagedX;
- mCurrentTouch.pointers[currentIndex].y = averagedY;
+ mCurrentTouch.pointers[currentIndex].x = averagedX;
+ mCurrentTouch.pointers[currentIndex].y = averagedY;
+ }
} else {
#if DEBUG_HACKS
LOGD("AveragingTouchFilter: Pointer id %d - Exceeded max distance", id);
@@ -2382,8 +2978,8 @@ void SingleTouchInputMapper::initialize() {
mDown = false;
mX = 0;
mY = 0;
- mPressure = 1; // default to 1 for devices that don't report pressure
- mSize = 0; // default to 0 for devices that don't report size
+ mPressure = 0; // default to 0 for devices that don't report pressure
+ mToolWidth = 0; // default to 0 for devices that don't report tool width
}
void SingleTouchInputMapper::reset() {
@@ -2460,7 +3056,7 @@ void SingleTouchInputMapper::sync(nsecs_t when) {
}
if (fields & Accumulator::FIELD_ABS_TOOL_WIDTH) {
- mSize = mAccumulator.absToolWidth;
+ mToolWidth = mAccumulator.absToolWidth;
}
mCurrentTouch.clear();
@@ -2471,11 +3067,10 @@ void SingleTouchInputMapper::sync(nsecs_t when) {
mCurrentTouch.pointers[0].x = mX;
mCurrentTouch.pointers[0].y = mY;
mCurrentTouch.pointers[0].pressure = mPressure;
- mCurrentTouch.pointers[0].size = mSize;
- mCurrentTouch.pointers[0].touchMajor = mSize;
- mCurrentTouch.pointers[0].touchMinor = mSize;
- mCurrentTouch.pointers[0].toolMajor = mSize;
- mCurrentTouch.pointers[0].toolMinor = mSize;
+ mCurrentTouch.pointers[0].touchMajor = 0;
+ mCurrentTouch.pointers[0].touchMinor = 0;
+ mCurrentTouch.pointers[0].toolMajor = mToolWidth;
+ mCurrentTouch.pointers[0].toolMinor = mToolWidth;
mCurrentTouch.pointers[0].orientation = 0;
mCurrentTouch.idToIndex[0] = 0;
mCurrentTouch.idBits.markBit(0);
@@ -2486,20 +3081,13 @@ void SingleTouchInputMapper::sync(nsecs_t when) {
mAccumulator.clear();
}
-void SingleTouchInputMapper::configureAxes() {
- TouchInputMapper::configureAxes();
-
- // The axes are aliased to take into account the manner in which they are presented
- // as part of the TouchData during the sync.
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_X, & mAxes.x);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_Y, & mAxes.y);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_PRESSURE, & mAxes.pressure);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_TOOL_WIDTH, & mAxes.size);
+void SingleTouchInputMapper::configureRawAxes() {
+ TouchInputMapper::configureRawAxes();
- mAxes.touchMajor = mAxes.size;
- mAxes.touchMinor = mAxes.size;
- mAxes.toolMajor = mAxes.size;
- mAxes.toolMinor = mAxes.size;
+ getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_X, & mRawAxes.x);
+ getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_Y, & mRawAxes.y);
+ getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_PRESSURE, & mRawAxes.pressure);
+ getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_TOOL_WIDTH, & mRawAxes.toolMajor);
}
@@ -2562,6 +3150,10 @@ void MultiTouchInputMapper::process(const RawEvent* rawEvent) {
pointer->fields |= Accumulator::FIELD_ABS_MT_TRACKING_ID;
pointer->absMTTrackingId = rawEvent->value;
break;
+ case ABS_MT_PRESSURE:
+ pointer->fields |= Accumulator::FIELD_ABS_MT_PRESSURE;
+ pointer->absMTPressure = rawEvent->value;
+ break;
}
break;
}
@@ -2596,8 +3188,7 @@ void MultiTouchInputMapper::process(const RawEvent* rawEvent) {
void MultiTouchInputMapper::sync(nsecs_t when) {
static const uint32_t REQUIRED_FIELDS =
- Accumulator::FIELD_ABS_MT_POSITION_X
- | Accumulator::FIELD_ABS_MT_POSITION_Y;
+ Accumulator::FIELD_ABS_MT_POSITION_X | Accumulator::FIELD_ABS_MT_POSITION_Y;
uint32_t inCount = mAccumulator.pointerCount;
uint32_t outCount = 0;
@@ -2619,60 +3210,59 @@ void MultiTouchInputMapper::sync(nsecs_t when) {
outPointer.x = inPointer.absMTPositionX;
outPointer.y = inPointer.absMTPositionY;
+ if (fields & Accumulator::FIELD_ABS_MT_PRESSURE) {
+ if (inPointer.absMTPressure <= 0) {
+ // Some devices send sync packets with X / Y but with a 0 presure to indicate
+ // a pointer up. Drop this finger.
+ continue;
+ }
+ outPointer.pressure = inPointer.absMTPressure;
+ } else {
+ // Default pressure to 0 if absent.
+ outPointer.pressure = 0;
+ }
+
if (fields & Accumulator::FIELD_ABS_MT_TOUCH_MAJOR) {
- int32_t value = inPointer.absMTTouchMajor;
- if (value <= 0) {
+ if (inPointer.absMTTouchMajor <= 0) {
// Some devices send sync packets with X / Y but with a 0 touch major to indicate
- // a pointer up. Drop this finger.
+ // a pointer going up. Drop this finger.
continue;
}
outPointer.touchMajor = inPointer.absMTTouchMajor;
} else {
+ // Default touch area to 0 if absent.
outPointer.touchMajor = 0;
}
if (fields & Accumulator::FIELD_ABS_MT_TOUCH_MINOR) {
outPointer.touchMinor = inPointer.absMTTouchMinor;
} else {
+ // Assume touch area is circular.
outPointer.touchMinor = outPointer.touchMajor;
}
if (fields & Accumulator::FIELD_ABS_MT_WIDTH_MAJOR) {
outPointer.toolMajor = inPointer.absMTWidthMajor;
} else {
- outPointer.toolMajor = outPointer.touchMajor;
+ // Default tool area to 0 if absent.
+ outPointer.toolMajor = 0;
}
if (fields & Accumulator::FIELD_ABS_MT_WIDTH_MINOR) {
outPointer.toolMinor = inPointer.absMTWidthMinor;
} else {
+ // Assume tool area is circular.
outPointer.toolMinor = outPointer.toolMajor;
}
if (fields & Accumulator::FIELD_ABS_MT_ORIENTATION) {
outPointer.orientation = inPointer.absMTOrientation;
} else {
+ // Default orientation to vertical if absent.
outPointer.orientation = 0;
}
- if (fields & Accumulator::FIELD_ABS_MT_PRESSURE) {
- outPointer.pressure = inPointer.absMTPressure;
- } else {
- // Derive an approximation of pressure.
- // FIXME Traditionally we have just passed a normalized value based on
- // ABS_MT_TOUCH_MAJOR as an estimate of pressure but the result is not
- // very meaningful, particularly on large displays. We should probably let
- // pressure = touch_major / tool_major but it is unclear whether that will
- // break applications.
- outPointer.pressure = outPointer.touchMajor;
- }
-
- // Size is an alias for a normalized tool width.
- // FIXME Normalized tool width doesn't actually make much sense since it literally
- // means the approaching contact major axis is divided by its full range as
- // reported by the driver. On a large display this could produce very small values.
- outPointer.size = outPointer.toolMajor;
-
+ // Assign pointer id using tracking id if available.
if (havePointerIds) {
if (fields & Accumulator::FIELD_ABS_MT_TRACKING_ID) {
uint32_t id = uint32_t(inPointer.absMTTrackingId);
@@ -2705,33 +3295,17 @@ void MultiTouchInputMapper::sync(nsecs_t when) {
mAccumulator.clear();
}
-void MultiTouchInputMapper::configureAxes() {
- TouchInputMapper::configureAxes();
-
- // The axes are aliased to take into account the manner in which they are presented
- // as part of the TouchData during the sync.
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_X, & mAxes.x);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_Y, & mAxes.y);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MAJOR, & mAxes.touchMajor);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MINOR, & mAxes.touchMinor);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MAJOR, & mAxes.toolMajor);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MINOR, & mAxes.toolMinor);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_ORIENTATION, & mAxes.orientation);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_PRESSURE, & mAxes.pressure);
-
- if (! mAxes.touchMinor.valid) {
- mAxes.touchMinor = mAxes.touchMajor;
- }
-
- if (! mAxes.toolMinor.valid) {
- mAxes.toolMinor = mAxes.toolMajor;
- }
-
- if (! mAxes.pressure.valid) {
- mAxes.pressure = mAxes.touchMajor;
- }
+void MultiTouchInputMapper::configureRawAxes() {
+ TouchInputMapper::configureRawAxes();
- mAxes.size = mAxes.toolMajor;
+ getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_X, & mRawAxes.x);
+ getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_Y, & mRawAxes.y);
+ getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MAJOR, & mRawAxes.touchMajor);
+ getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MINOR, & mRawAxes.touchMinor);
+ getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MAJOR, & mRawAxes.toolMajor);
+ getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MINOR, & mRawAxes.toolMinor);
+ getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_ORIENTATION, & mRawAxes.orientation);
+ getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_PRESSURE, & mRawAxes.pressure);
}
diff --git a/media/libstagefright/rtsp/ARTPConnection.cpp b/media/libstagefright/rtsp/ARTPConnection.cpp
index 42a22b71d9e4..12f8f323b61a 100644
--- a/media/libstagefright/rtsp/ARTPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTPConnection.cpp
@@ -263,6 +263,10 @@ void ARTPConnection::onPollStreams() {
}
}
+ if (maxSocket == -1) {
+ return;
+ }
+
int res = select(maxSocket + 1, &rs, NULL, NULL, &tv);
CHECK_GE(res, 0);
@@ -292,6 +296,10 @@ void ARTPConnection::onPollStreams() {
it != mStreams.end(); ++it) {
StreamInfo *s = &*it;
+ if (s->mIsInjected) {
+ continue;
+ }
+
if (s->mNumRTCPPacketsReceived == 0) {
// We have never received any RTCP packets on this stream,
// we don't even know where to send a report.
diff --git a/media/libstagefright/rtsp/ARTPSession.cpp b/media/libstagefright/rtsp/ARTPSession.cpp
index d2c56f70ff0c..f60c1a9eea59 100644
--- a/media/libstagefright/rtsp/ARTPSession.cpp
+++ b/media/libstagefright/rtsp/ARTPSession.cpp
@@ -167,6 +167,7 @@ void ARTPSession::onMessageReceived(const sp<AMessage> &msg) {
#endif
accessUnit->meta()->setInt64("ntp-time", ntpTime);
+ accessUnit->meta()->setInt64("timeUs", 0);
#if 0
int32_t damaged;
diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h
index 7c06db3077e0..3d8d86bf6cf5 100644
--- a/media/libstagefright/rtsp/MyHandler.h
+++ b/media/libstagefright/rtsp/MyHandler.h
@@ -31,8 +31,6 @@
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/MediaErrors.h>
-#define USE_TCP_INTERLEAVED 0
-
// If no access units are received within 3 secs, assume that the rtp
// stream has ended and signal end of stream.
static int64_t kAccessUnitTimeoutUs = 3000000ll;
@@ -83,7 +81,8 @@ struct MyHandler : public AHandler {
mFirstAccessUnit(true),
mFirstAccessUnitNTP(0),
mNumAccessUnitsReceived(0),
- mCheckPending(false) {
+ mCheckPending(false),
+ mTryTCPInterleaving(false) {
mNetLooper->setName("rtsp net");
mNetLooper->start(false /* runOnCallingThread */,
false /* canCallJava */,
@@ -158,7 +157,13 @@ struct MyHandler : public AHandler {
case 'disc':
{
- (new AMessage('quit', id()))->post();
+ int32_t reconnect;
+ if (msg->findInt32("reconnect", &reconnect) && reconnect) {
+ sp<AMessage> reply = new AMessage('conn', id());
+ mConn->connect(mSessionURL.c_str(), reply);
+ } else {
+ (new AMessage('quit', id()))->post();
+ }
break;
}
@@ -325,10 +330,6 @@ struct MyHandler : public AHandler {
parsePlayResponse(response);
- mDoneMsg->setInt32("result", OK);
- mDoneMsg->post();
- mDoneMsg = NULL;
-
sp<AMessage> timeout = new AMessage('tiou', id());
timeout->post(kStartupTimeoutUs);
} else {
@@ -342,12 +343,26 @@ struct MyHandler : public AHandler {
case 'abor':
{
for (size_t i = 0; i < mTracks.size(); ++i) {
- mTracks.editItemAt(i).mPacketSource->signalEOS(
- ERROR_END_OF_STREAM);
+ TrackInfo *info = &mTracks.editItemAt(i);
+
+ info->mPacketSource->signalEOS(ERROR_END_OF_STREAM);
+
+ if (!info->mUsingInterleavedTCP) {
+ mRTPConn->removeStream(info->mRTPSocket, info->mRTCPSocket);
+
+ close(info->mRTPSocket);
+ close(info->mRTCPSocket);
+ }
}
+ mTracks.clear();
sp<AMessage> reply = new AMessage('tear', id());
+ int32_t reconnect;
+ if (msg->findInt32("reconnect", &reconnect) && reconnect) {
+ reply->setInt32("reconnect", true);
+ }
+
AString request;
request = "TEARDOWN ";
@@ -374,6 +389,12 @@ struct MyHandler : public AHandler {
<< result << " (" << strerror(-result) << ")";
sp<AMessage> reply = new AMessage('disc', id());
+
+ int32_t reconnect;
+ if (msg->findInt32("reconnect", &reconnect) && reconnect) {
+ reply->setInt32("reconnect", true);
+ }
+
mConn->disconnect(reply);
break;
}
@@ -414,6 +435,11 @@ struct MyHandler : public AHandler {
size_t trackIndex;
CHECK(msg->findSize("track-index", &trackIndex));
+ if (trackIndex >= mTracks.size()) {
+ LOG(ERROR) << "late packets ignored.";
+ break;
+ }
+
TrackInfo *track = &mTracks.editItemAt(trackIndex);
int32_t eos;
@@ -457,6 +483,10 @@ struct MyHandler : public AHandler {
}
if (mFirstAccessUnit) {
+ mDoneMsg->setInt32("result", OK);
+ mDoneMsg->post();
+ mDoneMsg = NULL;
+
mFirstAccessUnit = false;
mFirstAccessUnitNTP = ntpTime;
}
@@ -583,8 +613,19 @@ struct MyHandler : public AHandler {
case 'tiou':
{
if (mFirstAccessUnit) {
- LOG(WARNING) << "Never received any data, disconnecting.";
- (new AMessage('abor', id()))->post();
+ if (mTryTCPInterleaving) {
+ LOG(WARNING) << "Never received any data, disconnecting.";
+ (new AMessage('abor', id()))->post();
+ } else {
+ LOG(WARNING)
+ << "Never received any data, switching transports.";
+
+ mTryTCPInterleaving = true;
+
+ sp<AMessage> msg = new AMessage('abor', id());
+ msg->setInt32("reconnect", true);
+ msg->post();
+ }
}
break;
}
@@ -705,6 +746,7 @@ private:
uint64_t mFirstAccessUnitNTP;
int64_t mNumAccessUnitsReceived;
bool mCheckPending;
+ bool mTryTCPInterleaving;
struct TrackInfo {
AString mURL;
@@ -723,6 +765,7 @@ private:
void setupTrack(size_t index) {
sp<APacketSource> source =
new APacketSource(mSessionDesc, index);
+
if (source->initCheck() != OK) {
LOG(WARNING) << "Unsupported format. Ignoring track #"
<< index << ".";
@@ -754,26 +797,26 @@ private:
request.append(trackURL);
request.append(" RTSP/1.0\r\n");
-#if USE_TCP_INTERLEAVED
- size_t interleaveIndex = 2 * (mTracks.size() - 1);
- info->mUsingInterleavedTCP = true;
- info->mRTPSocket = interleaveIndex;
- info->mRTCPSocket = interleaveIndex + 1;
-
- request.append("Transport: RTP/AVP/TCP;interleaved=");
- request.append(interleaveIndex);
- request.append("-");
- request.append(interleaveIndex + 1);
-#else
- unsigned rtpPort;
- ARTPConnection::MakePortPair(
- &info->mRTPSocket, &info->mRTCPSocket, &rtpPort);
-
- request.append("Transport: RTP/AVP/UDP;unicast;client_port=");
- request.append(rtpPort);
- request.append("-");
- request.append(rtpPort + 1);
-#endif
+ if (mTryTCPInterleaving) {
+ size_t interleaveIndex = 2 * (mTracks.size() - 1);
+ info->mUsingInterleavedTCP = true;
+ info->mRTPSocket = interleaveIndex;
+ info->mRTCPSocket = interleaveIndex + 1;
+
+ request.append("Transport: RTP/AVP/TCP;interleaved=");
+ request.append(interleaveIndex);
+ request.append("-");
+ request.append(interleaveIndex + 1);
+ } else {
+ unsigned rtpPort;
+ ARTPConnection::MakePortPair(
+ &info->mRTPSocket, &info->mRTCPSocket, &rtpPort);
+
+ request.append("Transport: RTP/AVP/UDP;unicast;client_port=");
+ request.append(rtpPort);
+ request.append("-");
+ request.append(rtpPort + 1);
+ }
request.append("\r\n");
diff --git a/native/include/android/input.h b/native/include/android/input.h
index 243c33c3a714..d9486e5a7170 100644
--- a/native/include/android/input.h
+++ b/native/include/android/input.h
@@ -718,8 +718,6 @@ int32_t AInputDevice_getKeyboardType(AInputDevice* device);
int32_t AInputDevice_getMotionRange(AInputDevice* device, int32_t rangeType,
float* outMin, float* outMax, float* outFlat, float* outFuzz);
-//TODO hasKey, keymap stuff, etc...
-
#ifdef __cplusplus
}
#endif
diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags
index 9ccc5a95633b..72bd77666aff 100644
--- a/packages/SystemUI/proguard.flags
+++ b/packages/SystemUI/proguard.flags
@@ -1,4 +1,5 @@
-keep class com.android.systemui.statusbar.tablet.TabletStatusBarService {
public void notificationIconsClicked(android.view.View);
public void systemInfoClicked(android.view.View);
+ public void recentButtonClicked(android.view.View);
}
diff --git a/packages/SystemUI/res/drawable/status_bar_recent.xml b/packages/SystemUI/res/drawable/status_bar_recent.xml
new file mode 100755
index 000000000000..d708455f0cb5
--- /dev/null
+++ b/packages/SystemUI/res/drawable/status_bar_recent.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true" android:drawable="@drawable/status_bar_recent_pressed" />
+ <item android:drawable="@drawable/status_bar_recent_default" />
+</selector>
+
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar.xml b/packages/SystemUI/res/layout-xlarge/status_bar.xml
index 481bcde0a500..a0c2c9504004 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar.xml
@@ -118,12 +118,21 @@
<com.android.systemui.statusbar.KeyButtonView android:id="@+id/menu"
android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:layout_toLeftOf="@+id/home"
+ android:layout_toLeftOf="@+id/recent"
android:src="@drawable/status_bar_menu"
android:paddingLeft="4dip"
android:paddingRight="4dip"
systemui:keyCode="82"
/>
+ <Button android:id="@+id/recent"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_toLeftOf="@+id/home"
+ android:background="@drawable/status_bar_recent"
+ android:paddingLeft="4dip"
+ android:paddingRight="4dip"
+ android:onClick="recentButtonClicked"
+ />
<com.android.systemui.statusbar.KeyButtonView android:id="@+id/home"
android:layout_width="wrap_content"
android:layout_height="match_parent"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java
index dfa2d10ae358..a32b01fd8f9e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java
@@ -78,7 +78,7 @@ import com.android.systemui.R;
public class SystemPanel extends LinearLayout {
private static final String TAG = "SystemPanel";
private static final boolean DEBUG = TabletStatusBarService.DEBUG;
- private static final boolean DEBUG_SIGNAL = true;
+ private static final boolean DEBUG_SIGNAL = false;
private static final int MINIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_DIM + 5;
private static final int MAXIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_ON;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
index 087671ac7814..312c5f44a807 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
@@ -22,6 +22,7 @@ import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.app.StatusBarManager;
+import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
@@ -495,6 +496,15 @@ public class TabletStatusBarService extends StatusBarService {
mHandler.sendEmptyMessage(msg);
}
+ public void recentButtonClicked(View v) {
+ if (DEBUG) Slog.d(TAG, "clicked recent apps");
+ Intent intent = new Intent();
+ intent.setClass(this, RecentApplicationsActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+ startActivity(intent);
+ }
+
/**
* Cancel this notification and tell the status bar service about the failure. Hold no locks.
*/
diff --git a/services/java/com/android/server/BootReceiver.java b/services/java/com/android/server/BootReceiver.java
index d15a05832db2..b9ff8d0ce7bb 100644
--- a/services/java/com/android/server/BootReceiver.java
+++ b/services/java/com/android/server/BootReceiver.java
@@ -167,7 +167,7 @@ public class BootReceiver extends BroadcastReceiver {
if (lastTime == fileTime) return; // Already logged this particular file
// TODO: move all these SharedPreferences Editor commits
// outside this function to the end of logBootEvents
- prefs.edit().putLong(filename, fileTime).startCommit();
+ prefs.edit().putLong(filename, fileTime).apply();
}
Slog.i(TAG, "Copying " + filename + " to DropBox (" + tag + ")");
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 57e8e021fe20..6f23805c0e9a 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -26,7 +26,7 @@ import android.net.ConnectivityManager;
import android.net.IConnectivityManager;
import android.net.MobileDataStateTracker;
import android.net.NetworkInfo;
-import android.net.NetworkProperties;
+import android.net.LinkProperties;
import android.net.NetworkStateTracker;
import android.net.NetworkUtils;
import android.net.wifi.WifiStateTracker;
@@ -756,7 +756,6 @@ public class ConnectivityService extends IConnectivityManager.Stub {
* specified host is to be routed
* @param hostAddress the IP address of the host to which the route is
* desired
- * todo - deprecate (only v4!)
* @return {@code true} on success, {@code false} on failure
*/
public boolean requestRouteToHost(int networkType, int hostAddress) {
@@ -813,7 +812,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
return false;
}
- NetworkProperties p = nt.getNetworkProperties();
+ LinkProperties p = nt.getLinkProperties();
if (p == null) return false;
String interfaceName = p.getInterfaceName();
@@ -1258,7 +1257,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
private void addPrivateDnsRoutes(NetworkStateTracker nt) {
boolean privateDnsRouteSet = nt.isPrivateDnsRouteSet();
- NetworkProperties p = nt.getNetworkProperties();
+ LinkProperties p = nt.getLinkProperties();
if (p == null) return;
String interfaceName = p.getInterfaceName();
@@ -1279,7 +1278,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
private void removePrivateDnsRoutes(NetworkStateTracker nt) {
// TODO - we should do this explicitly but the NetUtils api doesnt
// support this yet - must remove all. No worse than before
- NetworkProperties p = nt.getNetworkProperties();
+ LinkProperties p = nt.getLinkProperties();
if (p == null) return;
String interfaceName = p.getInterfaceName();
boolean privateDnsRouteSet = nt.isPrivateDnsRouteSet();
@@ -1295,7 +1294,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
private void addDefaultRoute(NetworkStateTracker nt) {
- NetworkProperties p = nt.getNetworkProperties();
+ LinkProperties p = nt.getLinkProperties();
if (p == null) return;
String interfaceName = p.getInterfaceName();
InetAddress defaultGatewayAddr = p.getGateway();
@@ -1311,7 +1310,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
public void removeDefaultRoute(NetworkStateTracker nt) {
- NetworkProperties p = nt.getNetworkProperties();
+ LinkProperties p = nt.getLinkProperties();
if (p == null) return;
String interfaceName = p.getInterfaceName();
@@ -1410,7 +1409,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
NetworkStateTracker nt = mNetTrackers[i];
if (nt.getNetworkInfo().isConnected() &&
!nt.isTeardownRequested()) {
- NetworkProperties p = nt.getNetworkProperties();
+ LinkProperties p = nt.getLinkProperties();
if (p == null) continue;
List pids = mNetRequestersPids[i];
for (int j=0; j<pids.size(); j++) {
@@ -1465,7 +1464,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
// add default net's dns entries
NetworkStateTracker nt = mNetTrackers[netType];
if (nt != null && nt.getNetworkInfo().isConnected() && !nt.isTeardownRequested()) {
- NetworkProperties p = nt.getNetworkProperties();
+ LinkProperties p = nt.getLinkProperties();
if (p == null) return;
Collection<InetAddress> dnses = p.getDnses();
if (mNetAttributes[netType].isDefault()) {
diff --git a/services/java/com/android/server/InputManager.java b/services/java/com/android/server/InputManager.java
index f330d40a80f6..314dd8a70a8a 100644
--- a/services/java/com/android/server/InputManager.java
+++ b/services/java/com/android/server/InputManager.java
@@ -30,6 +30,7 @@ import android.os.SystemProperties;
import android.util.Slog;
import android.util.Xml;
import android.view.InputChannel;
+import android.view.InputDevice;
import android.view.InputEvent;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -45,6 +46,7 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Properties;
/*
* Wraps the C++ InputManager and provides its callbacks.
@@ -82,6 +84,8 @@ public class InputManager {
private static native void nativeSetInputDispatchMode(boolean enabled, boolean frozen);
private static native void nativeSetFocusedApplication(InputApplication application);
private static native void nativePreemptInputDispatch();
+ private static native InputDevice nativeGetInputDevice(int deviceId);
+ private static native int[] nativeGetInputDeviceIds();
private static native String nativeDump();
// Input event injection constants defined in InputDispatcher.h.
@@ -302,6 +306,23 @@ public class InputManager {
return nativeInjectInputEvent(event, injectorPid, injectorUid, syncMode, timeoutMillis);
}
+ /**
+ * Gets information about the input device with the specified id.
+ * @param id The device id.
+ * @return The input device or null if not found.
+ */
+ public InputDevice getInputDevice(int deviceId) {
+ return nativeGetInputDevice(deviceId);
+ }
+
+ /**
+ * Gets the ids of all input devices in the system.
+ * @return The input device ids.
+ */
+ public int[] getInputDeviceIds() {
+ return nativeGetInputDeviceIds();
+ }
+
public void setInputWindows(InputWindow[] windows) {
nativeSetInputWindows(windows);
}
@@ -335,6 +356,11 @@ public class InputManager {
public int height;
}
+ private static final class InputDeviceCalibration {
+ public String[] keys;
+ public String[] values;
+ }
+
/*
* Callbacks from native.
*/
@@ -343,6 +369,7 @@ public class InputManager {
private static final boolean DEBUG_VIRTUAL_KEYS = false;
private static final String EXCLUDED_DEVICES_PATH = "etc/excluded-input-devices.xml";
+ private static final String CALIBRATION_DIR_PATH = "usr/idc/";
@SuppressWarnings("unused")
public void virtualKeyDownFeedback() {
@@ -438,8 +465,8 @@ public class InputManager {
final int N = it.length-6;
for (int i=0; i<=N; i+=6) {
if (!"0x01".equals(it[i])) {
- Slog.w(TAG, "Unknown virtual key type at elem #" + i
- + ": " + it[i]);
+ Slog.w(TAG, "Unknown virtual key type at elem #"
+ + i + ": " + it[i] + " for device " + deviceName);
continue;
}
try {
@@ -455,22 +482,47 @@ public class InputManager {
+ key.height);
keys.add(key);
} catch (NumberFormatException e) {
- Slog.w(TAG, "Bad number at region " + i + " in: "
- + str, e);
+ Slog.w(TAG, "Bad number in virtual key definition at region "
+ + i + " in: " + str + " for device " + deviceName, e);
}
}
}
br.close();
} catch (FileNotFoundException e) {
- Slog.i(TAG, "No virtual keys found");
+ Slog.i(TAG, "No virtual keys found for device " + deviceName + ".");
} catch (IOException e) {
- Slog.w(TAG, "Error reading virtual keys", e);
+ Slog.w(TAG, "Error reading virtual keys for device " + deviceName + ".", e);
}
return keys.toArray(new VirtualKeyDefinition[keys.size()]);
}
@SuppressWarnings("unused")
+ public InputDeviceCalibration getInputDeviceCalibration(String deviceName) {
+ // Calibration is specified as a sequence of colon-delimited key value pairs.
+ Properties properties = new Properties();
+ File calibrationFile = new File(Environment.getRootDirectory(),
+ CALIBRATION_DIR_PATH + deviceName + ".idc");
+ if (calibrationFile.exists()) {
+ try {
+ properties.load(new FileInputStream(calibrationFile));
+ } catch (IOException ex) {
+ Slog.w(TAG, "Error reading input device calibration properties for device "
+ + deviceName + " from " + calibrationFile + ".", ex);
+ }
+ } else {
+ Slog.i(TAG, "No input device calibration properties found for device "
+ + deviceName + ".");
+ return null;
+ }
+
+ InputDeviceCalibration calibration = new InputDeviceCalibration();
+ calibration.keys = properties.keySet().toArray(new String[properties.size()]);
+ calibration.values = properties.values().toArray(new String[properties.size()]);
+ return calibration;
+ }
+
+ @SuppressWarnings("unused")
public String[] getExcludedDeviceNames() {
ArrayList<String> names = new ArrayList<String>();
diff --git a/services/java/com/android/server/TelephonyRegistry.java b/services/java/com/android/server/TelephonyRegistry.java
index 73234df297ab..0a90a4cde285 100644
--- a/services/java/com/android/server/TelephonyRegistry.java
+++ b/services/java/com/android/server/TelephonyRegistry.java
@@ -19,7 +19,7 @@ package com.android.server;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
-import android.net.NetworkProperties;
+import android.net.LinkProperties;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
@@ -92,7 +92,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
private ArrayList<String> mConnectedApns;
- private NetworkProperties mDataConnectionProperties;
+ private LinkProperties mDataConnectionProperties;
private Bundle mCellLocation = new Bundle();
@@ -355,7 +355,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
public void notifyDataConnection(int state, boolean isDataConnectivityPossible,
- String reason, String apn, String apnType, NetworkProperties networkProperties,
+ String reason, String apn, String apnType, LinkProperties linkProperties,
int networkType) {
if (!checkNotifyPermission("notifyDataConnection()" )) {
return;
@@ -383,7 +383,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
mDataConnectionPossible = isDataConnectivityPossible;
mDataConnectionReason = reason;
mDataConnectionApn = apn;
- mDataConnectionProperties = networkProperties;
+ mDataConnectionProperties = linkProperties;
if (mDataConnectionNetworkType != networkType) {
mDataConnectionNetworkType = networkType;
modified = true;
@@ -403,7 +403,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
}
broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn,
- apnType, networkProperties);
+ apnType, linkProperties);
}
public void notifyDataConnectionFailed(String reason, String apnType) {
@@ -564,7 +564,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
private void broadcastDataConnectionStateChanged(int state,
boolean isDataConnectivityPossible,
- String reason, String apn, String apnType, NetworkProperties networkProperties) {
+ String reason, String apn, String apnType, LinkProperties linkProperties) {
// Note: not reporting to the battery stats service here, because the
// status bar takes care of that after taking into account all of the
// required info.
@@ -577,9 +577,9 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
if (reason != null) {
intent.putExtra(Phone.STATE_CHANGE_REASON_KEY, reason);
}
- if (networkProperties != null) {
- intent.putExtra(Phone.DATA_NETWORK_PROPERTIES_KEY, networkProperties);
- NetworkInterface iface = networkProperties.getInterface();
+ if (linkProperties != null) {
+ intent.putExtra(Phone.DATA_LINK_PROPERTIES_KEY, linkProperties);
+ NetworkInterface iface = linkProperties.getInterface();
if (iface != null) {
intent.putExtra(Phone.DATA_IFACE_NAME_KEY, iface.getName());
}
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 4407e96490e4..79bde7c2523f 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -4383,6 +4383,14 @@ public class WindowManagerService extends IWindowManager.Stub
return mInputManager.monitorInput(inputChannelName);
}
+ public InputDevice getInputDevice(int deviceId) {
+ return mInputManager.getInputDevice(deviceId);
+ }
+
+ public int[] getInputDeviceIds() {
+ return mInputManager.getInputDeviceIds();
+ }
+
public void enableScreenAfterBoot() {
synchronized(mWindowMap) {
if (mSystemBooted) {
diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp
index 3addc0d2e208..a237ee94bfb3 100644
--- a/services/jni/com_android_server_InputManager.cpp
+++ b/services/jni/com_android_server_InputManager.cpp
@@ -138,6 +138,7 @@ static struct {
jmethodID filterTouchEvents;
jmethodID filterJumpyTouchEvents;
jmethodID getVirtualKeyDefinitions;
+ jmethodID getInputDeviceCalibration;
jmethodID getExcludedDeviceNames;
jmethodID getMaxEventsPerSecond;
} gCallbacksClassInfo;
@@ -155,6 +156,13 @@ static struct {
static struct {
jclass clazz;
+ jfieldID keys;
+ jfieldID values;
+} gInputDeviceCalibrationClassInfo;
+
+static struct {
+ jclass clazz;
+
jfieldID inputChannel;
jfieldID layoutParamsFlags;
jfieldID layoutParamsType;
@@ -189,6 +197,19 @@ static struct {
jclass clazz;
} gMotionEventClassInfo;
+static struct {
+ jclass clazz;
+
+ jmethodID ctor;
+ jmethodID addMotionRange;
+
+ jfieldID mId;
+ jfieldID mName;
+ jfieldID mSources;
+ jfieldID mKeyboardType;
+ jfieldID mMotionRanges;
+} gInputDeviceClassInfo;
+
// ----------------------------------------------------------------------------
static inline nsecs_t now() {
@@ -235,7 +256,9 @@ public:
virtual bool filterTouchEvents();
virtual bool filterJumpyTouchEvents();
virtual void getVirtualKeyDefinitions(const String8& deviceName,
- Vector<InputReaderPolicyInterface::VirtualKeyDefinition>& outVirtualKeyDefinitions);
+ Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions);
+ virtual void getInputDeviceCalibration(const String8& deviceName,
+ InputDeviceCalibration& outCalibration);
virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames);
/* --- InputDispatcherPolicyInterface implementation --- */
@@ -761,7 +784,9 @@ bool NativeInputManager::filterJumpyTouchEvents() {
}
void NativeInputManager::getVirtualKeyDefinitions(const String8& deviceName,
- Vector<InputReaderPolicyInterface::VirtualKeyDefinition>& outVirtualKeyDefinitions) {
+ Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions) {
+ outVirtualKeyDefinitions.clear();
+
JNIEnv* env = jniEnv();
jstring deviceNameStr = env->NewStringUTF(deviceName.string());
@@ -793,7 +818,51 @@ void NativeInputManager::getVirtualKeyDefinitions(const String8& deviceName,
}
}
+void NativeInputManager::getInputDeviceCalibration(const String8& deviceName,
+ InputDeviceCalibration& outCalibration) {
+ outCalibration.clear();
+
+ JNIEnv* env = jniEnv();
+
+ jstring deviceNameStr = env->NewStringUTF(deviceName.string());
+ if (! checkAndClearExceptionFromCallback(env, "getInputDeviceCalibration")) {
+ jobject result = env->CallObjectMethod(mCallbacksObj,
+ gCallbacksClassInfo.getInputDeviceCalibration, deviceNameStr);
+ if (! checkAndClearExceptionFromCallback(env, "getInputDeviceCalibration") && result) {
+ jobjectArray keys = jobjectArray(env->GetObjectField(result,
+ gInputDeviceCalibrationClassInfo.keys));
+ jobjectArray values = jobjectArray(env->GetObjectField(result,
+ gInputDeviceCalibrationClassInfo.values));
+
+ jsize length = env->GetArrayLength(keys);
+ for (jsize i = 0; i < length; i++) {
+ jstring keyStr = jstring(env->GetObjectArrayElement(keys, i));
+ jstring valueStr = jstring(env->GetObjectArrayElement(values, i));
+
+ const char* keyChars = env->GetStringUTFChars(keyStr, NULL);
+ String8 key(keyChars);
+ env->ReleaseStringUTFChars(keyStr, keyChars);
+
+ const char* valueChars = env->GetStringUTFChars(valueStr, NULL);
+ String8 value(valueChars);
+ env->ReleaseStringUTFChars(valueStr, valueChars);
+
+ outCalibration.addProperty(key, value);
+
+ env->DeleteLocalRef(keyStr);
+ env->DeleteLocalRef(valueStr);
+ }
+ env->DeleteLocalRef(keys);
+ env->DeleteLocalRef(values);
+ env->DeleteLocalRef(result);
+ }
+ env->DeleteLocalRef(deviceNameStr);
+ }
+}
+
void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
+ outExcludedDeviceNames.clear();
+
JNIEnv* env = jniEnv();
jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacksObj,
@@ -2199,6 +2268,66 @@ static void android_server_InputManager_nativePreemptInputDispatch(JNIEnv* env,
gNativeInputManager->preemptInputDispatch();
}
+static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
+ jclass clazz, jint deviceId) {
+ if (checkInputManagerUnitialized(env)) {
+ return NULL;
+ }
+
+ InputDeviceInfo deviceInfo;
+ status_t status = gNativeInputManager->getInputManager()->getInputDeviceInfo(
+ deviceId, & deviceInfo);
+ if (status) {
+ return NULL;
+ }
+
+ jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor);
+ if (! deviceObj) {
+ return NULL;
+ }
+
+ jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string());
+ if (! deviceNameObj) {
+ return NULL;
+ }
+
+ env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId());
+ env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj);
+ env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
+ env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
+
+ const KeyedVector<int, InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
+ for (size_t i = 0; i < ranges.size(); i++) {
+ int rangeType = ranges.keyAt(i);
+ const InputDeviceInfo::MotionRange& range = ranges.valueAt(i);
+ env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
+ rangeType, range.min, range.max, range.flat, range.fuzz);
+ if (env->ExceptionCheck()) {
+ return NULL;
+ }
+ }
+
+ return deviceObj;
+}
+
+static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
+ jclass clazz) {
+ if (checkInputManagerUnitialized(env)) {
+ return NULL;
+ }
+
+ Vector<int> deviceIds;
+ gNativeInputManager->getInputManager()->getInputDeviceIds(deviceIds);
+
+ jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
+ if (! deviceIdsObj) {
+ return NULL;
+ }
+
+ env->SetIntArrayRegion(deviceIdsObj, 0, deviceIds.size(), deviceIds.array());
+ return deviceIdsObj;
+}
+
static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
if (checkInputManagerUnitialized(env)) {
return NULL;
@@ -2242,6 +2371,10 @@ static JNINativeMethod gInputManagerMethods[] = {
(void*) android_server_InputManager_nativeSetInputDispatchMode },
{ "nativePreemptInputDispatch", "()V",
(void*) android_server_InputManager_nativePreemptInputDispatch },
+ { "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
+ (void*) android_server_InputManager_nativeGetInputDevice },
+ { "nativeGetInputDeviceIds", "()[I",
+ (void*) android_server_InputManager_nativeGetInputDeviceIds },
{ "nativeDump", "()Ljava/lang/String;",
(void*) android_server_InputManager_nativeDump },
};
@@ -2311,6 +2444,10 @@ int register_android_server_InputManager(JNIEnv* env) {
"getVirtualKeyDefinitions",
"(Ljava/lang/String;)[Lcom/android/server/InputManager$VirtualKeyDefinition;");
+ GET_METHOD_ID(gCallbacksClassInfo.getInputDeviceCalibration, gCallbacksClassInfo.clazz,
+ "getInputDeviceCalibration",
+ "(Ljava/lang/String;)Lcom/android/server/InputManager$InputDeviceCalibration;");
+
GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, gCallbacksClassInfo.clazz,
"getExcludedDeviceNames", "()[Ljava/lang/String;");
@@ -2337,6 +2474,17 @@ int register_android_server_InputManager(JNIEnv* env) {
GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.height, gVirtualKeyDefinitionClassInfo.clazz,
"height", "I");
+ // InputDeviceCalibration
+
+ FIND_CLASS(gInputDeviceCalibrationClassInfo.clazz,
+ "com/android/server/InputManager$InputDeviceCalibration");
+
+ GET_FIELD_ID(gInputDeviceCalibrationClassInfo.keys, gInputDeviceCalibrationClassInfo.clazz,
+ "keys", "[Ljava/lang/String;");
+
+ GET_FIELD_ID(gInputDeviceCalibrationClassInfo.values, gInputDeviceCalibrationClassInfo.clazz,
+ "values", "[Ljava/lang/String;");
+
// InputWindow
FIND_CLASS(gInputWindowClassInfo.clazz, "com/android/server/InputWindow");
@@ -2407,10 +2555,35 @@ int register_android_server_InputManager(JNIEnv* env) {
FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
- // MotionEVent
+ // MotionEvent
FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
+ // InputDevice
+
+ FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
+
+ GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
+ "<init>", "()V");
+
+ GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
+ "addMotionRange", "(IFFFF)V");
+
+ GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
+ "mId", "I");
+
+ GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz,
+ "mName", "Ljava/lang/String;");
+
+ GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz,
+ "mSources", "I");
+
+ GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz,
+ "mKeyboardType", "I");
+
+ GET_FIELD_ID(gInputDeviceClassInfo.mMotionRanges, gInputDeviceClassInfo.clazz,
+ "mMotionRanges", "[Landroid/view/InputDevice$MotionRange;");
+
return 0;
}
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index b0fa0f51a24c..4f2d90f06761 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -1374,7 +1374,7 @@ public class PhoneNumberUtils
PhoneNumberUtil util = PhoneNumberUtil.getInstance();
String result = null;
try {
- PhoneNumber pn = util.parse(phoneNumber, defaultCountryIso);
+ PhoneNumber pn = util.parseAndKeepRawInput(phoneNumber, defaultCountryIso);
result = util.formatInOriginalFormat(pn, defaultCountryIso);
} catch (NumberParseException e) {
}
@@ -1382,6 +1382,50 @@ public class PhoneNumberUtils
}
/**
+ * Format the phone number only if the given number hasn't been formatted.
+ * <p>
+ * The number which has only dailable character is treated as not being
+ * formatted.
+ *
+ * @param phoneNumber
+ * the number to be formatted.
+ * @param phoneNumberE164
+ * the E164 format number whose country code is used if the given
+ * phoneNumber doesn't have the country code.
+ * @param defaultCountryIso
+ * the ISO 3166-1 two letters country code whose convention will
+ * be used if the phoneNumberE164 is null or invalid.
+ * @return the formatted number if the given number has been formatted,
+ * otherwise, return the given number.
+ *
+ * @hide
+ */
+ public static String formatNumber(
+ String phoneNumber, String phoneNumberE164, String defaultCountryIso) {
+ int len = phoneNumber.length();
+ for (int i = 0; i < len; i++) {
+ if (!isDialable(phoneNumber.charAt(i))) {
+ return phoneNumber;
+ }
+ }
+ PhoneNumberUtil util = PhoneNumberUtil.getInstance();
+ // Get the country code from phoneNumberE164
+ if (phoneNumberE164 != null && phoneNumberE164.length() >= 2
+ && phoneNumberE164.charAt(0) == '+') {
+ try {
+ PhoneNumber pn = util.parse(phoneNumberE164, defaultCountryIso);
+ String regionCode = util.getRegionCodeForNumber(pn);
+ if (!TextUtils.isEmpty(regionCode)) {
+ defaultCountryIso = regionCode;
+ }
+ } catch (NumberParseException e) {
+ }
+ }
+ String result = formatNumber(phoneNumber, defaultCountryIso);
+ return result != null ? result : phoneNumber;
+ }
+
+ /**
* Normalize a phone number by removing the characters other than digits. If
* the given number has keypad letters, the letters will be converted to
* digits first.
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index 7e722cbeb51e..521d90c5c141 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -21,7 +21,7 @@ import com.android.internal.telephony.gsm.ApnSetting;
import com.android.internal.util.HierarchicalState;
import com.android.internal.util.HierarchicalStateMachine;
-import android.net.NetworkProperties;
+import android.net.LinkProperties;
import android.os.AsyncResult;
import android.os.Message;
import android.os.SystemProperties;
@@ -261,7 +261,7 @@ public abstract class DataConnection extends HierarchicalStateMachine {
protected int mTag;
protected PhoneBase phone;
protected int cid;
- protected NetworkProperties mNetworkProperties = new NetworkProperties();
+ protected LinkProperties mLinkProperties = new LinkProperties();
protected long createTime;
protected long lastFailTime;
protected FailCause lastFailCause;
@@ -378,7 +378,7 @@ public abstract class DataConnection extends HierarchicalStateMachine {
this.lastFailTime = -1;
this.lastFailCause = FailCause.NONE;
- mNetworkProperties.clear();
+ mLinkProperties = new LinkProperties();
}
/**
@@ -416,7 +416,7 @@ public abstract class DataConnection extends HierarchicalStateMachine {
// Start with clean network properties and if we have
// a failure we'll clear again at the bottom of this code.
- mNetworkProperties.clear();
+ LinkProperties linkProperties = new LinkProperties();
if (response.length >= 2) {
cid = Integer.parseInt(response[0]);
String interfaceName = response[1];
@@ -425,23 +425,23 @@ public abstract class DataConnection extends HierarchicalStateMachine {
try {
String prefix = "net." + interfaceName + ".";
- mNetworkProperties.setInterface(NetworkInterface.getByName(interfaceName));
+ linkProperties.setInterface(NetworkInterface.getByName(interfaceName));
// TODO: Get gateway and dns via RIL interface not property?
String gatewayAddress = SystemProperties.get(prefix + "gw");
- mNetworkProperties.setGateway(InetAddress.getByName(gatewayAddress));
+ linkProperties.setGateway(InetAddress.getByName(gatewayAddress));
if (response.length > 2) {
String ipAddress = response[2];
- mNetworkProperties.addAddress(InetAddress.getByName(ipAddress));
+ linkProperties.addAddress(InetAddress.getByName(ipAddress));
// TODO: Get gateway and dns via RIL interface not property?
String dnsServers[] = new String[2];
dnsServers[0] = SystemProperties.get(prefix + "dns1");
dnsServers[1] = SystemProperties.get(prefix + "dns2");
if (isDnsOk(dnsServers)) {
- mNetworkProperties.addDns(InetAddress.getByName(dnsServers[0]));
- mNetworkProperties.addDns(InetAddress.getByName(dnsServers[1]));
+ linkProperties.addDns(InetAddress.getByName(dnsServers[0]));
+ linkProperties.addDns(InetAddress.getByName(dnsServers[1]));
} else {
result = SetupResult.ERR_BadDns;
}
@@ -463,15 +463,16 @@ public abstract class DataConnection extends HierarchicalStateMachine {
// An error occurred so clear properties
if (result != SetupResult.SUCCESS) {
- log("onSetupCompleted with an error clearing NetworkProperties");
- mNetworkProperties.clear();
+ log("onSetupCompleted with an error clearing LinkProperties");
+ linkProperties.clear();
}
+ mLinkProperties = linkProperties;
}
if (DBG) {
log("DataConnection setup result='" + result + "' on cid=" + cid);
if (result == SetupResult.SUCCESS) {
- log("NetworkProperties: " + mNetworkProperties.toString());
+ log("LinkProperties: " + mLinkProperties.toString());
}
}
return result;
@@ -636,7 +637,7 @@ public abstract class DataConnection extends HierarchicalStateMachine {
case ERR_BadDns:
// Connection succeeded but DNS info is bad so disconnect
StringBuilder dnsAddressesSb = new StringBuilder();
- for (InetAddress addr : mNetworkProperties.getDnses()) {
+ for (InetAddress addr : mLinkProperties.getDnses()) {
if (dnsAddressesSb.length() != 0) dnsAddressesSb.append(" ");
dnsAddressesSb.append(addr.toString());
}
@@ -911,10 +912,10 @@ public abstract class DataConnection extends HierarchicalStateMachine {
}
/**
- * @return the connections NetworkProperties
+ * @return the connections LinkProperties
*/
- public NetworkProperties getNetworkProperties() {
- return mNetworkProperties;
+ public LinkProperties getLinkProperties() {
+ return new LinkProperties(mLinkProperties);
}
/**
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index 14cb58474287..765f64bcb1cf 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -17,7 +17,7 @@
package com.android.internal.telephony;
import android.app.PendingIntent;
-import android.net.NetworkProperties;
+import android.net.LinkProperties;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
@@ -192,8 +192,8 @@ public abstract class DataConnectionTracker extends Handler {
/** indication of our availability (preconditions to trysetupData are met) **/
protected boolean mAvailability = false;
- /** all our network properties (dns, gateway, ip, etc) */
- protected NetworkProperties mNetworkProperties;
+ /** all our link properties (dns, gateway, ip, etc) */
+ protected LinkProperties mLinkProperties;
/**
* Default constructor
@@ -420,10 +420,10 @@ public abstract class DataConnectionTracker extends Handler {
protected abstract void setState(State s);
- protected NetworkProperties getNetworkProperties(String apnType) {
+ protected LinkProperties getLinkProperties(String apnType) {
int id = apnTypeToId(apnType);
if (isApnIdEnabled(id)) {
- return mNetworkProperties;
+ return new LinkProperties(mLinkProperties);
} else {
return null;
}
@@ -673,7 +673,7 @@ public abstract class DataConnectionTracker extends Handler {
}
}
- protected NetworkProperties getNetworkProperties(DataConnection connection) {
- return connection.getNetworkProperties();
+ protected LinkProperties getLinkProperties(DataConnection connection) {
+ return connection.getLinkProperties();
}
}
diff --git a/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java b/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java
index 382c19fcd98d..bf3c4d1e8fea 100644
--- a/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java
+++ b/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java
@@ -16,7 +16,7 @@
package com.android.internal.telephony;
-import android.net.NetworkProperties;
+import android.net.LinkProperties;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -108,9 +108,9 @@ public class DefaultPhoneNotifier implements PhoneNotifier {
// use apnType as the key to which connection we're talking about.
// pass apnType back up to fetch particular for this one.
TelephonyManager telephony = TelephonyManager.getDefault();
- NetworkProperties networkProperties = null;
+ LinkProperties linkProperties = null;
if (state == Phone.DataState.CONNECTED) {
- networkProperties = sender.getNetworkProperties(apnType);
+ linkProperties = sender.getLinkProperties(apnType);
}
try {
mRegistry.notifyDataConnection(
@@ -118,7 +118,7 @@ public class DefaultPhoneNotifier implements PhoneNotifier {
sender.isDataConnectivityPossible(), reason,
sender.getActiveApn(),
apnType,
- networkProperties,
+ linkProperties,
((telephony!=null) ? telephony.getNetworkType() :
TelephonyManager.NETWORK_TYPE_UNKNOWN));
} catch (RemoteException ex) {
diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index f7b70ee35fd6..eb7e566194f3 100644
--- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -17,7 +17,7 @@
package com.android.internal.telephony;
import android.content.Intent;
-import android.net.NetworkProperties;
+import android.net.LinkProperties;
import android.os.Bundle;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
@@ -33,7 +33,7 @@ interface ITelephonyRegistry {
void notifyCallForwardingChanged(boolean cfi);
void notifyDataActivity(int state);
void notifyDataConnection(int state, boolean isDataConnectivityPossible,
- String reason, String apn, String apnType, in NetworkProperties networkProperties,
+ String reason, String apn, String apnType, in LinkProperties linkProperties,
int networkType);
void notifyDataConnectionFailed(String reason, String apnType);
void notifyCellLocation(in Bundle cellLocation);
diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java
index e752dc6534d5..fffe057fccaa 100644
--- a/telephony/java/com/android/internal/telephony/Phone.java
+++ b/telephony/java/com/android/internal/telephony/Phone.java
@@ -17,7 +17,7 @@
package com.android.internal.telephony;
import android.content.Context;
-import android.net.NetworkProperties;
+import android.net.LinkProperties;
import android.os.Handler;
import android.os.Message;
import android.telephony.CellLocation;
@@ -99,7 +99,7 @@ public interface Phone {
static final String STATE_CHANGE_REASON_KEY = "reason";
static final String DATA_APN_TYPE_KEY = "apnType";
static final String DATA_APN_KEY = "apn";
- static final String DATA_NETWORK_PROPERTIES_KEY = "dataProperties";
+ static final String DATA_LINK_PROPERTIES_KEY = "linkProperties";
static final String DATA_IFACE_NAME_KEY = "iface";
static final String NETWORK_UNAVAILABLE_KEY = "networkUnvailable";
@@ -319,9 +319,9 @@ public interface Phone {
String getActiveApn();
/**
- * Return the NetworkProperties for the named apn or null if not available
+ * Return the LinkProperties for the named apn or null if not available
*/
- NetworkProperties getNetworkProperties(String apnType);
+ LinkProperties getLinkProperties(String apnType);
/**
* Get current signal strength. No change notification available on this
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index 05579423f49b..36a2fcff1718 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -21,7 +21,7 @@ import android.app.IActivityManager;
import android.content.Context;
import android.content.res.Configuration;
import android.content.SharedPreferences;
-import android.net.NetworkProperties;
+import android.net.LinkProperties;
import android.net.wifi.WifiManager;
import android.os.AsyncResult;
import android.os.Handler;
@@ -938,8 +938,8 @@ public abstract class PhoneBase extends Handler implements Phone {
return mDataConnection.getActiveApnTypes();
}
- public NetworkProperties getNetworkProperties(String apnType) {
- return mDataConnection.getNetworkProperties(apnType);
+ public LinkProperties getLinkProperties(String apnType) {
+ return mDataConnection.getLinkProperties(apnType);
}
public String getActiveApn() {
diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java
index bcf3337bb3ae..b6e4cda24db1 100644
--- a/telephony/java/com/android/internal/telephony/PhoneProxy.java
+++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java
@@ -20,7 +20,7 @@ package com.android.internal.telephony;
import android.app.ActivityManagerNative;
import android.content.Context;
import android.content.Intent;
-import android.net.NetworkProperties;
+import android.net.LinkProperties;
import android.os.Handler;
import android.os.Message;
import android.os.SystemProperties;
@@ -208,8 +208,8 @@ public class PhoneProxy extends Handler implements Phone {
return mActivePhone.getActiveApnTypes();
}
- public NetworkProperties getNetworkProperties(String apnType) {
- return mActivePhone.getNetworkProperties(apnType);
+ public LinkProperties getLinkProperties(String apnType) {
+ return mActivePhone.getLinkProperties(apnType);
}
public String getActiveApn() {
diff --git a/telephony/java/com/android/internal/telephony/SipPhoneNotifier.java b/telephony/java/com/android/internal/telephony/SipPhoneNotifier.java
index 1229d14df943..30d06d85512d 100644
--- a/telephony/java/com/android/internal/telephony/SipPhoneNotifier.java
+++ b/telephony/java/com/android/internal/telephony/SipPhoneNotifier.java
@@ -16,7 +16,7 @@
package com.android.internal.telephony;
-import android.net.NetworkProperties;
+import android.net.LinkProperties;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -110,9 +110,9 @@ public class SipPhoneNotifier implements PhoneNotifier {
// use apnType as the key to which connection we're talking about.
// pass apnType back up to fetch particular for this one.
TelephonyManager telephony = TelephonyManager.getDefault();
- NetworkProperties networkProperties = null;
+ LinkProperties linkProperties = null;
if (state == Phone.DataState.CONNECTED) {
- networkProperties = sender.getNetworkProperties(apnType);
+ linkProperties = sender.getLinkProperties(apnType);
}
try {
mRegistry.notifyDataConnection(
@@ -120,7 +120,7 @@ public class SipPhoneNotifier implements PhoneNotifier {
sender.isDataConnectivityPossible(), reason,
sender.getActiveApn(),
apnType,
- networkProperties,
+ linkProperties,
((telephony!=null) ? telephony.getNetworkType() :
TelephonyManager.NETWORK_TYPE_UNKNOWN));
} catch (RemoteException ex) {
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
index c94cfa448564..59182457038e 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -732,7 +732,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
}
if (ar.exception == null) {
- mNetworkProperties = getNetworkProperties(mActiveDataConnection);
+ mLinkProperties = getLinkProperties(mActiveDataConnection);
// everything is setup
notifyDefaultData(reason);
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index face581b41d7..441446061f55 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -1098,7 +1098,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
if (ar.exception == null) {
- mNetworkProperties = getNetworkProperties(mActivePdp);
+ mLinkProperties = getLinkProperties(mActivePdp);
ApnSetting apn = mActivePdp.getApn();
if (apn.proxy != null && apn.proxy.length() != 0) {
@@ -1106,7 +1106,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
ProxyProperties proxy = new ProxyProperties();
proxy.setAddress(InetAddress.getByName(apn.proxy));
proxy.setPort(Integer.parseInt(apn.port));
- mNetworkProperties.setHttpProxy(proxy);
+ mLinkProperties.setHttpProxy(proxy);
} catch (UnknownHostException e) {
Log.e(LOG_TAG, "UnknownHostException making ProxyProperties: " + e);
} catch (SecurityException e) {
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java b/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java
index 1d33be9e90a0..e7428877d4cc 100755
--- a/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java
@@ -19,7 +19,7 @@ package com.android.internal.telephony.sip;
import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
-import android.net.NetworkProperties;
+import android.net.LinkProperties;
import android.net.Uri;
import android.os.AsyncResult;
import android.os.Handler;
@@ -540,7 +540,7 @@ abstract class SipPhoneBase extends PhoneBase {
}
//@Override
- public NetworkProperties getNetworkProperties(String apnType) {
+ public LinkProperties getLinkProperties(String apnType) {
// FIXME: what's this for SIP?
return null;
}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
index 88aa78ef3dab..c4a6f53dc34a 100644
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
@@ -20,10 +20,6 @@ import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import android.text.SpannableStringBuilder;
import android.telephony.PhoneNumberUtils;
-import android.telephony.TelephonyManager;
-import android.content.Context;
-
-import junit.framework.TestCase;
public class PhoneNumberUtilsTest extends AndroidTestCase {
@@ -527,4 +523,16 @@ public class PhoneNumberUtilsTest extends AndroidTestCase {
assertEquals("+16502910000", PhoneNumberUtils.normalizeNumber("+1 650 2910000"));
}
+ @SmallTest
+ public void testFormatDailabeNumber() {
+ // Using the phoneNumberE164's country code
+ assertEquals("(650) 291-0000",
+ PhoneNumberUtils.formatNumber("6502910000", "+16502910000", "CN"));
+ // The phoneNumberE164 is null
+ assertEquals("(650) 291-0000", PhoneNumberUtils.formatNumber("6502910000", null, "US"));
+ // The given number has a country code.
+ assertEquals("+1 650-291-0000", PhoneNumberUtils.formatNumber("+16502910000", null, "CN"));
+ // The given number was formatted.
+ assertEquals("650-291-0000", PhoneNumberUtils.formatNumber("650-291-0000", null, "US"));
+ }
}
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 21671f1da1a1..8c3ec5ff4f1c 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -307,19 +307,19 @@ public class WifiManager {
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String CONFIG_CHANGED_ACTION = "android.net.wifi.CONFIG_CHANGED";
/**
- * The lookup key for a {@link android.net.NetworkProperties} object associated with the
+ * The lookup key for a {@link android.net.LinkProperties} object associated with the
* Wi-Fi network. Retrieve with
* {@link android.content.Intent#getParcelableExtra(String)}.
* @hide
*/
- public static final String EXTRA_NETWORK_PROPERTIES = "networkProperties";
+ public static final String EXTRA_LINK_PROPERTIES = "linkProperties";
/**
* The network IDs of the configured networks could have changed.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String NETWORK_IDS_CHANGED_ACTION = "android.net.wifi.NETWORK_IDS_CHANGED";
-
+
/**
* Activity Action: Pick a Wi-Fi network to connect to.
* <p>Input: Nothing.
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 69e8f2ebe148..7554bd1e61a5 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -43,7 +43,7 @@ import android.net.DhcpInfo;
import android.net.NetworkUtils;
import android.net.ConnectivityManager;
import android.net.NetworkInfo.DetailedState;
-import android.net.NetworkProperties;
+import android.net.LinkProperties;
import android.net.wifi.WifiConfiguration.Status;
import android.os.Binder;
import android.os.Message;
@@ -143,7 +143,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
* Observes the static IP address settings.
*/
private SettingsObserver mSettingsObserver;
- private NetworkProperties mNetworkProperties;
+ private LinkProperties mLinkProperties;
// Held during driver load and unload
private static PowerManager.WakeLock sWakeLock;
@@ -421,10 +421,10 @@ public class WifiStateMachine extends HierarchicalStateMachine {
mSupplicantStateTracker = new SupplicantStateTracker(context, getHandler());
mBluetoothHeadset = new BluetoothHeadset(mContext, null);
- mNetworkProperties = new NetworkProperties();
+ mLinkProperties = new LinkProperties();
mNetworkInfo.setIsAvailable(false);
- mNetworkProperties.clear();
+ mLinkProperties.clear();
mLastBssid = null;
mLastNetworkId = -1;
mLastSignalLevel = -1;
@@ -899,7 +899,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
StringBuffer sb = new StringBuffer();
String LS = System.getProperty("line.separator");
sb.append("current HSM state: ").append(getCurrentState().getName()).append(LS);
- sb.append("mNetworkProperties ").append(mNetworkProperties).append(LS);
+ sb.append("mLinkProperties ").append(mLinkProperties).append(LS);
sb.append("mWifiInfo ").append(mWifiInfo).append(LS);
sb.append("mDhcpInfo ").append(mDhcpInfo).append(LS);
sb.append("mNetworkInfo ").append(mNetworkInfo).append(LS);
@@ -1189,9 +1189,9 @@ public class WifiStateMachine extends HierarchicalStateMachine {
return null;
}
- private void configureNetworkProperties() {
+ private void configureLinkProperties() {
try {
- mNetworkProperties.setInterface(NetworkInterface.getByName(mInterfaceName));
+ mLinkProperties.setInterface(NetworkInterface.getByName(mInterfaceName));
} catch (SocketException e) {
Log.e(TAG, "SocketException creating NetworkInterface from " + mInterfaceName +
". e=" + e);
@@ -1201,10 +1201,10 @@ public class WifiStateMachine extends HierarchicalStateMachine {
return;
}
// TODO - fix this for v6
- mNetworkProperties.addAddress(NetworkUtils.intToInetAddress(mDhcpInfo.ipAddress));
- mNetworkProperties.setGateway(NetworkUtils.intToInetAddress(mDhcpInfo.gateway));
- mNetworkProperties.addDns(NetworkUtils.intToInetAddress(mDhcpInfo.dns1));
- mNetworkProperties.addDns(NetworkUtils.intToInetAddress(mDhcpInfo.dns2));
+ mLinkProperties.addAddress(NetworkUtils.intToInetAddress(mDhcpInfo.ipAddress));
+ mLinkProperties.setGateway(NetworkUtils.intToInetAddress(mDhcpInfo.gateway));
+ mLinkProperties.addDns(NetworkUtils.intToInetAddress(mDhcpInfo.dns1));
+ mLinkProperties.addDns(NetworkUtils.intToInetAddress(mDhcpInfo.dns2));
// TODO - add proxy info
}
@@ -1381,7 +1381,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
| Intent.FLAG_RECEIVER_REPLACE_PENDING);
intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, mNetworkInfo);
- intent.putExtra(WifiManager.EXTRA_NETWORK_PROPERTIES, mNetworkProperties);
+ intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, mLinkProperties);
if (bssid != null)
intent.putExtra(WifiManager.EXTRA_BSSID, bssid);
mContext.sendStickyBroadcast(intent);
@@ -1390,7 +1390,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
private void sendConfigChangeBroadcast() {
if (!ActivityManagerNative.isSystemReady()) return;
Intent intent = new Intent(WifiManager.CONFIG_CHANGED_ACTION);
- intent.putExtra(WifiManager.EXTRA_NETWORK_PROPERTIES, mNetworkProperties);
+ intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, mLinkProperties);
mContext.sendBroadcast(intent);
}
@@ -1945,7 +1945,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
mWifiInfo.setNetworkId(-1);
/* Clear network properties */
- mNetworkProperties.clear();
+ mLinkProperties.clear();
mLastBssid= null;
mLastNetworkId = -1;
@@ -3036,7 +3036,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
mLastSignalLevel = -1; // force update of signal strength
mWifiInfo.setIpAddress(mDhcpInfo.ipAddress);
Log.d(TAG, "IP configuration: " + mDhcpInfo);
- configureNetworkProperties();
+ configureLinkProperties();
setDetailedState(DetailedState.CONNECTED);
sendNetworkStateChangeBroadcast(mLastBssid);
//TODO: we could also detect an IP config change
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index 147e2dcdffaf..5a20736a7b75 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -24,7 +24,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
-import android.net.NetworkProperties;
+import android.net.LinkProperties;
import android.net.NetworkStateTracker;
import android.os.Handler;
import android.os.Message;
@@ -47,7 +47,7 @@ public class WifiStateTracker implements NetworkStateTracker {
private AtomicInteger mDefaultGatewayAddr = new AtomicInteger(0);
private AtomicBoolean mDefaultRouteSet = new AtomicBoolean(false);
- private NetworkProperties mNetworkProperties;
+ private LinkProperties mLinkProperties;
private NetworkInfo mNetworkInfo;
/* For sending events to connectivity service handler */
@@ -58,10 +58,10 @@ public class WifiStateTracker implements NetworkStateTracker {
public WifiStateTracker() {
mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, NETWORKTYPE, "");
- mNetworkProperties = new NetworkProperties();
+ mLinkProperties = new LinkProperties();
mNetworkInfo.setIsAvailable(false);
- mNetworkProperties.clear();
+ mLinkProperties.clear();
setTeardownRequested(false);
}
@@ -191,10 +191,10 @@ public class WifiStateTracker implements NetworkStateTracker {
}
/**
- * Fetch NetworkProperties for the network
+ * Fetch LinkProperties for the network
*/
- public NetworkProperties getNetworkProperties() {
- return mNetworkProperties;
+ public LinkProperties getLinkProperties() {
+ return new LinkProperties(mLinkProperties);
}
/**
@@ -232,13 +232,13 @@ public class WifiStateTracker implements NetworkStateTracker {
if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
mNetworkInfo = (NetworkInfo) intent.getParcelableExtra(
WifiManager.EXTRA_NETWORK_INFO);
- mNetworkProperties = (NetworkProperties) intent.getParcelableExtra(
- WifiManager.EXTRA_NETWORK_PROPERTIES);
+ mLinkProperties = (LinkProperties) intent.getParcelableExtra(
+ WifiManager.EXTRA_LINK_PROPERTIES);
Message msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
msg.sendToTarget();
} else if (intent.getAction().equals(WifiManager.CONFIG_CHANGED_ACTION)) {
- mNetworkProperties = (NetworkProperties) intent.getParcelableExtra(
- WifiManager.EXTRA_NETWORK_PROPERTIES);
+ mLinkProperties = (LinkProperties) intent.getParcelableExtra(
+ WifiManager.EXTRA_LINK_PROPERTIES);
Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo);
msg.sendToTarget();
}