Merge "Bug 5031179 possible fix for assert in join"
diff --git a/api/current.txt b/api/current.txt
index e636ae7..3503fb3 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -8937,6 +8937,8 @@
method public java.lang.String flatten();
method public java.lang.String get(java.lang.String);
method public java.lang.String getAntibanding();
+ method public boolean getAutoExposureLock();
+ method public boolean getAutoWhiteBalanceLock();
method public java.lang.String getColorEffect();
method public int getExposureCompensation();
method public float getExposureCompensationStep();
@@ -8982,6 +8984,8 @@
method public java.lang.String getWhiteBalance();
method public int getZoom();
method public java.util.List<java.lang.Integer> getZoomRatios();
+ method public boolean isAutoExposureLockSupported();
+ method public boolean isAutoWhiteBalanceLockSupported();
method public boolean isSmoothZoomSupported();
method public boolean isZoomSupported();
method public void remove(java.lang.String);
@@ -8989,6 +8993,8 @@
method public void set(java.lang.String, java.lang.String);
method public void set(java.lang.String, int);
method public void setAntibanding(java.lang.String);
+ method public void setAutoExposureLock(boolean);
+ method public void setAutoWhiteBalanceLock(boolean);
method public void setColorEffect(java.lang.String);
method public void setExposureCompensation(int);
method public void setFlashMode(java.lang.String);
@@ -18018,7 +18024,6 @@
public abstract interface SynthesisCallback {
method public abstract int audioAvailable(byte[], int, int);
- method public abstract int completeAudioAvailable(int, int, int, byte[], int, int);
method public abstract int done();
method public abstract void error();
method public abstract int getMaxBufferSize();
@@ -22074,6 +22079,7 @@
method public void buildDrawingCache();
method public void buildDrawingCache(boolean);
method public void buildLayer();
+ method protected boolean canResolveLayoutDirection();
method public boolean canScrollHorizontally(int);
method public boolean canScrollVertically(int);
method public void cancelLongPress();
@@ -25275,6 +25281,10 @@
method public void setRowCount(int);
method public void setRowOrderPreserved(boolean);
method public void setUseDefaultMargins(boolean);
+ method public static android.widget.GridLayout.Spec spec(int, int, android.widget.GridLayout.Alignment, int);
+ method public static android.widget.GridLayout.Spec spec(int, android.widget.GridLayout.Alignment, int);
+ method public static android.widget.GridLayout.Spec spec(int, int, android.widget.GridLayout.Alignment);
+ method public static android.widget.GridLayout.Spec spec(int, android.widget.GridLayout.Alignment);
field public static final int ALIGN_BOUNDS = 0; // 0x0
field public static final int ALIGN_MARGINS = 1; // 0x1
field public static final android.widget.GridLayout.Alignment BASELINE;
@@ -25293,23 +25303,19 @@
public static abstract class GridLayout.Alignment {
}
- public static class GridLayout.Group {
- ctor public GridLayout.Group(int, int, android.widget.GridLayout.Alignment);
- ctor public GridLayout.Group(int, android.widget.GridLayout.Alignment);
- field public final android.widget.GridLayout.Alignment alignment;
- field public int flexibility;
- }
-
public static class GridLayout.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
- ctor public GridLayout.LayoutParams(android.widget.GridLayout.Group, android.widget.GridLayout.Group);
+ ctor public GridLayout.LayoutParams(android.widget.GridLayout.Spec, android.widget.GridLayout.Spec);
ctor public GridLayout.LayoutParams();
ctor public GridLayout.LayoutParams(android.view.ViewGroup.LayoutParams);
ctor public GridLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
ctor public GridLayout.LayoutParams(android.widget.GridLayout.LayoutParams);
ctor public GridLayout.LayoutParams(android.content.Context, android.util.AttributeSet);
method public void setGravity(int);
- field public android.widget.GridLayout.Group columnGroup;
- field public android.widget.GridLayout.Group rowGroup;
+ field public android.widget.GridLayout.Spec columnSpec;
+ field public android.widget.GridLayout.Spec rowSpec;
+ }
+
+ public static class GridLayout.Spec {
}
public class GridView extends android.widget.AbsListView {
diff --git a/cmds/ip-up-vpn/ip-up-vpn.c b/cmds/ip-up-vpn/ip-up-vpn.c
index bbf6b14e..e9ee95d 100644
--- a/cmds/ip-up-vpn/ip-up-vpn.c
+++ b/cmds/ip-up-vpn/ip-up-vpn.c
@@ -17,19 +17,135 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <errno.h>
-#include <cutils/properties.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <linux/if.h>
+#include <linux/route.h>
+#define LOG_TAG "ip-up-vpn"
+#include <cutils/log.h>
+
+#define DIR "/data/misc/vpn/"
+
+static const char *env(const char *name) {
+ const char *value = getenv(name);
+ return value ? value : "";
+}
+
+static int set_address(struct sockaddr *sa, const char *address) {
+ sa->sa_family = AF_INET;
+ return inet_pton(AF_INET, address, &((struct sockaddr_in *)sa)->sin_addr);
+}
+
+/*
+ * The primary goal is to create a file with VPN parameters. Currently they
+ * are interface, addresses, routes, DNS servers, and search domains. Each
+ * parameter occupies one line in the file, and it can be an empty string or
+ * space-separated values. The order and the format must be consistent with
+ * com.android.server.connectivity.Vpn. Here is an example.
+ *
+ * ppp0
+ * 192.168.1.100/24
+ * 0.0.0.0/0
+ * 192.168.1.1 192.168.1.2
+ * example.org
+ *
+ * The secondary goal is to unify the outcome of VPN. The current baseline
+ * is to have an interface configured with the given address and netmask
+ * and maybe add a host route to protect the tunnel. PPP-based VPN already
+ * does this, but others might not. Routes, DNS servers, and search domains
+ * are handled by the framework since they can be overridden by the users.
+ */
int main(int argc, char **argv)
{
- if (argc > 1 && strlen(argv[1]) > 0) {
- char dns[PROPERTY_VALUE_MAX];
- char *dns1 = getenv("DNS1");
- char *dns2 = getenv("DNS2");
+ FILE *state = fopen(DIR ".tmp", "wb");
+ if (!state) {
+ LOGE("Cannot create state: %s", strerror(errno));
+ return 1;
+ }
- snprintf(dns, sizeof(dns), "%s %s", dns1 ? dns1 : "", dns2 ? dns2 : "");
- property_set("vpn.dns", dns);
- property_set("vpn.via", argv[1]);
+ if (argc >= 6) {
+ /* Invoked by pppd. */
+ fprintf(state, "%s\n", argv[1]);
+ fprintf(state, "%s/32\n", argv[4]);
+ fprintf(state, "0.0.0.0/0\n");
+ fprintf(state, "%s %s\n", env("DNS1"), env("DNS2"));
+ fprintf(state, "\n");
+ } else if (argc == 2) {
+ /* Invoked by racoon. */
+ const char *interface = env("INTERFACE");
+ const char *address = env("INTERNAL_ADDR4");
+ const char *routes = env("SPLIT_INCLUDE_CIDR");
+
+ int s = socket(AF_INET, SOCK_DGRAM, 0);
+ struct rtentry rt;
+ struct ifreq ifr;
+
+ memset(&rt, 0, sizeof(rt));
+ memset(&ifr, 0, sizeof(ifr));
+
+ /* Remove the old host route. There could be more than one. */
+ rt.rt_flags |= RTF_UP | RTF_HOST;
+ if (set_address(&rt.rt_dst, env("REMOTE_ADDR"))) {
+ while (!ioctl(s, SIOCDELRT, &rt));
+ }
+ if (errno != ESRCH) {
+ LOGE("Cannot remove host route: %s", strerror(errno));
+ return 1;
+ }
+
+ /* Create a new host route. */
+ rt.rt_flags |= RTF_GATEWAY;
+ if (!set_address(&rt.rt_gateway, argv[1]) ||
+ (ioctl(s, SIOCADDRT, &rt) && errno != EEXIST)) {
+ LOGE("Cannot create host route: %s", strerror(errno));
+ return 1;
+ }
+
+ /* Bring up the interface. */
+ ifr.ifr_flags = IFF_UP;
+ strncpy(ifr.ifr_name, interface, IFNAMSIZ);
+ if (ioctl(s, SIOCSIFFLAGS, &ifr)) {
+ LOGE("Cannot bring up %s: %s", interface, strerror(errno));
+ return 1;
+ }
+
+ /* Set the address. */
+ if (!set_address(&ifr.ifr_addr, address) ||
+ ioctl(s, SIOCSIFADDR, &ifr)) {
+ LOGE("Cannot set address: %s", strerror(errno));
+ return 1;
+ }
+
+ /* Set the netmask. */
+ if (!set_address(&ifr.ifr_netmask, env("INTERNAL_NETMASK4")) ||
+ ioctl(s, SIOCSIFNETMASK, &ifr)) {
+ LOGE("Cannot set netmask: %s", strerror(errno));
+ return 1;
+ }
+
+ /* TODO: Send few packets to trigger phase 2? */
+
+ fprintf(state, "%s\n", interface);
+ fprintf(state, "%s/%s\n", address, env("INTERNAL_CIDR4"));
+ fprintf(state, "%s\n", routes[0] ? routes : "0.0.0.0/0");
+ fprintf(state, "%s\n", env("INTERNAL_DNS4_LIST"));
+ fprintf(state, "%s\n", env("DEFAULT_DOMAIN"));
+ } else {
+ LOGE("Cannot parse parameters");
+ return 1;
+ }
+
+ fclose(state);
+ if (chmod(DIR ".tmp", 0444) || rename(DIR ".tmp", DIR "state")) {
+ LOGE("Cannot write state: %s", strerror(errno));
+ return 1;
}
return 0;
}
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 8a42693..7d67e11 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -720,8 +720,20 @@
* onAutoFocus will be called immediately with a fake value of
* <code>success</code> set to <code>true</code>.
*
+ * The auto-focus routine may lock auto-exposure and auto-white balance
+ * after it completes. To check for the state of these locks, use the
+ * {@link android.hardware.Camera.Parameters#getAutoExposureLock()} and
+ * {@link android.hardware.Camera.Parameters#getAutoWhiteBalanceLock()}
+ * methods. If such locking is undesirable, use
+ * {@link android.hardware.Camera.Parameters#setAutoExposureLock(boolean)}
+ * and
+ * {@link android.hardware.Camera.Parameters#setAutoWhiteBalanceLock(boolean)}
+ * to release the locks.
+ *
* @param success true if focus was successful, false if otherwise
* @param camera the Camera service object
+ * @see android.hardware.Camera.Parameters#setAutoExposureLock(boolean)
+ * @see android.hardware.Camera.Parameters#setAutoWhiteBalanceLock(boolean)
*/
void onAutoFocus(boolean success, Camera camera);
};
@@ -747,8 +759,21 @@
* {@link android.hardware.Camera.Parameters#FLASH_MODE_OFF}, flash may be
* fired during auto-focus, depending on the driver and camera hardware.<p>
*
+ * The auto-focus routine may lock auto-exposure and auto-white balance
+ * after it completes. To check for the state of these locks, use the
+ * {@link android.hardware.Camera.Parameters#getAutoExposureLock()} and
+ * {@link android.hardware.Camera.Parameters#getAutoWhiteBalanceLock()}
+ * methods after the {@link AutoFocusCallback#onAutoFocus(boolean, Camera)}
+ * callback is invoked. If such locking is undesirable, use
+ * {@link android.hardware.Camera.Parameters#setAutoExposureLock(boolean)}
+ * and
+ * {@link android.hardware.Camera.Parameters#setAutoWhiteBalanceLock(boolean)}
+ * to release the locks.
+ *
* @param cb the callback to run
* @see #cancelAutoFocus()
+ * @see android.hardware.Camera.Parameters#setAutoExposureLock(boolean)
+ * @see android.hardware.Camera.Parameters#setAutoWhiteBalanceLock(boolean)
*/
public final void autoFocus(AutoFocusCallback cb)
{
@@ -763,7 +788,13 @@
* this function will return the focus position to the default.
* If the camera does not support auto-focus, this is a no-op.
*
+ * Canceling auto-focus will return the auto-exposure lock and auto-white
+ * balance lock to their state before {@link #autoFocus(AutoFocusCallback)}
+ * was called.
+ *
* @see #autoFocus(Camera.AutoFocusCallback)
+ * @see android.hardware.Camera.Parameters#setAutoExposureLock(boolean)
+ * @see android.hardware.Camera.Parameters#setAutoWhiteBalanceLock(boolean)
*/
public final void cancelAutoFocus()
{
@@ -2562,8 +2593,6 @@
* routine is free to run normally.
*
* @see #getAutoExposureLock()
- *
- * @hide
*/
public void setAutoExposureLock(boolean toggle) {
set(KEY_AUTO_EXPOSURE_LOCK, toggle ? TRUE : FALSE);
@@ -2583,7 +2612,6 @@
*
* @see #setAutoExposureLock(boolean)
*
- * @hide
*/
public boolean getAutoExposureLock() {
String str = get(KEY_AUTO_EXPOSURE_LOCK);
@@ -2598,7 +2626,6 @@
* @return true if auto-exposure lock is supported.
* @see #setAutoExposureLock(boolean)
*
- * @hide
*/
public boolean isAutoExposureLockSupported() {
String str = get(KEY_AUTO_EXPOSURE_LOCK_SUPPORTED);
@@ -2645,8 +2672,6 @@
* auto-white balance routine is free to run normally.
*
* @see #getAutoWhiteBalanceLock()
- *
- * @hide
*/
public void setAutoWhiteBalanceLock(boolean toggle) {
set(KEY_AUTO_WHITEBALANCE_LOCK, toggle ? TRUE : FALSE);
@@ -2668,7 +2693,6 @@
*
* @see #setAutoWhiteBalanceLock(boolean)
*
- * @hide
*/
public boolean getAutoWhiteBalanceLock() {
String str = get(KEY_AUTO_WHITEBALANCE_LOCK);
@@ -2683,7 +2707,6 @@
* @return true if auto-white balance lock is supported.
* @see #setAutoWhiteBalanceLock(boolean)
*
- * @hide
*/
public boolean isAutoWhiteBalanceLockSupported() {
String str = get(KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED);
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index d6f5643..d95fc8d 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -100,7 +100,7 @@
void setDataDependency(int networkType, boolean met);
- void protectVpn(in ParcelFileDescriptor socket);
+ boolean protectVpn(in ParcelFileDescriptor socket);
boolean prepareVpn(String oldPackage, String newPackage);
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 19894a0..f2f0e82 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -52,11 +52,26 @@
public class LinkProperties implements Parcelable {
String mIfaceName;
- private Collection<LinkAddress> mLinkAddresses;
- private Collection<InetAddress> mDnses;
- private Collection<RouteInfo> mRoutes;
+ private Collection<LinkAddress> mLinkAddresses = new ArrayList<LinkAddress>();
+ private Collection<InetAddress> mDnses = new ArrayList<InetAddress>();
+ private Collection<RouteInfo> mRoutes = new ArrayList<RouteInfo>();
private ProxyProperties mHttpProxy;
+ public static class CompareAddressesResult {
+ public ArrayList<LinkAddress> removed = new ArrayList<LinkAddress>();
+ public ArrayList<LinkAddress> added = new ArrayList<LinkAddress>();
+
+ @Override
+ public String toString() {
+ String retVal = "removedAddresses=[";
+ for (LinkAddress addr : removed) retVal += addr.toString() + ",";
+ retVal += "] addedAddresses=[";
+ for (LinkAddress addr : added) retVal += addr.toString() + ",";
+ retVal += "]";
+ return retVal;
+ }
+ }
+
public LinkProperties() {
clear();
}
@@ -121,9 +136,9 @@
public void clear() {
mIfaceName = null;
- mLinkAddresses = new ArrayList<LinkAddress>();
- mDnses = new ArrayList<InetAddress>();
- mRoutes = new ArrayList<RouteInfo>();
+ mLinkAddresses.clear();
+ mDnses.clear();
+ mRoutes.clear();
mHttpProxy = null;
}
@@ -155,6 +170,63 @@
return ifaceName + linkAddresses + routes + dns + proxy;
}
+ /**
+ * Compares this {@code LinkProperties} interface name against the target
+ *
+ * @param target LinkProperties to compare.
+ * @return {@code true} if both are identical, {@code false} otherwise.
+ */
+ public boolean isIdenticalInterfaceName(LinkProperties target) {
+ return TextUtils.equals(getInterfaceName(), target.getInterfaceName());
+ }
+
+ /**
+ * Compares this {@code LinkProperties} interface name against the target
+ *
+ * @param target LinkProperties to compare.
+ * @return {@code true} if both are identical, {@code false} otherwise.
+ */
+ public boolean isIdenticalAddresses(LinkProperties target) {
+ Collection<InetAddress> targetAddresses = target.getAddresses();
+ Collection<InetAddress> sourceAddresses = getAddresses();
+ return (sourceAddresses.size() == targetAddresses.size()) ?
+ sourceAddresses.containsAll(targetAddresses) : false;
+ }
+
+ /**
+ * Compares this {@code LinkProperties} DNS addresses against the target
+ *
+ * @param target LinkProperties to compare.
+ * @return {@code true} if both are identical, {@code false} otherwise.
+ */
+ public boolean isIdenticalDnses(LinkProperties target) {
+ Collection<InetAddress> targetDnses = target.getDnses();
+ return (mDnses.size() == targetDnses.size()) ?
+ mDnses.containsAll(targetDnses) : false;
+ }
+
+ /**
+ * Compares this {@code LinkProperties} Routes against the target
+ *
+ * @param target LinkProperties to compare.
+ * @return {@code true} if both are identical, {@code false} otherwise.
+ */
+ public boolean isIdenticalRoutes(LinkProperties target) {
+ Collection<RouteInfo> targetRoutes = target.getRoutes();
+ return (mRoutes.size() == targetRoutes.size()) ?
+ mRoutes.containsAll(targetRoutes) : false;
+ }
+
+ /**
+ * Compares this {@code LinkProperties} HttpProxy against the target
+ *
+ * @param target LinkProperties to compare.
+ * @return {@code true} if both are identical, {@code false} otherwise.
+ */
+ public boolean isIdenticalHttpProxy(LinkProperties target) {
+ return getHttpProxy() == null ? target.getHttpProxy() == null :
+ getHttpProxy().equals(target.getHttpProxy());
+ }
@Override
/**
@@ -176,30 +248,41 @@
if (!(obj instanceof LinkProperties)) return false;
- boolean sameAddresses;
- boolean sameDnses;
- boolean sameRoutes;
-
LinkProperties target = (LinkProperties) obj;
- Collection<InetAddress> targetAddresses = target.getAddresses();
- Collection<InetAddress> sourceAddresses = getAddresses();
- sameAddresses = (sourceAddresses.size() == targetAddresses.size()) ?
- sourceAddresses.containsAll(targetAddresses) : false;
+ return isIdenticalInterfaceName(target) &&
+ isIdenticalAddresses(target) &&
+ isIdenticalDnses(target) &&
+ isIdenticalRoutes(target) &&
+ isIdenticalHttpProxy(target);
+ }
- Collection<InetAddress> targetDnses = target.getDnses();
- sameDnses = (mDnses.size() == targetDnses.size()) ?
- mDnses.containsAll(targetDnses) : false;
-
- Collection<RouteInfo> targetRoutes = target.getRoutes();
- sameRoutes = (mRoutes.size() == targetRoutes.size()) ?
- mRoutes.containsAll(targetRoutes) : false;
-
- return
- sameAddresses && sameDnses && sameRoutes
- && TextUtils.equals(getInterfaceName(), target.getInterfaceName())
- && (getHttpProxy() == null ? target.getHttpProxy() == null :
- getHttpProxy().equals(target.getHttpProxy()));
+ /**
+ * Return two lists, a list of addresses that would be removed from
+ * mLinkAddresses and a list of addresses that would be added to
+ * mLinkAddress which would then result in target and mLinkAddresses
+ * being the same list.
+ *
+ * @param target is a new list of addresses
+ * @return the removed and added lists.
+ */
+ public CompareAddressesResult compareAddresses(LinkProperties target) {
+ /*
+ * Duplicate the LinkAddresses into removed, we will be removing
+ * address which are common between mLinkAddresses and target
+ * leaving the addresses that are different. And address which
+ * are in target but not in mLinkAddresses are placed in the
+ * addedAddresses.
+ */
+ CompareAddressesResult result = new CompareAddressesResult();
+ result.removed = new ArrayList<LinkAddress>(mLinkAddresses);
+ result.added.clear();
+ for (LinkAddress newAddress : target.getLinkAddresses()) {
+ if (! result.removed.remove(newAddress)) {
+ result.added.add(newAddress);
+ }
+ }
+ return result;
}
@Override
diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java
index 9381f1d..1ef0d9d 100644
--- a/core/java/android/net/NetworkTemplate.java
+++ b/core/java/android/net/NetworkTemplate.java
@@ -18,6 +18,7 @@
import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.net.ConnectivityManager.TYPE_WIMAX;
+import static android.net.ConnectivityManager.TYPE_ETHERNET;
import static android.net.ConnectivityManager.isNetworkTypeMobile;
import static android.telephony.TelephonyManager.NETWORK_CLASS_2_G;
import static android.telephony.TelephonyManager.NETWORK_CLASS_3_G;
@@ -38,41 +39,69 @@
*/
public class NetworkTemplate implements Parcelable {
+ /** {@hide} */
+ public static final int MATCH_MOBILE_ALL = 1;
+ /** {@hide} */
+ public static final int MATCH_MOBILE_3G_LOWER = 2;
+ /** {@hide} */
+ public static final int MATCH_MOBILE_4G = 3;
+ /** {@hide} */
+ public static final int MATCH_WIFI = 4;
+ /** {@hide} */
+ public static final int MATCH_ETHERNET = 5;
+
/**
* Template to combine all {@link ConnectivityManager#TYPE_MOBILE} style
* networks together. Only uses statistics for requested IMSI.
*/
- public static final int MATCH_MOBILE_ALL = 1;
+ public static NetworkTemplate buildTemplateMobileAll(String subscriberId) {
+ return new NetworkTemplate(MATCH_MOBILE_ALL, subscriberId);
+ }
/**
* Template to combine all {@link ConnectivityManager#TYPE_MOBILE} style
* networks together that roughly meet a "3G" definition, or lower. Only
* uses statistics for requested IMSI.
*/
- public static final int MATCH_MOBILE_3G_LOWER = 2;
+ public static NetworkTemplate buildTemplateMobile3gLower(String subscriberId) {
+ return new NetworkTemplate(MATCH_MOBILE_3G_LOWER, subscriberId);
+ }
/**
* Template to combine all {@link ConnectivityManager#TYPE_MOBILE} style
* networks together that meet a "4G" definition. Only uses statistics for
* requested IMSI.
*/
- public static final int MATCH_MOBILE_4G = 3;
+ public static NetworkTemplate buildTemplateMobile4g(String subscriberId) {
+ return new NetworkTemplate(MATCH_MOBILE_4G, subscriberId);
+ }
/**
* Template to combine all {@link ConnectivityManager#TYPE_WIFI} style
* networks together.
*/
- public static final int MATCH_WIFI = 4;
+ public static NetworkTemplate buildTemplateWifi() {
+ return new NetworkTemplate(MATCH_WIFI, null);
+ }
- final int mMatchRule;
- final String mSubscriberId;
+ /**
+ * Template to combine all {@link ConnectivityManager#TYPE_ETHERNET} style
+ * networks together.
+ */
+ public static NetworkTemplate buildTemplateEthernet() {
+ return new NetworkTemplate(MATCH_ETHERNET, null);
+ }
+ private final int mMatchRule;
+ private final String mSubscriberId;
+
+ /** {@hide} */
public NetworkTemplate(int matchRule, String subscriberId) {
this.mMatchRule = matchRule;
this.mSubscriberId = subscriberId;
}
- public NetworkTemplate(Parcel in) {
+ private NetworkTemplate(Parcel in) {
mMatchRule = in.readInt();
mSubscriberId = in.readString();
}
@@ -110,10 +139,12 @@
return false;
}
+ /** {@hide} */
public int getMatchRule() {
return mMatchRule;
}
+ /** {@hide} */
public String getSubscriberId() {
return mSubscriberId;
}
@@ -131,6 +162,8 @@
return matchesMobile4g(ident);
case MATCH_WIFI:
return matchesWifi(ident);
+ case MATCH_ETHERNET:
+ return matchesEthernet(ident);
default:
throw new IllegalArgumentException("unknown network template");
}
@@ -190,7 +223,17 @@
return false;
}
- public static String getMatchRuleName(int matchRule) {
+ /**
+ * Check if matches Ethernet network template.
+ */
+ private boolean matchesEthernet(NetworkIdentity ident) {
+ if (ident.mType == TYPE_ETHERNET) {
+ return true;
+ }
+ return false;
+ }
+
+ private static String getMatchRuleName(int matchRule) {
switch (matchRule) {
case MATCH_MOBILE_3G_LOWER:
return "MOBILE_3G_LOWER";
@@ -200,6 +243,8 @@
return "MOBILE_ALL";
case MATCH_WIFI:
return "WIFI";
+ case MATCH_ETHERNET:
+ return "ETHERNET";
default:
return "UNKNOWN";
}
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 5b1f563..3362575 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -86,6 +86,12 @@
public static final int WIFI_UID = 1010;
/**
+ * Defines the UID/GID for the mediaserver process.
+ * @hide
+ */
+ public static final int MEDIA_UID = 1013;
+
+ /**
* Defines the GID for the group that allows write access to the SD card.
* @hide
*/
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index f799af3..f3bcedb 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -283,6 +283,13 @@
*/
public static final String IS_DRM = "is_drm";
+ /**
+ * Used by the media scanner to suppress files from being processed as media files.
+ *
+ * <P>Type: INTEGER (boolean)</P>
+ * @hide
+ */
+ public static final String NO_MEDIA = "no_media";
}
/**
diff --git a/core/java/android/speech/tts/AudioPlaybackHandler.java b/core/java/android/speech/tts/AudioPlaybackHandler.java
index 1210941..dea708a 100644
--- a/core/java/android/speech/tts/AudioPlaybackHandler.java
+++ b/core/java/android/speech/tts/AudioPlaybackHandler.java
@@ -31,8 +31,7 @@
private static final int SYNTHESIS_START = 1;
private static final int SYNTHESIS_DATA_AVAILABLE = 2;
- private static final int SYNTHESIS_COMPLETE_DATA_AVAILABLE = 3;
- private static final int SYNTHESIS_DONE = 4;
+ private static final int SYNTHESIS_DONE = 3;
private static final int PLAY_AUDIO = 5;
private static final int PLAY_SILENCE = 6;
@@ -120,10 +119,6 @@
mQueue.add(new ListEntry(SYNTHESIS_DATA_AVAILABLE, token));
}
- void enqueueSynthesisCompleteDataAvailable(SynthesisMessageParams token) {
- mQueue.add(new ListEntry(SYNTHESIS_COMPLETE_DATA_AVAILABLE, token));
- }
-
void enqueueSynthesisDone(SynthesisMessageParams token) {
mQueue.add(new ListEntry(SYNTHESIS_DONE, token));
}
@@ -280,8 +275,6 @@
handleSynthesisDataAvailable(msg);
} else if (entry.mWhat == SYNTHESIS_DONE) {
handleSynthesisDone(msg);
- } else if (entry.mWhat == SYNTHESIS_COMPLETE_DATA_AVAILABLE) {
- handleSynthesisCompleteDataAvailable(msg);
} else if (entry.mWhat == PLAY_AUDIO) {
handleAudio(msg);
} else if (entry.mWhat == PLAY_SILENCE) {
@@ -424,54 +417,11 @@
return;
}
- final AudioTrack track = params.mAudioTrack;
+ final AudioTrack audioTrack = params.mAudioTrack;
final int bytesPerFrame = getBytesPerFrame(params.mAudioFormat);
final int lengthInBytes = params.mBytesWritten;
+ final int lengthInFrames = lengthInBytes / bytesPerFrame;
- blockUntilDone(track, bytesPerFrame, lengthInBytes);
- }
-
- private void handleSynthesisCompleteDataAvailable(MessageParams msg) {
- final SynthesisMessageParams params = (SynthesisMessageParams) msg;
- if (DBG) Log.d(TAG, "completeAudioAvailable(" + params + ")");
-
- params.mLogger.onPlaybackStart();
-
- // Channel config and bytes per frame are checked before
- // this message is sent.
- int channelConfig = AudioPlaybackHandler.getChannelConfig(params.mChannelCount);
- int bytesPerFrame = AudioPlaybackHandler.getBytesPerFrame(params.mAudioFormat);
-
- SynthesisMessageParams.ListEntry entry = params.getNextBuffer();
-
- if (entry == null) {
- Log.w(TAG, "completeDataAvailable : No buffers available to play.");
- return;
- }
-
- final AudioTrack audioTrack = new AudioTrack(params.mStreamType, params.mSampleRateInHz,
- channelConfig, params.mAudioFormat, entry.mLength, AudioTrack.MODE_STATIC);
-
- // So that handleDone can access this correctly.
- params.mAudioTrack = audioTrack;
-
- try {
- audioTrack.write(entry.mBytes, entry.mOffset, entry.mLength);
- setupVolume(audioTrack, params.mVolume, params.mPan);
- audioTrack.play();
- blockUntilDone(audioTrack, bytesPerFrame, entry.mLength);
- if (DBG) Log.d(TAG, "Wrote data to audio track successfully : " + entry.mLength);
- } catch (IllegalStateException ex) {
- Log.e(TAG, "Playback error", ex);
- } finally {
- handleSynthesisDone(msg);
- }
- }
-
-
- private static void blockUntilDone(AudioTrack audioTrack, int bytesPerFrame,
- int lengthInBytes) {
- int lengthInFrames = lengthInBytes / bytesPerFrame;
int currentPosition = 0;
while ((currentPosition = audioTrack.getPlaybackHeadPosition()) < lengthInFrames) {
if (audioTrack.getPlayState() != AudioTrack.PLAYSTATE_PLAYING) {
diff --git a/core/java/android/speech/tts/FileSynthesisCallback.java b/core/java/android/speech/tts/FileSynthesisCallback.java
index 4f4b3fb..5808919 100644
--- a/core/java/android/speech/tts/FileSynthesisCallback.java
+++ b/core/java/android/speech/tts/FileSynthesisCallback.java
@@ -187,37 +187,6 @@
}
}
- @Override
- public int completeAudioAvailable(int sampleRateInHz, int audioFormat, int channelCount,
- byte[] buffer, int offset, int length) {
- synchronized (mStateLock) {
- if (mStopped) {
- if (DBG) Log.d(TAG, "Request has been aborted.");
- return TextToSpeech.ERROR;
- }
- }
- FileOutputStream out = null;
- try {
- out = new FileOutputStream(mFileName);
- out.write(makeWavHeader(sampleRateInHz, audioFormat, channelCount, length));
- out.write(buffer, offset, length);
- mDone = true;
- return TextToSpeech.SUCCESS;
- } catch (IOException ex) {
- Log.e(TAG, "Failed to write to " + mFileName + ": " + ex);
- mFileName.delete();
- return TextToSpeech.ERROR;
- } finally {
- try {
- if (out != null) {
- out.close();
- }
- } catch (IOException ex) {
- Log.e(TAG, "Failed to close " + mFileName + ": " + ex);
- }
- }
- }
-
private byte[] makeWavHeader(int sampleRateInHz, int audioFormat, int channelCount,
int dataLength) {
// TODO: is AudioFormat.ENCODING_DEFAULT always the same as ENCODING_PCM_16BIT?
diff --git a/core/java/android/speech/tts/PlaybackSynthesisCallback.java b/core/java/android/speech/tts/PlaybackSynthesisCallback.java
index 38030a6..04bd745 100644
--- a/core/java/android/speech/tts/PlaybackSynthesisCallback.java
+++ b/core/java/android/speech/tts/PlaybackSynthesisCallback.java
@@ -53,8 +53,7 @@
// Handler associated with a thread that plays back audio requests.
private final AudioPlaybackHandler mAudioTrackHandler;
- // A request "token", which will be non null after start() or
- // completeAudioAvailable() have been called.
+ // A request "token", which will be non null after start() has been called.
private SynthesisMessageParams mToken = null;
// Whether this request has been stopped. This is useful for keeping
// track whether stop() has been called before start(). In all other cases,
@@ -206,35 +205,4 @@
stop();
}
- @Override
- public int completeAudioAvailable(int sampleRateInHz, int audioFormat, int channelCount,
- byte[] buffer, int offset, int length) {
- int channelConfig = AudioPlaybackHandler.getChannelConfig(channelCount);
- if (channelConfig == 0) {
- Log.e(TAG, "Unsupported number of channels :" + channelCount);
- return TextToSpeech.ERROR;
- }
-
- int bytesPerFrame = AudioPlaybackHandler.getBytesPerFrame(audioFormat);
- if (bytesPerFrame < 0) {
- Log.e(TAG, "Unsupported audio format :" + audioFormat);
- return TextToSpeech.ERROR;
- }
-
- synchronized (mStateLock) {
- if (mStopped) {
- return TextToSpeech.ERROR;
- }
- SynthesisMessageParams params = new SynthesisMessageParams(
- mStreamType, sampleRateInHz, audioFormat, channelCount, mVolume, mPan,
- mDispatcher, mCallingApp, mLogger);
- params.addBuffer(buffer, offset, length);
-
- mAudioTrackHandler.enqueueSynthesisCompleteDataAvailable(params);
- mToken = params;
- }
-
- return TextToSpeech.SUCCESS;
- }
-
}
diff --git a/core/java/android/speech/tts/SynthesisCallback.java b/core/java/android/speech/tts/SynthesisCallback.java
index 1b80e40..d70c371d 100644
--- a/core/java/android/speech/tts/SynthesisCallback.java
+++ b/core/java/android/speech/tts/SynthesisCallback.java
@@ -22,19 +22,16 @@
* {@link #start}, then {@link #audioAvailable} until all audio has been provided, then finally
* {@link #done}.
*
- * Alternatively, the engine can provide all the audio at once, by using
- * {@link #completeAudioAvailable}.
*
* {@link #error} can be called at any stage in the synthesis process to
- * indicate that an error has occured, but if the call is made after a call
- * to {@link #done} or {@link #completeAudioAvailable} it might be discarded.
+ * indicate that an error has occurred, but if the call is made after a call
+ * to {@link #done}, it might be discarded.
*/
public interface SynthesisCallback {
/**
* @return the maximum number of bytes that the TTS engine can pass in a single call of
- * {@link #audioAvailable}. This does not apply to {@link #completeAudioAvailable}.
- * Calls to {@link #audioAvailable} with data lengths larger than this
- * value will not succeed.
+ * {@link #audioAvailable}. Calls to {@link #audioAvailable} with data lengths
+ * larger than this value will not succeed.
*/
public int getMaxBufferSize();
@@ -69,23 +66,6 @@
public int audioAvailable(byte[] buffer, int offset, int length);
/**
- * The service can call this method instead of using {@link #start}, {@link #audioAvailable}
- * and {@link #done} if all the audio data is available in a single buffer.
- *
- * @param sampleRateInHz Sample rate in HZ of the generated audio.
- * @param audioFormat Audio format of the generated audio. Must be one of
- * the ENCODING_ constants defined in {@link android.media.AudioFormat}.
- * @param channelCount The number of channels. Must be {@code 1} or {@code 2}.
- * @param buffer The generated audio data. This method will not hold on to {@code buffer},
- * so the caller is free to modify it after this method returns.
- * @param offset The offset into {@code buffer} where the audio data starts.
- * @param length The number of bytes of audio data in {@code buffer}.
- * @return {@link TextToSpeech#SUCCESS} or {@link TextToSpeech#ERROR}.
- */
- public int completeAudioAvailable(int sampleRateInHz, int audioFormat,
- int channelCount, byte[] buffer, int offset, int length);
-
- /**
* The service should call this method when all the synthesized audio for a request has
* been passed to {@link #audioAvailable}.
*
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 74dc100..8cd683e 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -9066,11 +9066,20 @@
// Set resolved depending on layout direction
switch (getLayoutDirection()) {
case LAYOUT_DIRECTION_INHERIT:
+ // We cannot do the resolution if there is no parent
+ if (mParent == null) return;
+
// If this is root view, no need to look at parent's layout dir.
- if (mParent != null &&
- mParent instanceof ViewGroup &&
- ((ViewGroup) mParent).getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL) {
- mPrivateFlags2 |= LAYOUT_DIRECTION_RESOLVED_RTL;
+ if (mParent instanceof ViewGroup) {
+ ViewGroup viewGroup = ((ViewGroup) mParent);
+
+ // Check if the parent view group can resolve
+ if (! viewGroup.canResolveLayoutDirection()) {
+ return;
+ }
+ if (viewGroup.getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL) {
+ mPrivateFlags2 |= LAYOUT_DIRECTION_RESOLVED_RTL;
+ }
}
break;
case LAYOUT_DIRECTION_RTL:
@@ -9132,6 +9141,15 @@
recomputePadding();
}
+ protected boolean canResolveLayoutDirection() {
+ switch (getLayoutDirection()) {
+ case LAYOUT_DIRECTION_INHERIT:
+ return (mParent != null);
+ default:
+ return true;
+ }
+ }
+
/**
* Reset the resolved layout direction.
*
diff --git a/core/java/android/view/ViewAncestor.java b/core/java/android/view/ViewAncestor.java
index 1dcbc26..d539a03 100644
--- a/core/java/android/view/ViewAncestor.java
+++ b/core/java/android/view/ViewAncestor.java
@@ -2634,8 +2634,9 @@
mInputEventDeliverTimeNanos = System.nanoTime();
}
+ final boolean isTouchEvent = event.isTouchEvent();
if (mInputEventConsistencyVerifier != null) {
- if (event.isTouchEvent()) {
+ if (isTouchEvent) {
mInputEventConsistencyVerifier.onTouchEvent(event, 0);
} else {
mInputEventConsistencyVerifier.onGenericMotionEvent(event, 0);
@@ -2653,9 +2654,9 @@
mTranslator.translateEventInScreenToAppWindow(event);
}
- // Enter touch mode on the down.
- boolean isDown = event.getAction() == MotionEvent.ACTION_DOWN;
- if (isDown) {
+ // Enter touch mode on down or scroll.
+ final int action = event.getAction();
+ if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_SCROLL) {
ensureTouchMode(true);
}
@@ -2668,8 +2669,10 @@
}
// Remember the touch position for possible drag-initiation.
- mLastTouchPoint.x = event.getRawX();
- mLastTouchPoint.y = event.getRawY();
+ if (isTouchEvent) {
+ mLastTouchPoint.x = event.getRawX();
+ mLastTouchPoint.y = event.getRawY();
+ }
// Dispatch touch to view hierarchy.
boolean handled = mView.dispatchPointerEvent(event);
@@ -2681,51 +2684,6 @@
return;
}
- // Apply edge slop and try again, if appropriate.
- final int edgeFlags = event.getEdgeFlags();
- if (edgeFlags != 0 && mView instanceof ViewGroup) {
- final int edgeSlop = mViewConfiguration.getScaledEdgeSlop();
- int direction = View.FOCUS_UP;
- int x = (int)event.getX();
- int y = (int)event.getY();
- final int[] deltas = new int[2];
-
- if ((edgeFlags & MotionEvent.EDGE_TOP) != 0) {
- direction = View.FOCUS_DOWN;
- if ((edgeFlags & MotionEvent.EDGE_LEFT) != 0) {
- deltas[0] = edgeSlop;
- x += edgeSlop;
- } else if ((edgeFlags & MotionEvent.EDGE_RIGHT) != 0) {
- deltas[0] = -edgeSlop;
- x -= edgeSlop;
- }
- } else if ((edgeFlags & MotionEvent.EDGE_BOTTOM) != 0) {
- direction = View.FOCUS_UP;
- if ((edgeFlags & MotionEvent.EDGE_LEFT) != 0) {
- deltas[0] = edgeSlop;
- x += edgeSlop;
- } else if ((edgeFlags & MotionEvent.EDGE_RIGHT) != 0) {
- deltas[0] = -edgeSlop;
- x -= edgeSlop;
- }
- } else if ((edgeFlags & MotionEvent.EDGE_LEFT) != 0) {
- direction = View.FOCUS_RIGHT;
- } else if ((edgeFlags & MotionEvent.EDGE_RIGHT) != 0) {
- direction = View.FOCUS_LEFT;
- }
-
- View nearest = FocusFinder.getInstance().findNearestTouchable(
- ((ViewGroup) mView), x, y, direction, deltas);
- if (nearest != null) {
- event.offsetLocation(deltas[0], deltas[1]);
- event.setEdgeFlags(0);
- if (mView.dispatchPointerEvent(event)) {
- finishMotionEvent(event, sendDone, true);
- return;
- }
- }
- }
-
// Pointer event was unhandled.
finishMotionEvent(event, sendDone, false);
}
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 1449b18..8f8c1d0 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -271,12 +271,6 @@
Drawable mSelector;
/**
- * Set to true if we would like to have the selector showing itself.
- * We still need to draw and position it even if this is false.
- */
- boolean mSelectorShowing;
-
- /**
* The current position of the selector in the list.
*/
int mSelectorPosition = INVALID_POSITION;
@@ -1669,7 +1663,6 @@
setSelectedPositionInt(INVALID_POSITION);
setNextSelectedPositionInt(INVALID_POSITION);
mSelectedTop = 0;
- mSelectorShowing = false;
mSelectorPosition = INVALID_POSITION;
mSelectorRect.setEmpty();
invalidate();
@@ -2025,7 +2018,7 @@
final boolean isChildViewEnabled = mIsChildViewEnabled;
if (sel.isEnabled() != isChildViewEnabled) {
mIsChildViewEnabled = !isChildViewEnabled;
- if (mSelectorShowing) {
+ if (getSelectedItemPosition() != INVALID_POSITION) {
refreshDrawableState();
}
}
@@ -2769,6 +2762,7 @@
// touch mode). Force an initial layout to get rid of the selection.
layoutChildren();
}
+ updateSelectorState();
} else {
int touchMode = mTouchMode;
if (touchMode == TOUCH_MODE_OVERSCROLL || touchMode == TOUCH_MODE_OVERFLING) {
@@ -2847,14 +2841,6 @@
}
postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
} else {
- if (ev.getEdgeFlags() != 0 && motionPosition < 0) {
- // If we couldn't find a view to click on, but the down event
- // was touching the edge, we will bail out and try again.
- // This allows the edge correcting code in ViewAncestor to try to
- // find a nearby view to select
- return false;
- }
-
if (mTouchMode == TOUCH_MODE_FLING) {
// Stopped a fling. It is a scroll.
createScrollingCache();
@@ -2888,7 +2874,11 @@
}
case MotionEvent.ACTION_MOVE: {
- final int pointerIndex = ev.findPointerIndex(mActivePointerId);
+ int pointerIndex = ev.findPointerIndex(mActivePointerId);
+ if (pointerIndex == -1) {
+ pointerIndex = 0;
+ mActivePointerId = ev.getPointerId(pointerIndex);
+ }
final int y = (int) ev.getY(pointerIndex);
deltaY = y - mMotionY;
switch (mTouchMode) {
@@ -3464,7 +3454,11 @@
case MotionEvent.ACTION_MOVE: {
switch (mTouchMode) {
case TOUCH_MODE_DOWN:
- final int pointerIndex = ev.findPointerIndex(mActivePointerId);
+ int pointerIndex = ev.findPointerIndex(mActivePointerId);
+ if (pointerIndex == -1) {
+ pointerIndex = 0;
+ mActivePointerId = ev.getPointerId(pointerIndex);
+ }
final int y = (int) ev.getY(pointerIndex);
if (startScrollIfNeeded(y - mMotionY)) {
return true;
@@ -4521,7 +4515,6 @@
setSelectedPositionInt(INVALID_POSITION);
setNextSelectedPositionInt(INVALID_POSITION);
mSelectedTop = 0;
- mSelectorShowing = false;
}
}
@@ -4645,6 +4638,9 @@
childrenTop += getVerticalFadingEdgeLength();
}
}
+ // Don't ever focus a disabled item.
+ if (!mAdapter.isEnabled(i)) continue;
+
if (top >= childrenTop) {
// Found a view whose top is fully visisble
selectedPos = firstPosition + i;
diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java
index c2759e5..b9eb5ff 100644
--- a/core/java/android/widget/GridLayout.java
+++ b/core/java/android/widget/GridLayout.java
@@ -53,12 +53,12 @@
* container and grid index {@code N} is fixed to its trailing edge
* (after padding is taken into account).
*
- * <h4>Row and Column Groups</h4>
+ * <h4>Row and Column Specs</h4>
*
* Children occupy one or more contiguous cells, as defined
- * by their {@link GridLayout.LayoutParams#rowGroup rowGroup} and
- * {@link GridLayout.LayoutParams#columnGroup columnGroup} layout parameters.
- * Each group specifies the set of rows or columns that are to be
+ * by their {@link GridLayout.LayoutParams#rowSpec rowSpec} and
+ * {@link GridLayout.LayoutParams#columnSpec columnSpec} layout parameters.
+ * Each spec defines the set of rows or columns that are to be
* occupied; and how children should be aligned within the resulting group of cells.
* Although cells do not normally overlap in a GridLayout, GridLayout does
* not prevent children being defined to occupy the same cell or group of cells.
@@ -92,7 +92,7 @@
*
* <h4>Excess Space Distribution</h4>
*
- * A child's ability to stretch is controlled using the {@link Group#flexibility flexibility}
+ * A child's ability to stretch is controlled using the flexibility
* properties of its row and column groups.
* <p>
* <p>
@@ -167,8 +167,7 @@
// Misc constants
private static final String TAG = GridLayout.class.getName();
- private static final boolean DEBUG = false;
- private static final double GOLDEN_RATIO = (1 + Math.sqrt(5)) / 2;
+ static final boolean DEBUG = false;
private static final int PRF = 1;
// Defaults
@@ -178,8 +177,9 @@
private static final boolean DEFAULT_USE_DEFAULT_MARGINS = false;
private static final boolean DEFAULT_ORDER_PRESERVED = false;
private static final int DEFAULT_ALIGNMENT_MODE = ALIGN_MARGINS;
- // todo remove this
- private static final int DEFAULT_CONTAINER_MARGIN = 20;
+ private static final int DEFAULT_CONTAINER_MARGIN = 0;
+ private static final int DEFAULT_MARGIN = 8;
+ private static final int DEFAULT_CONTAINER_PADDING = 16;
private static final int MAX_SIZE = 100000;
// TypedArray indices
@@ -278,12 +278,12 @@
/**
* Returns the current number of rows. This is either the last value that was set
* with {@link #setRowCount(int)} or, if no such value was set, the maximum
- * value of each the upper bounds defined in {@link LayoutParams#rowGroup}.
+ * value of each the upper bounds defined in {@link LayoutParams#rowSpec}.
*
* @return the current number of rows
*
* @see #setRowCount(int)
- * @see LayoutParams#rowGroup
+ * @see LayoutParams#rowSpec
*
* @attr ref android.R.styleable#GridLayout_rowCount
*/
@@ -299,7 +299,7 @@
* @param rowCount the number of rows
*
* @see #getRowCount()
- * @see LayoutParams#rowGroup
+ * @see LayoutParams#rowSpec
*
* @attr ref android.R.styleable#GridLayout_rowCount
*/
@@ -310,12 +310,12 @@
/**
* Returns the current number of columns. This is either the last value that was set
* with {@link #setColumnCount(int)} or, if no such value was set, the maximum
- * value of each the upper bounds defined in {@link LayoutParams#columnGroup}.
+ * value of each the upper bounds defined in {@link LayoutParams#columnSpec}.
*
* @return the current number of columns
*
* @see #setColumnCount(int)
- * @see LayoutParams#columnGroup
+ * @see LayoutParams#columnSpec
*
* @attr ref android.R.styleable#GridLayout_columnCount
*/
@@ -331,7 +331,7 @@
* @param columnCount the number of columns.
*
* @see #getColumnCount()
- * @see LayoutParams#columnGroup
+ * @see LayoutParams#columnSpec
*
* @attr ref android.R.styleable#GridLayout_columnCount
*/
@@ -381,6 +381,10 @@
*/
public void setUseDefaultMargins(boolean useDefaultMargins) {
mUseDefaultMargins = useDefaultMargins;
+ if (useDefaultMargins) {
+ int padding = DEFAULT_CONTAINER_PADDING;
+ setPadding(padding, padding, padding, padding);
+ }
requestLayout();
}
@@ -518,6 +522,14 @@
return result;
}
+ private static int sum(int[] a) {
+ int result = 0;
+ for (int i = 0, N = a.length; i < N; i++) {
+ result += a[i];
+ }
+ return result;
+ }
+
private static <T> T[] append(T[] a, T[] b) {
T[] result = (T[]) Array.newInstance(a.getClass().getComponentType(), a.length + b.length);
System.arraycopy(a, 0, result, 0, a.length);
@@ -526,16 +538,10 @@
}
private int getDefaultMargin(View c, boolean horizontal, boolean leading) {
- // In the absence of any other information, calculate a default gap such
- // that, in a grid of identical components, the heights and the vertical
- // gaps are in the proportion of the golden ratio.
- // To effect this with equal margins at each edge, set each of the
- // four margin values to half this amount.
- return (int) (c.getMeasuredHeight() / GOLDEN_RATIO / 2);
+ return DEFAULT_MARGIN;
}
private int getDefaultMargin(View c, boolean isAtEdge, boolean horizontal, boolean leading) {
- // todo remove DEFAULT_CONTAINER_MARGIN. Use padding? Seek advice on Themes/Styles, etc.
return isAtEdge ? DEFAULT_CONTAINER_MARGIN : getDefaultMargin(c, horizontal, leading);
}
@@ -543,9 +549,9 @@
if (!mUseDefaultMargins) {
return 0;
}
- Group group = horizontal ? p.columnGroup : p.rowGroup;
+ Spec spec = horizontal ? p.columnSpec : p.rowSpec;
Axis axis = horizontal ? mHorizontalAxis : mVerticalAxis;
- Interval span = group.span;
+ Interval span = spec.span;
boolean isAtEdge = leading ? (span.min == 0) : (span.max == axis.getCount());
return getDefaultMargin(c, isAtEdge, horizontal, leading);
@@ -593,12 +599,12 @@
if (isGone(c)) continue;
LayoutParams lp = getLayoutParams1(c);
- final Group colGroup = lp.columnGroup;
- final Interval cols = colGroup.span;
+ final Spec colSpec = lp.columnSpec;
+ final Interval cols = colSpec.span;
final int colSpan = cols.size();
- final Group rowGroup = lp.rowGroup;
- final Interval rows = rowGroup.span;
+ final Spec rowSpec = lp.rowSpec;
+ final Interval rows = rowSpec.span;
final int rowSpan = rows.size();
if (horizontal) {
@@ -623,8 +629,8 @@
maxSize = max(maxSize, colSpan);
}
- lp.setColumnGroupSpan(new Interval(col, col + colSpan));
- lp.setRowGroupSpan(new Interval(row, row + rowSpan));
+ lp.setColumnSpecSpan(new Interval(col, col + colSpan));
+ lp.setRowSpecSpan(new Interval(row, row + rowSpan));
if (horizontal) {
col = col + colSpan;
@@ -737,7 +743,7 @@
}
// Draw margins
- paint.setColor(Color.YELLOW);
+ paint.setColor(Color.MAGENTA);
for (int i = 0; i < getChildCount(); i++) {
View c = getChildAt(i);
drawRectangle(canvas,
@@ -872,11 +878,11 @@
View c = getChildAt(i);
if (isGone(c)) continue;
LayoutParams lp = getLayoutParams(c);
- Group columnGroup = lp.columnGroup;
- Group rowGroup = lp.rowGroup;
+ Spec columnSpec = lp.columnSpec;
+ Spec rowSpec = lp.rowSpec;
- Interval colSpan = columnGroup.span;
- Interval rowSpan = rowGroup.span;
+ Interval colSpan = columnSpec.span;
+ Interval rowSpan = rowSpec.span;
int x1 = mHorizontalAxis.getLocationIncludingMargin(true, colSpan.min);
int y1 = mVerticalAxis.getLocationIncludingMargin(true, rowSpan.min);
@@ -890,8 +896,8 @@
int pWidth = getMeasurement(c, true);
int pHeight = getMeasurement(c, false);
- Alignment hAlign = columnGroup.alignment;
- Alignment vAlign = rowGroup.alignment;
+ Alignment hAlign = columnSpec.alignment;
+ Alignment vAlign = rowSpec.alignment;
int dx, dy;
@@ -961,7 +967,7 @@
public boolean countValid = false;
public boolean countWasExplicitySet = false;
- PackedMap<Group, Bounds> groupBounds;
+ PackedMap<Spec, Bounds> groupBounds;
public boolean groupBoundsValid = false;
PackedMap<Interval, MutableInt> forwardLinks;
@@ -998,9 +1004,9 @@
View c = getChildAt(i);
if (isGone(c)) continue;
LayoutParams params = getLayoutParams(c);
- Group g = horizontal ? params.columnGroup : params.rowGroup;
- count = max(count, g.span.min);
- count = max(count, g.span.max);
+ Spec spec = horizontal ? params.columnSpec : params.rowSpec;
+ count = max(count, spec.span.min);
+ count = max(count, spec.span.max);
}
return count == -1 ? UNDEFINED : count;
}
@@ -1027,17 +1033,17 @@
invalidateStructure();
}
- private PackedMap<Group, Bounds> createGroupBounds() {
- Assoc<Group, Bounds> assoc = Assoc.of(Group.class, Bounds.class);
+ private PackedMap<Spec, Bounds> createGroupBounds() {
+ Assoc<Spec, Bounds> assoc = Assoc.of(Spec.class, Bounds.class);
for (int i = 0, N = getChildCount(); i < N; i++) {
View c = getChildAt(i);
if (isGone(c)) {
- assoc.put(Group.GONE, Bounds.GONE);
+ assoc.put(Spec.GONE, Bounds.GONE);
} else {
LayoutParams lp = getLayoutParams(c);
- Group group = horizontal ? lp.columnGroup : lp.rowGroup;
- Bounds bounds = group.alignment.getBounds();
- assoc.put(group, bounds);
+ Spec spec = horizontal ? lp.columnSpec : lp.rowSpec;
+ Bounds bounds = spec.alignment.getBounds();
+ assoc.put(spec, bounds);
}
}
return assoc.pack();
@@ -1052,12 +1058,12 @@
View c = getChildAt(i);
if (isGone(c)) continue;
LayoutParams lp = getLayoutParams(c);
- Group g = horizontal ? lp.columnGroup : lp.rowGroup;
- groupBounds.getValue(i).include(c, g, GridLayout.this, this);
+ Spec spec = horizontal ? lp.columnSpec : lp.rowSpec;
+ groupBounds.getValue(i).include(c, spec, GridLayout.this, this);
}
}
- private PackedMap<Group, Bounds> getGroupBounds() {
+ private PackedMap<Spec, Bounds> getGroupBounds() {
if (groupBounds == null) {
groupBounds = createGroupBounds();
}
@@ -1071,7 +1077,7 @@
// Add values computed by alignment - taking the max of all alignments in each span
private PackedMap<Interval, MutableInt> createLinks(boolean min) {
Assoc<Interval, MutableInt> result = Assoc.of(Interval.class, MutableInt.class);
- Group[] keys = getGroupBounds().keys;
+ Spec[] keys = getGroupBounds().keys;
for (int i = 0, N = keys.length; i < N; i++) {
Interval span = min ? keys[i].span : keys[i].span.inverse();
result.put(span, new MutableInt());
@@ -1092,8 +1098,7 @@
MutableInt valueHolder = links.getValue(i);
if (min) {
valueHolder.value = max(valueHolder.value, size);
- }
- else {
+ } else {
valueHolder.value = -max(-valueHolder.value, size);
}
}
@@ -1236,8 +1241,8 @@
View c = getChildAt(i);
if (isGone(c)) continue;
LayoutParams lp = getLayoutParams(c);
- Group g = horizontal ? lp.columnGroup : lp.rowGroup;
- Interval span = g.span;
+ Spec spec = horizontal ? lp.columnSpec : lp.rowSpec;
+ Interval span = spec.span;
leadingEdgeCount[span.min]++;
trailingEdgeCount[span.max]++;
}
@@ -1436,8 +1441,8 @@
View c = getChildAt(i);
if (isGone(c)) continue;
LayoutParams lp = getLayoutParams(c);
- Group g = horizontal ? lp.columnGroup : lp.rowGroup;
- Interval span = g.span;
+ Spec spec = horizontal ? lp.columnSpec : lp.rowSpec;
+ Interval span = spec.span;
int index = leading ? span.min : span.max;
margins[index] = max(margins[index], getMargin(c, horizontal, leading));
}
@@ -1514,6 +1519,12 @@
}
private void setParentConstraints(int min, int max) {
+ if (mAlignmentMode != ALIGN_MARGINS) {
+ int margins = sum(getLeadingMargins()) + sum(getTrailingMargins());
+ min -= margins;
+ max -= margins;
+ }
+
parentMin.value = min;
parentMax.value = -max;
locationsValid = false;
@@ -1529,7 +1540,7 @@
int size = MeasureSpec.getSize(measureSpec);
switch (mode) {
case MeasureSpec.UNSPECIFIED: {
- return getMeasure(0, MAX_SIZE);
+ return getMeasure(0, MAX_SIZE);
}
case MeasureSpec.EXACTLY: {
return getMeasure(size, size);
@@ -1584,14 +1595,14 @@
* GridLayout supports both row and column spanning and arbitrary forms of alignment within
* each cell group. The fundamental parameters associated with each cell group are
* gathered into their vertical and horizontal components and stored
- * in the {@link #rowGroup} and {@link #columnGroup} layout parameters.
- * {@link Group Groups} are immutable structures and may be shared between the layout
+ * in the {@link #rowSpec} and {@link #columnSpec} layout parameters.
+ * {@link android.widget.GridLayout.Spec Specs} are immutable structures and may be shared between the layout
* parameters of different children.
* <p>
- * The row and column groups contain the leading and trailing indices along each axis
+ * The row and column specs contain the leading and trailing indices along each axis
* and together specify the four grid indices that delimit the cells of this cell group.
* <p>
- * The {@link Group#alignment alignment} fields of the row and column groups together specify
+ * The alignment properties of the row and column specs together specify
* both aspects of alignment within the cell group. It is also possible to specify a child's
* alignment within its cell group by using the {@link GridLayout.LayoutParams#setGravity(int)}
* method.
@@ -1620,10 +1631,10 @@
* {@link GridLayout#setUseDefaultMargins(boolean) useDefaultMargins} is
* {@code false}; otherwise {@link #UNDEFINED}, to
* indicate that a default value should be computed on demand. </li>
- * <li>{@link #rowGroup}{@code .span} = {@code [0, 1]} </li>
- * <li>{@link #rowGroup}{@code .alignment} = {@link #BASELINE} </li>
- * <li>{@link #columnGroup}{@code .span} = {@code [0, 1]} </li>
- * <li>{@link #columnGroup}{@code .alignment} = {@link #LEFT} </li>
+ * <li>{@link #rowSpec}{@code .span} = {@code [0, 1]} </li>
+ * <li>{@link #rowSpec}{@code .alignment} = {@link #BASELINE} </li>
+ * <li>{@link #columnSpec}{@code .span} = {@code [0, 1]} </li>
+ * <li>{@link #columnSpec}{@code .alignment} = {@link #LEFT} </li>
* </ul>
*
* @attr ref android.R.styleable#GridLayout_Layout_layout_row
@@ -1678,48 +1689,48 @@
// Instance variables
/**
- * The group that specifies the vertical characteristics of the cell group
+ * The spec that specifies the vertical characteristics of the cell group
* described by these layout parameters.
*/
- public Group rowGroup;
+ public Spec rowSpec;
/**
- * The group that specifies the horizontal characteristics of the cell group
+ * The spec that specifies the horizontal characteristics of the cell group
* described by these layout parameters.
*/
- public Group columnGroup;
+ public Spec columnSpec;
// Constructors
private LayoutParams(
int width, int height,
int left, int top, int right, int bottom,
- Group rowGroup, Group columnGroup) {
+ Spec rowSpec, Spec columnSpec) {
super(width, height);
setMargins(left, top, right, bottom);
- this.rowGroup = rowGroup;
- this.columnGroup = columnGroup;
+ this.rowSpec = rowSpec;
+ this.columnSpec = columnSpec;
}
/**
- * Constructs a new LayoutParams instance for this <code>rowGroup</code>
- * and <code>columnGroup</code>. All other fields are initialized with
+ * Constructs a new LayoutParams instance for this <code>rowSpec</code>
+ * and <code>columnSpec</code>. All other fields are initialized with
* default values as defined in {@link LayoutParams}.
*
- * @param rowGroup the rowGroup
- * @param columnGroup the columnGroup
+ * @param rowSpec the rowSpec
+ * @param columnSpec the columnSpec
*/
- public LayoutParams(Group rowGroup, Group columnGroup) {
+ public LayoutParams(Spec rowSpec, Spec columnSpec) {
this(DEFAULT_WIDTH, DEFAULT_HEIGHT,
DEFAULT_MARGIN, DEFAULT_MARGIN, DEFAULT_MARGIN, DEFAULT_MARGIN,
- rowGroup, columnGroup);
+ rowSpec, columnSpec);
}
/**
* Constructs a new LayoutParams with default values as defined in {@link LayoutParams}.
*/
public LayoutParams() {
- this(new Group(DEFAULT_SPAN, DEFAULT_ROW_ALIGNMENT),
- new Group(DEFAULT_SPAN, DEFAULT_COLUMN_ALIGNMENT));
+ this(new Spec(DEFAULT_SPAN, DEFAULT_ROW_ALIGNMENT, Spec.DEFAULT_FLEXIBILITY),
+ new Spec(DEFAULT_SPAN, DEFAULT_COLUMN_ALIGNMENT, Spec.DEFAULT_FLEXIBILITY));
}
// Copying constructors
@@ -1743,8 +1754,8 @@
*/
public LayoutParams(LayoutParams that) {
super(that);
- this.columnGroup = new Group(that.columnGroup);
- this.rowGroup = new Group(that.rowGroup);
+ this.columnSpec = new Spec(that.columnSpec);
+ this.rowSpec = new Spec(that.rowSpec);
}
// AttributeSet constructors
@@ -1836,14 +1847,14 @@
int column = a.getInt(COLUMN, DEFAULT_COLUMN);
int columnSpan = a.getInt(COLUMN_SPAN, DEFAULT_SPAN_SIZE);
Interval hSpan = new Interval(column, column + columnSpan);
- int hFlexibility = a.getInt(COLUMN_FLEXIBILITY, Group.DEFAULT_FLEXIBILITY);
- this.columnGroup = new Group(hSpan, getColAlignment(gravity, width), hFlexibility);
+ int hFlexibility = a.getInt(COLUMN_FLEXIBILITY, Spec.DEFAULT_FLEXIBILITY);
+ this.columnSpec = new Spec(hSpan, getColAlignment(gravity, width), hFlexibility);
int row = a.getInt(ROW, DEFAULT_ROW);
int rowSpan = a.getInt(ROW_SPAN, DEFAULT_SPAN_SIZE);
Interval vSpan = new Interval(row, row + rowSpan);
- int vFlexibility = a.getInt(ROW_FLEXIBILITY, Group.DEFAULT_FLEXIBILITY);
- this.rowGroup = new Group(vSpan, getRowAlignment(gravity, height), vFlexibility);
+ int vFlexibility = a.getInt(ROW_FLEXIBILITY, Spec.DEFAULT_FLEXIBILITY);
+ this.rowSpec = new Spec(vSpan, getRowAlignment(gravity, height), vFlexibility);
} finally {
a.recycle();
}
@@ -1858,8 +1869,8 @@
* @attr ref android.R.styleable#GridLayout_Layout_layout_gravity
*/
public void setGravity(int gravity) {
- columnGroup = columnGroup.copyWriteAlignment(getColAlignment(gravity, width));
- rowGroup = rowGroup.copyWriteAlignment(getRowAlignment(gravity, height));
+ columnSpec = columnSpec.copyWriteAlignment(getColAlignment(gravity, width));
+ rowSpec = rowSpec.copyWriteAlignment(getRowAlignment(gravity, height));
}
@Override
@@ -1868,12 +1879,12 @@
this.height = attributes.getLayoutDimension(heightAttr, DEFAULT_HEIGHT);
}
- private void setRowGroupSpan(Interval span) {
- rowGroup = rowGroup.copyWriteSpan(span);
+ private void setRowSpecSpan(Interval span) {
+ rowSpec = rowSpec.copyWriteSpan(span);
}
- private void setColumnGroupSpan(Interval span) {
- columnGroup = columnGroup.copyWriteSpan(span);
+ private void setColumnSpecSpan(Interval span) {
+ columnSpec = columnSpec.copyWriteSpan(span);
}
}
@@ -2019,14 +2030,14 @@
}
/*
- For each Group (with a given alignment) we need to store the amount of space required
+ For each group (with a given alignment) we need to store the amount of space required
before the alignment point and the amount of space required after it. One side of this
calculation is always 0 for LEADING and TRAILING alignments but we don't make use of this.
For CENTER and BASELINE alignments both sides are needed and in the BASELINE case no
simple optimisations are possible.
The general algorithm therefore is to create a Map (actually a PackedMap) from
- Group to Bounds and to loop through all Views in the group taking the maximum
+ group to Bounds and to loop through all Views in the group taking the maximum
of the values for each View.
*/
private static class Bounds {
@@ -2067,11 +2078,11 @@
return before - alignment.getAlignmentValue(c, size);
}
- protected void include(View c, Group group, GridLayout gridLayout, Axis axis) {
- this.flexibility &= group.flexibility;
+ protected void include(View c, Spec spec, GridLayout gridLayout, Axis axis) {
+ this.flexibility &= spec.flexibility;
int size = gridLayout.getMeasurementIncludingMargin(c, axis.horizontal);
// todo test this works correctly when the returned value is UNDEFINED
- int before = group.alignment.getAlignmentValue(c, size);
+ int before = spec.alignment.getAlignmentValue(c, size);
include(before, size - before);
}
@@ -2176,16 +2187,13 @@
}
/**
- * A group specifies either the horizontal or vertical characteristics of a group of
+ * A spec defines either the horizontal or vertical characteristics of a group of
* cells.
- * <p>
- * Groups are immutable and so may be shared between views with the same
- * {@code span} and {@code alignment}.
*/
- public static class Group {
+ public static class Spec {
private static final int DEFAULT_FLEXIBILITY = UNDEFINED_FLEXIBILITY;
- private static final Group GONE = new Group(Interval.GONE, Alignment.GONE);
+ private static final Spec GONE = new Spec(Interval.GONE, Alignment.GONE);
/**
* The grid indices of the leading and trailing edges of this cell group for the
@@ -2200,7 +2208,7 @@
* For row groups, this specifies the vertical alignment.
* For column groups, this specifies the horizontal alignment.
*/
- public final Alignment alignment;
+ final Alignment alignment;
/**
* The flexibility field tells GridLayout how to derive minimum and maximum size
@@ -2212,82 +2220,48 @@
*
* @see GridLayout#CAN_STRETCH
*/
- public int flexibility = DEFAULT_FLEXIBILITY;
+ final int flexibility;
- /**
- * Construct a new Group, {@code group}, where:
- * <ul>
- * <li> {@code group.span = span} </li>
- * <li> {@code group.alignment = alignment} </li>
- * </ul>
- *
- * @param span the span
- * @param alignment the alignment
- */
- private Group(Interval span, Alignment alignment) {
- this.span = span;
- this.alignment = alignment;
- }
-
- private Group(Interval span, Alignment alignment, int flexibility) {
+ private Spec(Interval span, Alignment alignment, int flexibility) {
this.span = span;
this.alignment = alignment;
this.flexibility = flexibility;
}
+ private Spec(Interval span, Alignment alignment) {
+ this(span, alignment, DEFAULT_FLEXIBILITY);
+ }
+
/* Copying constructor */
- private Group(Group that) {
- this.span = that.span;
- this.alignment = that.alignment;
- this.flexibility = that.flexibility;
+ private Spec(Spec that) {
+ this(that.span, that.alignment, that.flexibility);
+ }
+
+ Spec(int start, int size, Alignment alignment, int flexibility) {
+ this(new Interval(start, start + size), alignment, flexibility);
+ }
+
+ private Spec copyWriteSpan(Interval span) {
+ return new Spec(span, alignment, flexibility);
+ }
+
+ private Spec copyWriteAlignment(Alignment alignment) {
+ return new Spec(span, alignment, flexibility);
+ }
+
+ private Spec copyWriteFlexibility(int flexibility) {
+ return new Spec(span, alignment, flexibility);
}
/**
- * Construct a new Group, {@code group}, where:
- * <ul>
- * <li> {@code group.span = [start, start + size]} </li>
- * <li> {@code group.alignment = alignment} </li>
- * </ul>
- *
- * @param start the start
- * @param size the size
- * @param alignment the alignment
- */
- public Group(int start, int size, Alignment alignment) {
- this(new Interval(start, start + size), alignment);
- }
-
- /**
- * Construct a new Group, {@code group}, where:
- * <ul>
- * <li> {@code group.span = [start, start + 1]} </li>
- * <li> {@code group.alignment = alignment} </li>
- * </ul>
- *
- * @param start the start index
- * @param alignment the alignment
- */
- public Group(int start, Alignment alignment) {
- this(start, 1, alignment);
- }
-
- private Group copyWriteSpan(Interval span) {
- return new Group(span, alignment, flexibility);
- }
-
- private Group copyWriteAlignment(Alignment alignment) {
- return new Group(span, alignment, flexibility);
- }
-
- /**
- * Returns {@code true} if the {@link #getClass class}, {@link #alignment} and {@code span}
- * properties of this Group and the supplied parameter are pairwise equal,
+ * Returns {@code true} if the {@code class}, {@code alignment} and {@code span}
+ * properties of this Spec and the supplied parameter are pairwise equal,
* {@code false} otherwise.
*
- * @param that the object to compare this group with
+ * @param that the object to compare this spec with
*
* @return {@code true} if the specified object is equal to this
- * {@code Group}; {@code false} otherwise
+ * {@code Spec}; {@code false} otherwise
*/
@Override
public boolean equals(Object that) {
@@ -2298,12 +2272,12 @@
return false;
}
- Group group = (Group) that;
+ Spec spec = (Spec) that;
- if (!alignment.equals(group.alignment)) {
+ if (!alignment.equals(spec.alignment)) {
return false;
}
- if (!span.equals(group.span)) {
+ if (!span.equals(spec.span)) {
return false;
}
@@ -2319,12 +2293,93 @@
}
/**
+ * Temporary backward compatibility class for Launcher - to avoid
+ * dependent multi-project commit. This class will be deleted after
+ * AppsCustomizePagedView is updated to new API.
+ *
+ * @hide
+ */
+ @Deprecated
+ public static class Group extends Spec {
+ /**
+ * @deprecated Please replace with {@link #spec(int, int, Alignment)}
+ * @hide
+ */
+ @Deprecated
+ public Group(int start, int size, Alignment alignment) {
+ super(start, size, alignment, UNDEFINED_FLEXIBILITY);
+ }
+ }
+
+ /**
+ * Return a Spec, {@code spec}, where:
+ * <ul>
+ * <li> {@code spec.span = [start, start + size]} </li>
+ * <li> {@code spec.alignment = alignment} </li>
+ * <li> {@code spec.flexibility = flexibility} </li>
+ * </ul>
+ *
+ * @param start the start
+ * @param size the size
+ * @param alignment the alignment
+ * @param flexibility the flexibility
+ */
+ public static Spec spec(int start, int size, Alignment alignment, int flexibility) {
+ return new Spec(start, size, alignment, flexibility);
+ }
+
+ /**
+ * Return a Spec, {@code spec}, where:
+ * <ul>
+ * <li> {@code spec.span = [start, start + 1]} </li>
+ * <li> {@code spec.alignment = alignment} </li>
+ * <li> {@code spec.flexibility = flexibility} </li>
+ * </ul>
+ *
+ * @param start the start
+ * @param alignment the alignment
+ * @param flexibility the flexibility
+ */
+ public static Spec spec(int start, Alignment alignment, int flexibility) {
+ return spec(start, 1, alignment, flexibility);
+ }
+
+ /**
+ * Return a Spec, {@code spec}, where:
+ * <ul>
+ * <li> {@code spec.span = [start, start + size]} </li>
+ * <li> {@code spec.alignment = alignment} </li>
+ * </ul>
+ *
+ * @param start the start
+ * @param size the size
+ * @param alignment the alignment
+ */
+ public static Spec spec(int start, int size, Alignment alignment) {
+ return spec(start, size, alignment, Spec.DEFAULT_FLEXIBILITY);
+ }
+
+ /**
+ * Return a Spec, {@code spec}, where:
+ * <ul>
+ * <li> {@code spec.span = [start, start + 1]} </li>
+ * <li> {@code spec.alignment = alignment} </li>
+ * </ul>
+ *
+ * @param start the start index
+ * @param alignment the alignment
+ */
+ public static Spec spec(int start, Alignment alignment) {
+ return spec(start, 1, alignment);
+ }
+
+ /**
* Alignments specify where a view should be placed within a cell group and
* what size it should be.
* <p>
- * The {@link LayoutParams} class contains a {@link LayoutParams#rowGroup rowGroup}
- * and a {@link LayoutParams#columnGroup columnGroup} each of which contains an
- * {@link Group#alignment alignment}. Overall placement of the view in the cell
+ * The {@link LayoutParams} class contains a {@link LayoutParams#rowSpec rowSpec}
+ * and a {@link LayoutParams#columnSpec columnSpec} each of which contains an
+ * {@code alignment}. Overall placement of the view in the cell
* group is specified by the two alignments which act along each axis independently.
* <p>
* The GridLayout class defines the most common alignments used in general layout:
@@ -2425,8 +2480,8 @@
/**
* Indicates that a view should be <em>centered</em> with the other views in its cell group.
- * This constant may be used in both {@link LayoutParams#rowGroup rowGroups} and {@link
- * LayoutParams#columnGroup columnGroups}.
+ * This constant may be used in both {@link LayoutParams#rowSpec rowSpecs} and {@link
+ * LayoutParams#columnSpec columnSpecs}.
*/
public static final Alignment CENTER = new Alignment() {
public int getAlignmentValue(View view, int viewSize) {
@@ -2437,7 +2492,7 @@
/**
* Indicates that a view should be aligned with the <em>baselines</em>
* of the other views in its cell group.
- * This constant may only be used as an alignment in {@link LayoutParams#rowGroup rowGroups}.
+ * This constant may only be used as an alignment in {@link LayoutParams#rowSpec rowSpecs}.
*
* @see View#getBaseline()
*/
@@ -2488,8 +2543,8 @@
/**
* Indicates that a view should expanded to fit the boundaries of its cell group.
- * This constant may be used in both {@link LayoutParams#rowGroup rowGroups} and
- * {@link LayoutParams#columnGroup columnGroups}.
+ * This constant may be used in both {@link LayoutParams#rowSpec rowSpecs} and
+ * {@link LayoutParams#columnSpec columnSpecs}.
*/
public static final Alignment FILL = new Alignment() {
public int getAlignmentValue(View view, int viewSize) {
@@ -2513,42 +2568,30 @@
/**
* Indicates that a view requests precisely the size specified by its layout parameters.
*
- * @see Group#flexibility
- *
- * @hide
+ * @see Spec#flexibility
*/
- public static final int FIXED = 0;
+ private static final int NONE = 0;
/**
* Indicates that a view's size should lie between its minimum and the size specified by
* its layout parameters.
*
- * @see Group#flexibility
- *
- * @hide
+ * @see Spec#flexibility
*/
- public static final int CAN_SHRINK = 1;
+ private static final int CAN_SHRINK = 1;
/**
* Indicates that a view's size should be greater than or equal to the size specified by
* its layout parameters.
*
- * @see Group#flexibility
+ * @see Spec#flexibility
*/
public static final int CAN_STRETCH = 2;
/**
- * Indicates that a view will ignore its measurement, and can take any size that is greater
- * than its minimum.
- *
- * @see Group#flexibility
- */
- private static final int CAN_SHRINK_OR_STRETCH = CAN_SHRINK | CAN_STRETCH;
-
- /**
* A default value for flexibility.
*
- * @see Group#flexibility
+ * @see Spec#flexibility
*/
private static final int UNDEFINED_FLEXIBILITY = UNDEFINED | CAN_SHRINK | CAN_STRETCH;
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index 7c9be1e..b428301 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -498,13 +498,6 @@
@Override
public boolean onTouchEvent(MotionEvent ev) {
-
- if (ev.getAction() == MotionEvent.ACTION_DOWN && ev.getEdgeFlags() != 0) {
- // Don't handle edge touches immediately -- they may actually belong to one of our
- // descendants.
- return false;
- }
-
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index e7a9e41..1f29b16 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -3588,17 +3588,6 @@
return null;
}
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- //noinspection SimplifiableIfStatement
- if (mItemsCanFocus && ev.getAction() == MotionEvent.ACTION_DOWN && ev.getEdgeFlags() != 0) {
- // Don't handle edge touches immediately -- they may actually belong to one of our
- // descendants.
- return false;
- }
- return super.onTouchEvent(ev);
- }
-
/**
* Returns the set of checked items ids. The result is only valid if the
* choice mode has not been set to {@link #CHOICE_MODE_NONE}.
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index 4c47d37..867ebb4 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -53,6 +53,10 @@
// This ensures that we don't stay continually bound to the service and that it can be destroyed
// if we need the memory elsewhere in the system.
private static final int sUnbindServiceDelay = 5000;
+
+ // Default height for the default loading view, in case we cannot get inflate the first view
+ private static final int sDefaultLoadingViewHeight = 50;
+
// Type defs for controlling different messages across the main and worker message queues
private static final int sDefaultMessageType = 0;
private static final int sUnbindServiceMessageType = 1;
@@ -386,21 +390,39 @@
// Create a new loading view
synchronized (mCache) {
+ boolean customLoadingViewAvailable = false;
+
if (mUserLoadingView != null) {
- // A user-specified loading view
- View loadingView = mUserLoadingView.apply(parent.getContext(), parent);
- loadingView.setTagInternal(com.android.internal.R.id.rowTypeId, new Integer(0));
- layout.addView(loadingView);
- } else {
+ // Try to inflate user-specified loading view
+ try {
+ View loadingView = mUserLoadingView.apply(parent.getContext(), parent);
+ loadingView.setTagInternal(com.android.internal.R.id.rowTypeId,
+ new Integer(0));
+ layout.addView(loadingView);
+ customLoadingViewAvailable = true;
+ } catch (Exception e) {
+ Log.w(TAG, "Error inflating custom loading view, using default loading" +
+ "view instead", e);
+ }
+ }
+ if (!customLoadingViewAvailable) {
// A default loading view
// Use the size of the first row as a guide for the size of the loading view
if (mFirstViewHeight < 0) {
- View firstView = mFirstView.apply(parent.getContext(), parent);
- firstView.measure(
- MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
- MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
- mFirstViewHeight = firstView.getMeasuredHeight();
- mFirstView = null;
+ try {
+ View firstView = mFirstView.apply(parent.getContext(), parent);
+ firstView.measure(
+ MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
+ MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
+ mFirstViewHeight = firstView.getMeasuredHeight();
+ mFirstView = null;
+ } catch (Exception e) {
+ float density = mContext.getResources().getDisplayMetrics().density;
+ mFirstViewHeight = (int)
+ Math.round(sDefaultLoadingViewHeight * density);
+ mFirstView = null;
+ Log.w(TAG, "Error inflating first RemoteViews" + e);
+ }
}
// Compose the loading view text
@@ -937,24 +959,40 @@
indexMetaData.isRequested = true;
int typeId = indexMetaData.typeId;
- // Reuse the convert view where possible
- if (layout != null) {
- if (convertViewTypeId == typeId) {
- rv.reapply(context, convertViewChild);
- return layout;
+ try {
+ // Reuse the convert view where possible
+ if (layout != null) {
+ if (convertViewTypeId == typeId) {
+ rv.reapply(context, convertViewChild);
+ return layout;
+ }
+ layout.removeAllViews();
+ } else {
+ layout = new RemoteViewsFrameLayout(context);
}
- layout.removeAllViews();
- } else {
- layout = new RemoteViewsFrameLayout(context);
+
+ // Otherwise, create a new view to be returned
+ View newView = rv.apply(context, parent);
+ newView.setTagInternal(com.android.internal.R.id.rowTypeId,
+ new Integer(typeId));
+ layout.addView(newView);
+ return layout;
+
+ } catch (Exception e){
+ // We have to make sure that we successfully inflated the RemoteViews, if not
+ // we return the loading view instead.
+ Log.w(TAG, "Error inflating RemoteViews at position: " + position + ", using" +
+ "loading view instead" + e);
+
+ RemoteViewsFrameLayout loadingView = null;
+ final RemoteViewsMetaData metaData = mCache.getMetaData();
+ synchronized (metaData) {
+ loadingView = metaData.createLoadingView(position, convertView, parent);
+ }
+ return loadingView;
+ } finally {
+ if (hasNewItems) loadNextIndexInBackground();
}
-
- // Otherwise, create a new view to be returned
- View newView = rv.apply(context, parent);
- newView.setTagInternal(com.android.internal.R.id.rowTypeId, new Integer(typeId));
- layout.addView(newView);
- if (hasNewItems) loadNextIndexInBackground();
-
- return layout;
} else {
// If the cache does not have the RemoteViews at this position, then create a
// loading view and queue the actual position to be loaded in the background
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 12775a4..191410b 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -506,13 +506,6 @@
@Override
public boolean onTouchEvent(MotionEvent ev) {
-
- if (ev.getAction() == MotionEvent.ACTION_DOWN && ev.getEdgeFlags() != 0) {
- // Don't handle edge touches immediately -- they may actually belong to one of our
- // descendants.
- return false;
- }
-
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index 243c605..cf5666c 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -500,7 +500,7 @@
@Override
public int getHeight() {
- return mActionView.getHeight();
+ return mContainerView.getHeight();
}
@Override
diff --git a/services/java/com/android/server/ProcessStats.java b/core/java/com/android/internal/os/ProcessStats.java
similarity index 99%
rename from services/java/com/android/server/ProcessStats.java
rename to core/java/com/android/internal/os/ProcessStats.java
index f693ed1..ea5ce09 100644
--- a/services/java/com/android/server/ProcessStats.java
+++ b/core/java/com/android/internal/os/ProcessStats.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.internal.os;
import static android.os.Process.*;
@@ -182,7 +182,7 @@
public String baseName;
public String name;
- int nameWidth;
+ public int nameWidth;
public long base_uptime;
public long rel_uptime;
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index 258ffa5..ea35006 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -116,7 +116,7 @@
bool forcePurgeable = false) {
int sampleSize = 1;
SkImageDecoder::Mode mode = SkImageDecoder::kDecodePixels_Mode;
- SkBitmap::Config prefConfig = SkBitmap::kNo_Config;
+ SkBitmap::Config prefConfig = SkBitmap::kARGB_8888_Config;
bool doDither = true;
bool isMutable = false;
bool isPurgeable = forcePurgeable ||
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 49eaf19..0397dfa 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1489,9 +1489,6 @@
android:excludeFromRecents="true">
</activity>
- <service android:name="com.android.server.LoadAverageService"
- android:exported="true" />
-
<service android:name="com.android.internal.service.wallpaper.ImageWallpaper"
android:permission="android.permission.BIND_WALLPAPER">
</service>
diff --git a/core/res/res/layout/list_menu_item_icon.xml b/core/res/res/layout/list_menu_item_icon.xml
index a885211..27dd9b8 100644
--- a/core/res/res/layout/list_menu_item_icon.xml
+++ b/core/res/res/layout/list_menu_item_icon.xml
@@ -21,6 +21,8 @@
android:layout_gravity="center_vertical"
android:layout_marginLeft="8dip"
android:layout_marginRight="-8dip"
- android:scaleType="center"
+ android:layout_marginTop="8dip"
+ android:layout_marginBottom="8dip"
+ android:scaleType="centerInside"
android:duplicateParentState="true" />
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index 0f04a67..bcf1991 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -22,6 +22,15 @@
<!-- Do not translate. These are all of the drawable resources that should be preloaded by
the zygote process before it starts forking application processes. -->
<array name="preloaded_drawables">
+ <item>@drawable/spinner_black_16</item>
+ <item>@drawable/spinner_black_20</item>
+ <item>@drawable/spinner_black_48</item>
+ <item>@drawable/spinner_black_76</item>
+ <item>@drawable/spinner_white_16</item>
+ <item>@drawable/spinner_white_48</item>
+ <item>@drawable/spinner_white_76</item>
+ <item>@drawable/toast_frame</item>
+ <item>@drawable/toast_frame_holo</item>
<item>@drawable/btn_check_on_selected</item>
<item>@drawable/btn_check_on_pressed_holo_light</item>
<item>@drawable/btn_check_on_pressed_holo_dark</item>
@@ -109,6 +118,11 @@
<item>@drawable/btn_default_disabled_holo_dark</item>
<item>@drawable/btn_default_disabled_focused_holo_light</item>
<item>@drawable/btn_default_disabled_focused_holo_dark</item>
+ <item>@drawable/btn_dropdown_disabled</item>
+ <item>@drawable/btn_dropdown_disabled_focused</item>
+ <item>@drawable/btn_dropdown_normal</item>
+ <item>@drawable/btn_dropdown_pressed</item>
+ <item>@drawable/btn_dropdown_selected</item>
<item>@drawable/btn_toggle_on_pressed_holo_light</item>
<item>@drawable/btn_toggle_on_pressed_holo_dark</item>
<item>@drawable/btn_toggle_on_normal_holo_light</item>
@@ -141,6 +155,10 @@
<item>@drawable/edit_text_holo_light</item>
<item>@drawable/edit_text_holo_dark</item>
<item>@drawable/edit_text</item>
+ <item>@drawable/expander_close_holo_dark</item>
+ <item>@drawable/expander_close_holo_light</item>
+ <item>@drawable/expander_ic_maximized</item>
+ <item>@drawable/expander_ic_minimized</item>
<item>@drawable/expander_group</item>
<item>@drawable/expander_group_holo_dark</item>
<item>@drawable/expander_group_holo_light</item>
@@ -157,6 +175,8 @@
<item>@drawable/menu_background_fill_parent_width</item>
<item>@drawable/menu_submenu_background</item>
<item>@drawable/menu_selector</item>
+ <item>@drawable/overscroll_edge</item>
+ <item>@drawable/overscroll_glow</item>
<item>@drawable/panel_background</item>
<item>@drawable/popup_bottom_bright</item>
<item>@drawable/popup_bottom_dark</item>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index cfc5041..9613712 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3349,7 +3349,7 @@
<!-- The row span: the difference between the bottom and top
boundaries delimiting the group of cells occupied by this view.
The default is one.
- See {@link android.widget.GridLayout.Group}. -->
+ See {@link android.widget.GridLayout.Spec}. -->
<attr name="layout_rowSpan" format="integer" min="1" />
<!-- The column boundary delimiting the left of the group of cells
occupied by this view. -->
@@ -3357,23 +3357,21 @@
<!-- The column span: the difference between the right and left
boundaries delimiting the group of cells occupied by this view.
The default is one.
- See {@link android.widget.GridLayout.Group}. -->
+ See {@link android.widget.GridLayout.Spec}. -->
<attr name="layout_columnSpan" format="integer" min="1" />
<!-- Gravity specifies how a component should be placed in its group of cells.
The default is LEFT | BASELINE.
See {@link android.widget.GridLayout.LayoutParams#setGravity(int)}. -->
<attr name="layout_gravity" />
<!-- A value specifying how much deficit or excess width this component can accomodate.
- The default is FIXED.
- See {@link android.widget.GridLayout.Group#flexibility}.-->
+ The default is FIXED. -->
<attr name="layout_columnFlexibility" >
<!-- If possible, width should be greater than or equal to the specified width.
See {@link android.widget.GridLayout#CAN_STRETCH}. -->
<enum name="canStretch" value="2" />
</attr>
<!-- A value specifying how much deficit or excess height this component can accomodate.
- The default is FIXED.
- See {@link android.widget.GridLayout.Group#flexibility}.-->
+ The default is FIXED. -->
<attr name="layout_rowFlexibility" >
<!-- If possible, height should be greater than or equal to the specified height.
See {@link android.widget.GridLayout#CAN_STRETCH}. -->
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index a5cd6e3..6b75146 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1672,6 +1672,7 @@
<style name="Widget.Holo.ProgressBar.Small" parent="Widget.ProgressBar.Small">
<item name="android:indeterminateDrawable">@android:drawable/progress_small_holo</item>
+ <item name="android:animationResolution">33</item>
</style>
<style name="Widget.Holo.ProgressBar.Small.Title">
@@ -1679,6 +1680,7 @@
<style name="Widget.Holo.ProgressBar.Large" parent="Widget.ProgressBar.Large">
<item name="android:indeterminateDrawable">@android:drawable/progress_large_holo</item>
+ <item name="android:animationResolution">33</item>
</style>
<style name="Widget.Holo.ProgressBar.Inverse">
diff --git a/include/gui/ISurfaceTexture.h b/include/gui/ISurfaceTexture.h
index e705c6f..5b5b731 100644
--- a/include/gui/ISurfaceTexture.h
+++ b/include/gui/ISurfaceTexture.h
@@ -104,6 +104,24 @@
// queued buffers will be retired in order.
// The default mode is asynchronous.
virtual status_t setSynchronousMode(bool enabled) = 0;
+
+ // connect attempts to connect a client API to the SurfaceTexture. This
+ // must be called before any other ISurfaceTexture methods are called except
+ // for getAllocator.
+ //
+ // This method will fail if the connect was previously called on the
+ // SurfaceTexture and no corresponding disconnect call was made.
+ virtual status_t connect(int api) = 0;
+
+ // disconnect attempts to disconnect a client API from the SurfaceTexture.
+ // Calling this method will cause any subsequent calls to other
+ // ISurfaceTexture methods to fail except for getAllocator and connect.
+ // Successfully calling connect after this will allow the other methods to
+ // succeed again.
+ //
+ // This method will fail if the the SurfaceTexture is not currently
+ // connected to the specified client API.
+ virtual status_t disconnect(int api) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index e36360c..4080f27 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -44,6 +44,7 @@
MIN_SYNC_BUFFER_SLOTS = MIN_UNDEQUEUED_BUFFERS
};
enum { NUM_BUFFER_SLOTS = 32 };
+ enum { NO_CONNECTED_API = 0 };
struct FrameAvailableListener : public virtual RefBase {
// onFrameAvailable() is called from queueBuffer() each time an
@@ -97,6 +98,24 @@
// The default mode is asynchronous.
virtual status_t setSynchronousMode(bool enabled);
+ // connect attempts to connect a client API to the SurfaceTexture. This
+ // must be called before any other ISurfaceTexture methods are called except
+ // for getAllocator.
+ //
+ // This method will fail if the connect was previously called on the
+ // SurfaceTexture and no corresponding disconnect call was made.
+ virtual status_t connect(int api);
+
+ // disconnect attempts to disconnect a client API from the SurfaceTexture.
+ // Calling this method will cause any subsequent calls to other
+ // ISurfaceTexture methods to fail except for getAllocator and connect.
+ // Successfully calling connect after this will allow the other methods to
+ // succeed again.
+ //
+ // This method will fail if the the SurfaceTexture is not currently
+ // connected to the specified client API.
+ virtual status_t disconnect(int api);
+
// updateTexImage sets the image contents of the target texture to that of
// the most recently queued buffer.
//
@@ -362,6 +381,11 @@
// mAllowSynchronousMode whether we allow synchronous mode or not
const bool mAllowSynchronousMode;
+ // mConnectedApi indicates the API that is currently connected to this
+ // SurfaceTexture. It defaults to NO_CONNECTED_API (= 0), and gets updated
+ // by the connect and disconnect methods.
+ int mConnectedApi;
+
// mDequeueCondition condition used for dequeueBuffer in synchronous mode
mutable Condition mDequeueCondition;
diff --git a/include/gui/SurfaceTextureClient.h b/include/gui/SurfaceTextureClient.h
index 9db7364..5ec469e 100644
--- a/include/gui/SurfaceTextureClient.h
+++ b/include/gui/SurfaceTextureClient.h
@@ -129,9 +129,6 @@
// a timestamp is auto-generated when queueBuffer is called.
int64_t mTimestamp;
- // mConnectedApi holds the currently connected API to this surface
- int mConnectedApi;
-
// mQueryWidth is the width returned by query(). It is set to width
// of the last dequeued buffer or to mReqWidth if no buffer was dequeued.
uint32_t mQueryWidth;
diff --git a/libs/gui/ISurfaceTexture.cpp b/libs/gui/ISurfaceTexture.cpp
index 16e3780..41434a4 100644
--- a/libs/gui/ISurfaceTexture.cpp
+++ b/libs/gui/ISurfaceTexture.cpp
@@ -41,6 +41,8 @@
GET_ALLOCATOR,
QUERY,
SET_SYNCHRONOUS_MODE,
+ CONNECT,
+ DISCONNECT,
};
@@ -154,7 +156,23 @@
return result;
}
+ virtual status_t connect(int api) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
+ data.writeInt32(api);
+ remote()->transact(CONNECT, data, &reply);
+ status_t result = reply.readInt32();
+ return result;
+ }
+ virtual status_t disconnect(int api) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
+ data.writeInt32(api);
+ remote()->transact(DISCONNECT, data, &reply);
+ status_t result = reply.readInt32();
+ return result;
+ }
};
IMPLEMENT_META_INTERFACE(SurfaceTexture, "android.gui.SurfaceTexture");
@@ -248,6 +266,20 @@
reply->writeInt32(res);
return NO_ERROR;
} break;
+ case CONNECT: {
+ CHECK_INTERFACE(ISurfaceTexture, data, reply);
+ int api = data.readInt32();
+ status_t res = connect(api);
+ reply->writeInt32(res);
+ return NO_ERROR;
+ } break;
+ case DISCONNECT: {
+ CHECK_INTERFACE(ISurfaceTexture, data, reply);
+ int api = data.readInt32();
+ status_t res = disconnect(api);
+ reply->writeInt32(res);
+ return NO_ERROR;
+ } break;
}
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 886a3fb..1410481 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -92,7 +92,8 @@
mNextTransform(0),
mTexName(tex),
mSynchronousMode(false),
- mAllowSynchronousMode(allowSynchronousMode) {
+ mAllowSynchronousMode(allowSynchronousMode),
+ mConnectedApi(NO_CONNECTED_API) {
LOGV("SurfaceTexture::SurfaceTexture");
sp<ISurfaceComposer> composer(ComposerService::getComposerService());
mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
@@ -493,6 +494,50 @@
return OK;
}
+status_t SurfaceTexture::connect(int api) {
+ LOGV("SurfaceTexture::connect");
+ Mutex::Autolock lock(mMutex);
+ int err = NO_ERROR;
+ switch (api) {
+ case NATIVE_WINDOW_API_EGL:
+ case NATIVE_WINDOW_API_CPU:
+ case NATIVE_WINDOW_API_MEDIA:
+ case NATIVE_WINDOW_API_CAMERA:
+ if (mConnectedApi != NO_CONNECTED_API) {
+ err = -EINVAL;
+ } else {
+ mConnectedApi = api;
+ }
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+ return err;
+}
+
+status_t SurfaceTexture::disconnect(int api) {
+ LOGV("SurfaceTexture::disconnect");
+ Mutex::Autolock lock(mMutex);
+ int err = NO_ERROR;
+ switch (api) {
+ case NATIVE_WINDOW_API_EGL:
+ case NATIVE_WINDOW_API_CPU:
+ case NATIVE_WINDOW_API_MEDIA:
+ case NATIVE_WINDOW_API_CAMERA:
+ if (mConnectedApi == api) {
+ mConnectedApi = NO_CONNECTED_API;
+ } else {
+ err = -EINVAL;
+ }
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+ return err;
+}
+
status_t SurfaceTexture::updateTexImage() {
LOGV("SurfaceTexture::updateTexImage");
Mutex::Autolock lock(mMutex);
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index e203035..f39cabf 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -27,7 +27,7 @@
const sp<ISurfaceTexture>& surfaceTexture):
mSurfaceTexture(surfaceTexture), mAllocator(0), mReqWidth(0),
mReqHeight(0), mReqFormat(0), mReqUsage(0),
- mTimestamp(NATIVE_WINDOW_TIMESTAMP_AUTO), mConnectedApi(0),
+ mTimestamp(NATIVE_WINDOW_TIMESTAMP_AUTO),
mQueryWidth(0), mQueryHeight(0), mQueryFormat(0),
mMutex() {
// Initialize the ANativeWindow function pointers.
@@ -327,45 +327,22 @@
int SurfaceTextureClient::connect(int api) {
LOGV("SurfaceTextureClient::connect");
Mutex::Autolock lock(mMutex);
- int err = NO_ERROR;
- switch (api) {
- case NATIVE_WINDOW_API_EGL:
- if (mConnectedApi) {
- err = -EINVAL;
- } else {
- mConnectedApi = api;
- }
- break;
- default:
- err = -EINVAL;
- break;
- }
- return err;
+ return mSurfaceTexture->connect(api);
}
int SurfaceTextureClient::disconnect(int api) {
LOGV("SurfaceTextureClient::disconnect");
Mutex::Autolock lock(mMutex);
- int err = NO_ERROR;
- switch (api) {
- case NATIVE_WINDOW_API_EGL:
- if (mConnectedApi == api) {
- mConnectedApi = 0;
- } else {
- err = -EINVAL;
- }
- break;
- default:
- err = -EINVAL;
- break;
- }
- return err;
+ return mSurfaceTexture->disconnect(api);
}
int SurfaceTextureClient::getConnectedApi() const
{
+ // XXX: This method will be going away shortly, and is currently bogus. It
+ // always returns "nothing is connected". It will go away once Surface gets
+ // updated to actually connect as the 'CPU' API when locking a buffer.
Mutex::Autolock lock(mMutex);
- return mConnectedApi;
+ return 0;
}
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
index 50312e7..d18c0a2 100644
--- a/libs/utils/Threads.cpp
+++ b/libs/utils/Threads.cpp
@@ -161,6 +161,7 @@
pthread_t thread;
int result = pthread_create(&thread, &attr,
(android_pthread_entry)entryFunction, userData);
+ pthread_attr_destroy(&attr);
if (result != 0) {
LOGE("androidCreateRawThreadEtc failed (entry=%p, res=%d, errno=%d)\n"
"(android threadPriority=%d)",
diff --git a/libs/utils/VectorImpl.cpp b/libs/utils/VectorImpl.cpp
index 87ae3d5..bfb37a6 100644
--- a/libs/utils/VectorImpl.cpp
+++ b/libs/utils/VectorImpl.cpp
@@ -252,13 +252,15 @@
"[%p] replace: index=%d, size=%d", this, (int)index, (int)size());
void* item = editItemLocation(index);
- if (item == 0)
- return NO_MEMORY;
- _do_destroy(item, 1);
- if (prototype == 0) {
- _do_construct(item, 1);
- } else {
- _do_copy(item, prototype, 1);
+ if (item != prototype) {
+ if (item == 0)
+ return NO_MEMORY;
+ _do_destroy(item, 1);
+ if (prototype == 0) {
+ _do_construct(item, 1);
+ } else {
+ _do_copy(item, prototype, 1);
+ }
}
return ssize_t(index);
}
@@ -347,9 +349,10 @@
// LOGV("_grow(this=%p, where=%d, amount=%d) count=%d, capacity=%d",
// this, (int)where, (int)amount, (int)mCount, (int)capacity());
- if (where > mCount)
- where = mCount;
-
+ LOG_ASSERT(where <= mCount,
+ "[%p] _grow: where=%d, amount=%d, count=%d",
+ this, (int)where, (int)amount, (int)mCount); // caller already checked
+
const size_t new_size = mCount + amount;
if (capacity() < new_size) {
const size_t new_capacity = max(kMinVectorCapacity, ((new_size*3)+1)/2);
@@ -366,10 +369,10 @@
SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize);
if (sb) {
void* array = sb->data();
- if (where>0) {
+ if (where != 0) {
_do_copy(array, mStorage, where);
}
- if (mCount>where) {
+ if (where != mCount) {
const void* from = reinterpret_cast<const uint8_t *>(mStorage) + where*mItemSize;
void* dest = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize;
_do_copy(dest, from, mCount-where);
@@ -379,15 +382,14 @@
}
}
} else {
- ssize_t s = mCount-where;
- if (s>0) {
- void* array = editArrayImpl();
- void* to = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize;
+ if (where != mCount) {
+ void* array = editArrayImpl();
const void* from = reinterpret_cast<const uint8_t *>(array) + where*mItemSize;
- _do_move_forward(to, from, s);
+ void* to = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize;
+ _do_move_forward(to, from, mCount - where);
}
}
- mCount += amount;
+ mCount = new_size;
void* free_space = const_cast<void*>(itemLocation(where));
return free_space;
}
@@ -400,14 +402,15 @@
// LOGV("_shrink(this=%p, where=%d, amount=%d) count=%d, capacity=%d",
// this, (int)where, (int)amount, (int)mCount, (int)capacity());
- if (where >= mCount)
- where = mCount - amount;
+ LOG_ASSERT(where + amount <= mCount,
+ "[%p] _shrink: where=%d, amount=%d, count=%d",
+ this, (int)where, (int)amount, (int)mCount); // caller already checked
const size_t new_size = mCount - amount;
if (new_size*3 < capacity()) {
const size_t new_capacity = max(kMinVectorCapacity, new_size*2);
// LOGV("shrink vector %p, new_capacity=%d", this, (int)new_capacity);
- if ((where == mCount-amount) &&
+ if ((where == new_size) &&
(mFlags & HAS_TRIVIAL_COPY) &&
(mFlags & HAS_TRIVIAL_DTOR))
{
@@ -418,31 +421,28 @@
SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize);
if (sb) {
void* array = sb->data();
- if (where>0) {
+ if (where != 0) {
_do_copy(array, mStorage, where);
}
- if (mCount > where+amount) {
+ if (where != new_size) {
const void* from = reinterpret_cast<const uint8_t *>(mStorage) + (where+amount)*mItemSize;
void* dest = reinterpret_cast<uint8_t *>(array) + where*mItemSize;
- _do_copy(dest, from, mCount-(where+amount));
+ _do_copy(dest, from, new_size - where);
}
release_storage();
mStorage = const_cast<void*>(array);
}
}
} else {
- void* array = editArrayImpl();
+ void* array = editArrayImpl();
void* to = reinterpret_cast<uint8_t *>(array) + where*mItemSize;
_do_destroy(to, amount);
- ssize_t s = mCount-(where+amount);
- if (s>0) {
+ if (where != new_size) {
const void* from = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize;
- _do_move_backward(to, from, s);
+ _do_move_backward(to, from, new_size - where);
}
}
-
- // adjust the number of items...
- mCount -= amount;
+ mCount = new_size;
}
size_t VectorImpl::itemSize() const {
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index b97c3c4..b20a6e9 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -32,24 +32,25 @@
* It allows to stream PCM audio buffers to the audio hardware for playback. This is
* achieved by "pushing" the data to the AudioTrack object using one of the
* {@link #write(byte[], int, int)} and {@link #write(short[], int, int)} methods.
- *
+ *
* <p>An AudioTrack instance can operate under two modes: static or streaming.<br>
* In Streaming mode, the application writes a continuous stream of data to the AudioTrack, using
- * one of the write() methods. These are blocking and return when the data has been transferred
- * from the Java layer to the native layer and queued for playback. The streaming mode
- * is most useful when playing blocks of audio data that for instance are:
+ * one of the {@code write()} methods. These are blocking and return when the data has been
+ * transferred from the Java layer to the native layer and queued for playback. The streaming
+ * mode is most useful when playing blocks of audio data that for instance are:
+ *
* <ul>
* <li>too big to fit in memory because of the duration of the sound to play,</li>
* <li>too big to fit in memory because of the characteristics of the audio data
* (high sampling rate, bits per sample ...)</li>
* <li>received or generated while previously queued audio is playing.</li>
* </ul>
+ *
* The static mode is to be chosen when dealing with short sounds that fit in memory and
- * that need to be played with the smallest latency possible. AudioTrack instances in static mode
- * can play the sound without the need to transfer the audio data from Java to native layer
- * each time the sound is to be played. The static mode will therefore be preferred for UI and
- * game sounds that are played often, and with the smallest overhead possible.
- *
+ * that need to be played with the smallest latency possible. The static mode will
+ * therefore be preferred for UI and game sounds that are played often, and with the
+ * smallest overhead possible.
+ *
* <p>Upon creation, an AudioTrack object initializes its associated audio buffer.
* The size of this buffer, specified during the construction, determines how long an AudioTrack
* can play before running out of data.<br>
@@ -816,6 +817,7 @@
//--------------------
/**
* Starts playing an AudioTrack.
+ *
* @throws IllegalStateException
*/
public void play()
@@ -832,6 +834,7 @@
/**
* Stops playing the audio data.
+ *
* @throws IllegalStateException
*/
public void stop()
@@ -848,7 +851,10 @@
}
/**
- * Pauses the playback of the audio data.
+ * Pauses the playback of the audio data. Data that has not been played
+ * back will not be discarded. Subsequent calls to {@link #play} will play
+ * this data back.
+ *
* @throws IllegalStateException
*/
public void pause()
@@ -871,9 +877,9 @@
//--------------------
/**
- * Flushes the audio data currently queued for playback.
+ * Flushes the audio data currently queued for playback. Any data that has
+ * not been played back will be discarded.
*/
-
public void flush() {
if (mState == STATE_INITIALIZED) {
// flush the data in native layer
@@ -883,9 +889,14 @@
}
/**
- * Writes the audio data to the audio hardware for playback.
+ * Writes the audio data to the audio hardware for playback. Will block until
+ * all data has been written to the audio mixer.
+ * Note that the actual playback of this data might occur after this function
+ * returns. This function is thread safe with respect to {@link #stop} calls,
+ * in which case all of the specified data might not be written to the mixer.
+ *
* @param audioData the array that holds the data to play.
- * @param offsetInBytes the offset expressed in bytes in audioData where the data to play
+ * @param offsetInBytes the offset expressed in bytes in audioData where the data to play
* starts.
* @param sizeInBytes the number of bytes to read in audioData after the offset.
* @return the number of bytes that were written or {@link #ERROR_INVALID_OPERATION}
@@ -914,7 +925,12 @@
/**
- * Writes the audio data to the audio hardware for playback.
+ * Writes the audio data to the audio hardware for playback. Will block until
+ * all data has been written to the audio mixer.
+ * Note that the actual playback of this data might occur after this function
+ * returns. This function is thread safe with respect to {@link #stop} calls,
+ * in which case all of the specified data might not be written to the mixer.
+ *
* @param audioData the array that holds the data to play.
* @param offsetInShorts the offset expressed in shorts in audioData where the data to play
* starts.
@@ -988,7 +1004,7 @@
/**
* Sets the send level of the audio track to the attached auxiliary effect
- * {@see #attachAuxEffect(int)}. The level value range is 0 to 1.0.
+ * {@link #attachAuxEffect(int)}. The level value range is 0 to 1.0.
* <p>By default the send level is 0, so even if an effect is attached to the player
* this method must be called for the effect to be applied.
* <p>Note that the passed level value is a raw scalar. UI controls should be scaled
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index e89be08..8c8569a 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -707,7 +707,9 @@
map.put(MediaStore.MediaColumns.MIME_TYPE, mMimeType);
map.put(MediaStore.MediaColumns.IS_DRM, mIsDrm);
- if (!mNoMedia) {
+ if (mNoMedia) {
+ map.put(MediaStore.MediaColumns.NO_MEDIA, true);
+ } else {
if (MediaFile.isVideoFileType(mFileType)) {
map.put(Video.Media.ARTIST, (mArtist != null && mArtist.length() > 0
? mArtist : MediaStore.UNKNOWN_STRING));
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 77c25d1..0098537 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -453,7 +453,6 @@
}
void AwesomePlayer::reset() {
- LOGI("reset");
Mutex::Autolock autoLock(mLock);
reset_l();
}
@@ -467,10 +466,8 @@
Playback::STOP, 0);
mDecryptHandle = NULL;
mDrmManagerClient = NULL;
- LOGI("DRM manager client stopped");
}
-
if (mFlags & PLAYING) {
uint32_t params = IMediaPlayerService::kBatteryDataTrackDecoder;
if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) {
@@ -503,7 +500,6 @@
mPreparedCondition.wait(mLock);
}
- LOGI("cancel player events");
cancelPlayerEvents();
mWVMExtractor.clear();
@@ -890,7 +886,11 @@
CHECK(!(mFlags & AUDIO_RUNNING));
if (mVideoSource == NULL) {
- status_t err = startAudioPlayer_l();
+ // We don't want to post an error notification at this point,
+ // the error returned from MediaPlayer::start() will suffice.
+
+ status_t err = startAudioPlayer_l(
+ false /* sendErrorNotification */);
if (err != OK) {
delete mAudioPlayer;
@@ -940,7 +940,7 @@
return OK;
}
-status_t AwesomePlayer::startAudioPlayer_l() {
+status_t AwesomePlayer::startAudioPlayer_l(bool sendErrorNotification) {
CHECK(!(mFlags & AUDIO_RUNNING));
if (mAudioSource == NULL || mAudioPlayer == NULL) {
@@ -958,7 +958,10 @@
true /* sourceAlreadyStarted */);
if (err != OK) {
- notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
+ if (sendErrorNotification) {
+ notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
+ }
+
return err;
}
@@ -1684,7 +1687,7 @@
if (mAudioPlayer != NULL && !(mFlags & (AUDIO_RUNNING | SEEK_PREVIEW))) {
status_t err = startAudioPlayer_l();
if (err != OK) {
- LOGE("Startung the audio player failed w/ err %d", err);
+ LOGE("Starting the audio player failed w/ err %d", err);
return;
}
}
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index b7b0dc0f..5cab60e 100755
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -3539,7 +3539,7 @@
}
status_t OMXCodec::stop() {
- CODEC_LOGI("stop mState=%d", mState);
+ CODEC_LOGV("stop mState=%d", mState);
Mutex::Autolock autoLock(mLock);
@@ -3601,7 +3601,6 @@
mLeftOverBuffer = NULL;
}
- CODEC_LOGI("stopping video source");
mSource->stop();
CODEC_LOGI("stopped in state %d", mState);
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index e069b4d..95f2ae8 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -291,7 +291,7 @@
void finishSeekIfNecessary(int64_t videoTimeUs);
void ensureCacheIsFetching_l();
- status_t startAudioPlayer_l();
+ status_t startAudioPlayer_l(bool sendErrorNotification = true);
void postAudioSeekComplete_l();
void shutdownVideoDecoder_l();
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 26ea225..d32df6e 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -30,6 +30,15 @@
<service android:name=".screenshot.TakeScreenshotService"
android:exported="false" />
+ <service android:name=".LoadAverageService"
+ android:exported="true" />
+
+ <receiver android:name=".BootReceiver" >
+ <intent-filter>
+ <action android:name="android.intent.action.BOOT_COMPLETED" />
+ </intent-filter>
+ </receiver>
+
<activity android:name=".usb.UsbStorageActivity"
android:excludeFromRecents="true">
</activity>
diff --git a/packages/SystemUI/src/com/android/systemui/BootReceiver.java b/packages/SystemUI/src/com/android/systemui/BootReceiver.java
new file mode 100644
index 0000000..de005aa
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/BootReceiver.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui;
+
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.provider.Settings;
+import android.util.Slog;
+
+/**
+ * Performs a number of miscellaneous, non-system-critical actions
+ * after the system has finished booting.
+ */
+public class BootReceiver extends BroadcastReceiver {
+ private static final String TAG = "SystemUIBootReceiver";
+
+ @Override
+ public void onReceive(final Context context, Intent intent) {
+ try {
+ // Start the load average overlay, if activated
+ ContentResolver res = context.getContentResolver();
+ if (Settings.System.getInt(res, Settings.System.SHOW_PROCESSES, 0) != 0) {
+ Intent loadavg = new Intent(context, com.android.systemui.LoadAverageService.class);
+ context.startService(loadavg);
+ }
+ } catch (Exception e) {
+ Slog.e(TAG, "Can't start load average service", e);
+ }
+ }
+}
diff --git a/services/java/com/android/server/LoadAverageService.java b/packages/SystemUI/src/com/android/systemui/LoadAverageService.java
similarity index 98%
rename from services/java/com/android/server/LoadAverageService.java
rename to packages/SystemUI/src/com/android/systemui/LoadAverageService.java
index e05b570..67dc3cd 100644
--- a/services/java/com/android/server/LoadAverageService.java
+++ b/packages/SystemUI/src/com/android/systemui/LoadAverageService.java
@@ -14,7 +14,9 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.systemui;
+
+import com.android.internal.os.ProcessStats;
import android.app.Service;
import android.content.Context;
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index 8ba235b..935f4ad 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -689,13 +689,11 @@
switch (simState) {
case ABSENT:
- case PERM_DISABLED:
// only force lock screen in case of missing sim if user hasn't
// gone through setup wizard
if (!mUpdateMonitor.isDeviceProvisioned()) {
if (!isShowing()) {
- if (DEBUG) Log.d(TAG, "INTENT_VALUE_ICC_ABSENT "
- + "or PERM_DISABLED and keygaurd isn't showing,"
+ if (DEBUG) Log.d(TAG, "ICC_ABSENT isn't showing,"
+ " we need to show the keyguard since the "
+ "device isn't provisioned yet.");
doKeyguard();
@@ -713,7 +711,17 @@
} else {
resetStateLocked();
}
-
+ break;
+ case PERM_DISABLED:
+ if (!isShowing()) {
+ if (DEBUG) Log.d(TAG, "PERM_DISABLED and "
+ + "keygaurd isn't showing.");
+ doKeyguard();
+ } else {
+ if (DEBUG) Log.d(TAG, "PERM_DISABLED, resetStateLocked to"
+ + "show permanently disabled message in lockscreen.");
+ resetStateLocked();
+ }
break;
case READY:
if (isShowing()) {
diff --git a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
index 75e799c..e177565 100644
--- a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
@@ -75,6 +75,7 @@
private StatusView mStatusView;
private final boolean mUseSystemIME = true; // TODO: Make configurable
+ private boolean mResuming; // used to prevent poking the wakelock during onResume()
// To avoid accidental lockout due to events while the device in in the pocket, ignore
// any passwords with length less than or equal to this length.
@@ -185,7 +186,9 @@
}
public void afterTextChanged(Editable s) {
- mCallback.pokeWakelock();
+ if (!mResuming) {
+ mCallback.pokeWakelock();
+ }
}
});
}
@@ -208,6 +211,7 @@
/** {@inheritDoc} */
public void onResume() {
+ mResuming = true;
// reset status
mStatusView.resetStatusInfo(mUpdateMonitor, mLockPatternUtils);
@@ -222,6 +226,7 @@
if (deadline != 0) {
handleAttemptLockout(deadline);
}
+ mResuming = false;
}
/** {@inheritDoc} */
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index dff0556..4be00c5 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -2240,7 +2240,7 @@
}
PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, false);
- if (st != null && st.menu != null) {
+ if (st != null && st.menu != null && mFeatureId < 0) {
st.menu.close();
}
}
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index 49cb864..b2fbcb1 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -181,25 +181,6 @@
| AMOTION_EVENT_BUTTON_TERTIARY);
}
-static int32_t calculateEdgeFlagsUsingPointerBounds(
- const sp<PointerControllerInterface>& pointerController, float x, float y) {
- int32_t edgeFlags = 0;
- float minX, minY, maxX, maxY;
- if (pointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
- if (x <= minX) {
- edgeFlags |= AMOTION_EVENT_EDGE_FLAG_LEFT;
- } else if (x >= maxX) {
- edgeFlags |= AMOTION_EVENT_EDGE_FLAG_RIGHT;
- }
- if (y <= minY) {
- edgeFlags |= AMOTION_EVENT_EDGE_FLAG_TOP;
- } else if (y >= maxY) {
- edgeFlags |= AMOTION_EVENT_EDGE_FLAG_BOTTOM;
- }
- }
- return edgeFlags;
-}
-
static float calculateCommonVector(float a, float b) {
if (a > 0 && b > 0) {
return a < b ? a : b;
@@ -1619,7 +1600,6 @@
}
int32_t motionEventAction;
- int32_t motionEventEdgeFlags;
int32_t lastButtonState, currentButtonState;
PointerProperties pointerProperties;
PointerCoords pointerCoords;
@@ -1697,8 +1677,6 @@
}
}
- motionEventEdgeFlags = AMOTION_EVENT_EDGE_FLAG_NONE;
-
pointerProperties.clear();
pointerProperties.id = 0;
pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_MOUSE;
@@ -1742,11 +1720,6 @@
mPointerController->getPosition(&x, &y);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
-
- if (motionEventAction == AMOTION_EVENT_ACTION_DOWN) {
- motionEventEdgeFlags = calculateEdgeFlagsUsingPointerBounds(
- mPointerController, x, y);
- }
} else {
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
@@ -1771,7 +1744,7 @@
// Send motion event.
int32_t metaState = mContext->getGlobalMetaState();
getDispatcher()->notifyMotion(when, getDeviceId(), mSource, policyFlags,
- motionEventAction, 0, metaState, currentButtonState, motionEventEdgeFlags,
+ motionEventAction, 0, metaState, currentButtonState, 0,
1, &pointerProperties, &pointerCoords, mXPrecision, mYPrecision, downTime);
// Send hover move after UP to tell the application that the mouse is hovering now.
@@ -3168,9 +3141,8 @@
}
// Update current touch coordinates.
- int32_t edgeFlags;
float xPrecision, yPrecision;
- prepareTouches(&edgeFlags, &xPrecision, &yPrecision);
+ prepareTouches(&xPrecision, &yPrecision);
// Dispatch motions.
BitSet32 currentIdBits = mCurrentTouch.idBits;
@@ -3239,13 +3211,10 @@
if (dispatchedIdBits.count() == 1) {
// First pointer is going down. Set down time.
mDownTime = when;
- } else {
- // Only send edge flags with first pointer down.
- edgeFlags = AMOTION_EVENT_EDGE_FLAG_NONE;
}
dispatchMotion(when, policyFlags, mTouchSource,
- AMOTION_EVENT_ACTION_POINTER_DOWN, 0, metaState, buttonState, edgeFlags,
+ AMOTION_EVENT_ACTION_POINTER_DOWN, 0, metaState, buttonState, 0,
mCurrentTouchProperties, mCurrentTouchCoords,
mCurrentTouch.idToIndex, dispatchedIdBits, downId,
xPrecision, yPrecision, mDownTime);
@@ -3259,8 +3228,7 @@
}
}
-void TouchInputMapper::prepareTouches(int32_t* outEdgeFlags,
- float* outXPrecision, float* outYPrecision) {
+void TouchInputMapper::prepareTouches(float* outXPrecision, float* outYPrecision) {
uint32_t currentPointerCount = mCurrentTouch.pointerCount;
uint32_t lastPointerCount = mLastTouch.pointerCount;
@@ -3471,28 +3439,6 @@
properties.toolType = getTouchToolType(mCurrentTouch.pointers[i].isStylus);
}
- // Check edge flags by looking only at the first pointer since the flags are
- // global to the event.
- *outEdgeFlags = AMOTION_EVENT_EDGE_FLAG_NONE;
- if (lastPointerCount == 0 && currentPointerCount > 0) {
- const PointerData& in = mCurrentTouch.pointers[0];
-
- if (in.x <= mRawAxes.x.minValue) {
- *outEdgeFlags |= rotateEdgeFlag(AMOTION_EVENT_EDGE_FLAG_LEFT,
- mLocked.surfaceOrientation);
- } else if (in.x >= mRawAxes.x.maxValue) {
- *outEdgeFlags |= rotateEdgeFlag(AMOTION_EVENT_EDGE_FLAG_RIGHT,
- mLocked.surfaceOrientation);
- }
- if (in.y <= mRawAxes.y.minValue) {
- *outEdgeFlags |= rotateEdgeFlag(AMOTION_EVENT_EDGE_FLAG_TOP,
- mLocked.surfaceOrientation);
- } else if (in.y >= mRawAxes.y.maxValue) {
- *outEdgeFlags |= rotateEdgeFlag(AMOTION_EVENT_EDGE_FLAG_BOTTOM,
- mLocked.surfaceOrientation);
- }
- }
-
*outXPrecision = mLocked.orientedXPrecision;
*outYPrecision = mLocked.orientedYPrecision;
}
@@ -3640,19 +3586,12 @@
downGestureIdBits.clearBit(id);
dispatchedGestureIdBits.markBit(id);
- int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_NONE;
if (dispatchedGestureIdBits.count() == 1) {
- // First pointer is going down. Calculate edge flags and set down time.
- uint32_t index = mPointerGesture.currentGestureIdToIndex[id];
- const PointerCoords& downCoords = mPointerGesture.currentGestureCoords[index];
- edgeFlags = calculateEdgeFlagsUsingPointerBounds(mPointerController,
- downCoords.getAxisValue(AMOTION_EVENT_AXIS_X),
- downCoords.getAxisValue(AMOTION_EVENT_AXIS_Y));
mPointerGesture.downTime = when;
}
dispatchMotion(when, policyFlags, mPointerSource,
- AMOTION_EVENT_ACTION_POINTER_DOWN, 0, metaState, buttonState, edgeFlags,
+ AMOTION_EVENT_ACTION_POINTER_DOWN, 0, metaState, buttonState, 0,
mPointerGesture.currentGestureProperties,
mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
dispatchedGestureIdBits, id,
diff --git a/services/input/InputReader.h b/services/input/InputReader.h
index 69fa6b4..b1fdcf2 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -1176,7 +1176,7 @@
TouchResult consumeOffScreenTouches(nsecs_t when, uint32_t policyFlags);
void dispatchTouches(nsecs_t when, uint32_t policyFlags);
- void prepareTouches(int32_t* outEdgeFlags, float* outXPrecision, float* outYPrecision);
+ void prepareTouches(float* outXPrecision, float* outYPrecision);
void dispatchPointerGestures(nsecs_t when, uint32_t policyFlags, bool isTimeout);
bool preparePointerGestures(nsecs_t when,
bool* outCancelPreviousGesture, bool* outFinishPreviousGesture, bool isTimeout);
diff --git a/services/java/com/android/server/BootReceiver.java b/services/java/com/android/server/BootReceiver.java
index b9ff8d0..6665614 100644
--- a/services/java/com/android/server/BootReceiver.java
+++ b/services/java/com/android/server/BootReceiver.java
@@ -17,7 +17,6 @@
package com.android.server;
import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -28,7 +27,6 @@
import android.os.FileUtils;
import android.os.RecoverySystem;
import android.os.SystemProperties;
-import android.provider.Settings;
import android.util.Slog;
import java.io.File;
@@ -59,17 +57,6 @@
@Override
public void onReceive(final Context context, Intent intent) {
- try {
- // Start the load average overlay, if activated
- ContentResolver res = context.getContentResolver();
- if (Settings.System.getInt(res, Settings.System.SHOW_PROCESSES, 0) != 0) {
- Intent loadavg = new Intent(context, com.android.server.LoadAverageService.class);
- context.startService(loadavg);
- }
- } catch (Exception e) {
- Slog.e(TAG, "Can't start load average service", e);
- }
-
// Log boot events in the background to avoid blocking the main thread with I/O
new Thread() {
@Override
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 41450d2..bf5deb7 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -33,7 +33,9 @@
import android.net.IConnectivityManager;
import android.net.INetworkPolicyListener;
import android.net.INetworkPolicyManager;
+import android.net.LinkAddress;
import android.net.LinkProperties;
+import android.net.LinkProperties.CompareAddressesResult;
import android.net.MobileDataStateTracker;
import android.net.NetworkConfig;
import android.net.NetworkInfo;
@@ -76,6 +78,8 @@
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
@@ -92,6 +96,7 @@
public class ConnectivityService extends IConnectivityManager.Stub {
private static final boolean DBG = true;
+ private static final boolean VDBG = true;
private static final String TAG = "ConnectivityService";
private static final boolean LOGD_RULES = false;
@@ -126,6 +131,11 @@
private NetworkStateTracker mNetTrackers[];
/**
+ * The link properties that define the current links
+ */
+ private LinkProperties mCurrentLinkProperties[];
+
+ /**
* A per Net list of the PID's that requested access to the net
* used both as a refcount and for per-PID DNS selection
*/
@@ -332,6 +342,7 @@
mNetTrackers = new NetworkStateTracker[
ConnectivityManager.MAX_NETWORK_TYPE+1];
+ mCurrentLinkProperties = new LinkProperties[ConnectivityManager.MAX_NETWORK_TYPE+1];
mNetworkPreference = getPersistedNetworkPreference();
@@ -468,6 +479,7 @@
mNetConfigs[netType].radio);
continue;
}
+ mCurrentLinkProperties[netType] = mNetTrackers[netType].getLinkProperties();
}
IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
@@ -1563,6 +1575,8 @@
* right routing table entries exist.
*/
private void handleConnectivityChange(int netType, boolean doReset) {
+ int resetMask = doReset ? NetworkUtils.RESET_ALL_ADDRESSES : 0;
+
/*
* If a non-default network is enabled, add the host routes that
* will allow it's DNS servers to be accessed.
@@ -1570,6 +1584,45 @@
handleDnsConfigurationChange(netType);
if (mNetTrackers[netType].getNetworkInfo().isConnected()) {
+ LinkProperties newLp = mNetTrackers[netType].getLinkProperties();
+ LinkProperties curLp = mCurrentLinkProperties[netType];
+ mCurrentLinkProperties[netType] = newLp;
+ if (VDBG) {
+ log("handleConnectivityChange: changed linkProperty[" + netType + "]:" +
+ " doReset=" + doReset + " resetMask=" + resetMask +
+ "\n curLp=" + curLp +
+ "\n newLp=" + newLp);
+ }
+
+ if (curLp.isIdenticalInterfaceName(newLp)) {
+ CompareAddressesResult car = curLp.compareAddresses(newLp);
+ if ((car.removed.size() != 0) || (car.added.size() != 0)) {
+ for (LinkAddress linkAddr : car.removed) {
+ if (linkAddr.getAddress() instanceof Inet4Address) {
+ resetMask |= NetworkUtils.RESET_IPV4_ADDRESSES;
+ }
+ if (linkAddr.getAddress() instanceof Inet6Address) {
+ resetMask |= NetworkUtils.RESET_IPV6_ADDRESSES;
+ }
+ }
+ if (DBG) {
+ log("handleConnectivityChange: addresses changed" +
+ " linkProperty[" + netType + "]:" + " resetMask=" + resetMask +
+ "\n car=" + car);
+ }
+ } else {
+ if (DBG) {
+ log("handleConnectivityChange: address are the same reset per doReset" +
+ " linkProperty[" + netType + "]:" +
+ " resetMask=" + resetMask);
+ }
+ }
+ } else {
+ resetMask = NetworkUtils.RESET_ALL_ADDRESSES;
+ log("handleConnectivityChange: interface not not equivalent reset both" +
+ " linkProperty[" + netType + "]:" +
+ " resetMask=" + resetMask);
+ }
if (mNetConfigs[netType].isDefault()) {
handleApplyDefaultProxy(netType);
addDefaultRoute(mNetTrackers[netType]);
@@ -1597,15 +1650,13 @@
}
}
- if (doReset) {
+ if (doReset || resetMask != 0) {
LinkProperties linkProperties = mNetTrackers[netType].getLinkProperties();
if (linkProperties != null) {
String iface = linkProperties.getInterfaceName();
if (TextUtils.isEmpty(iface) == false) {
- if (DBG) {
- log("resetConnections(" + iface + ", NetworkUtils.RESET_ALL_ADDRESSES)");
- }
- NetworkUtils.resetConnections(iface, NetworkUtils.RESET_ALL_ADDRESSES);
+ if (DBG) log("resetConnections(" + iface + ", " + resetMask + ")");
+ NetworkUtils.resetConnections(iface, resetMask);
}
}
}
@@ -2477,8 +2528,23 @@
* @hide
*/
@Override
- public void protectVpn(ParcelFileDescriptor socket) {
- mVpn.protect(socket, getDefaultInterface());
+ public boolean protectVpn(ParcelFileDescriptor socket) {
+ try {
+ int type = mActiveDefaultNetwork;
+ if (ConnectivityManager.isNetworkTypeValid(type)) {
+ mVpn.protect(socket, mNetTrackers[type].getLinkProperties().getInterfaceName());
+ return true;
+ }
+ } catch (Exception e) {
+ // ignore
+ } finally {
+ try {
+ socket.close();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ return false;
}
/**
@@ -2526,19 +2592,6 @@
return mVpn.getLegacyVpnInfo();
}
- private String getDefaultInterface() {
- if (ConnectivityManager.isNetworkTypeValid(mActiveDefaultNetwork)) {
- NetworkStateTracker tracker = mNetTrackers[mActiveDefaultNetwork];
- if (tracker != null) {
- LinkProperties properties = tracker.getLinkProperties();
- if (properties != null) {
- return properties.getInterfaceName();
- }
- }
- }
- throw new IllegalStateException("No default interface");
- }
-
/**
* Callback for VPN subsystem. Currently VPN is not adapted to the service
* through NetworkStateTracker since it works differently. For example, it
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index fd93bcf..f546cf1 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -18,10 +18,10 @@
import com.android.internal.R;
import com.android.internal.os.BatteryStatsImpl;
+import com.android.internal.os.ProcessStats;
import com.android.server.AttributeCache;
import com.android.server.IntentResolver;
import com.android.server.ProcessMap;
-import com.android.server.ProcessStats;
import com.android.server.SystemServer;
import com.android.server.Watchdog;
import com.android.server.am.ActivityStack.ActivityState;
diff --git a/services/java/com/android/server/connectivity/Vpn.java b/services/java/com/android/server/connectivity/Vpn.java
index c185012..05e95a7 100644
--- a/services/java/com/android/server/connectivity/Vpn.java
+++ b/services/java/com/android/server/connectivity/Vpn.java
@@ -41,6 +41,9 @@
import com.android.internal.net.VpnConfig;
import com.android.server.ConnectivityService.VpnCallback;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charsets;
import java.util.Arrays;
@@ -67,22 +70,14 @@
/**
* Protect a socket from routing changes by binding it to the given
- * interface. The socket IS closed by this method.
+ * interface. The socket is NOT closed by this method.
*
* @param socket The socket to be bound.
* @param name The name of the interface.
*/
public void protect(ParcelFileDescriptor socket, String interfaze) {
- try {
- mContext.enforceCallingPermission(VPN, "protect");
- jniProtect(socket.getFd(), interfaze);
- } finally {
- try {
- socket.close();
- } catch (Exception e) {
- // ignore
- }
- }
+ mContext.enforceCallingPermission(VPN, "protect");
+ jniProtect(socket.getFd(), interfaze);
}
/**
@@ -192,10 +187,15 @@
}
// Configure the interface. Abort if any of these steps fails.
- ParcelFileDescriptor tun = ParcelFileDescriptor.adoptFd(
- jniConfigure(config.mtu, config.addresses, config.routes));
+ ParcelFileDescriptor tun = ParcelFileDescriptor.adoptFd(jniCreate(config.mtu));
try {
String interfaze = jniGetName(tun.getFd());
+ if (jniSetAddresses(interfaze, config.addresses) < 1) {
+ throw new IllegalArgumentException("At least one address must be specified");
+ }
+ if (config.routes != null) {
+ jniSetRoutes(interfaze, config.routes);
+ }
if (mInterface != null && !mInterface.equals(interfaze)) {
jniReset(mInterface);
}
@@ -222,18 +222,24 @@
}
// INetworkManagementEventObserver.Stub
- public void interfaceStatusChanged(String interfaze, boolean up) {
- }
-
- // INetworkManagementEventObserver.Stub
- public void interfaceLinkStateChanged(String interfaze, boolean up) {
- }
-
- // INetworkManagementEventObserver.Stub
public void interfaceAdded(String interfaze) {
}
// INetworkManagementEventObserver.Stub
+ public synchronized void interfaceStatusChanged(String interfaze, boolean up) {
+ if (!up && mLegacyVpnRunner != null) {
+ mLegacyVpnRunner.check(interfaze);
+ }
+ }
+
+ // INetworkManagementEventObserver.Stub
+ public synchronized void interfaceLinkStateChanged(String interfaze, boolean up) {
+ if (!up && mLegacyVpnRunner != null) {
+ mLegacyVpnRunner.check(interfaze);
+ }
+ }
+
+ // INetworkManagementEventObserver.Stub
public synchronized void interfaceRemoved(String interfaze) {
if (interfaze.equals(mInterface) && jniCheck(interfaze) == 0) {
mCallback.restore();
@@ -279,8 +285,10 @@
}
}
- private native int jniConfigure(int mtu, String addresses, String routes);
+ private native int jniCreate(int mtu);
private native String jniGetName(int tun);
+ private native int jniSetAddresses(String interfaze, String addresses);
+ private native int jniSetRoutes(String interfaze, String routes);
private native void jniReset(String interfaze);
private native int jniCheck(String interfaze);
private native void jniProtect(int socket, String interfaze);
@@ -323,11 +331,11 @@
*/
private class LegacyVpnRunner extends Thread {
private static final String TAG = "LegacyVpnRunner";
- private static final String NONE = "--";
private final VpnConfig mConfig;
private final String[] mDaemons;
private final String[][] mArguments;
+ private final String mOuterInterface;
private final LegacyVpnInfo mInfo;
private long mTimer = -1;
@@ -339,17 +347,27 @@
mArguments = new String[][] {racoon, mtpd};
mInfo = new LegacyVpnInfo();
+ // This is the interface which VPN is running on.
+ mOuterInterface = mConfig.interfaze;
+
// Legacy VPN is not a real package, so we use it to carry the key.
mInfo.key = mConfig.packagz;
mConfig.packagz = VpnConfig.LEGACY_VPN;
}
+ public void check(String interfaze) {
+ if (interfaze.equals(mOuterInterface)) {
+ Log.i(TAG, "Legacy VPN is going down with " + interfaze);
+ exit();
+ }
+ }
+
public void exit() {
// We assume that everything is reset after the daemons die.
+ interrupt();
for (String daemon : mDaemons) {
SystemProperties.set("ctl.stop", daemon);
}
- interrupt();
}
public LegacyVpnInfo getInfo() {
@@ -380,7 +398,7 @@
Thread.sleep(yield ? 200 : 1);
} else {
mInfo.state = LegacyVpnInfo.STATE_TIMEOUT;
- throw new IllegalStateException("time is up");
+ throw new IllegalStateException("Time is up");
}
}
@@ -404,12 +422,11 @@
}
}
- // Reset the properties.
- SystemProperties.set("vpn.dns", NONE);
- SystemProperties.set("vpn.via", NONE);
- while (!NONE.equals(SystemProperties.get("vpn.dns")) ||
- !NONE.equals(SystemProperties.get("vpn.via"))) {
- checkpoint(true);
+ // Clear the previous state.
+ File state = new File("/data/misc/vpn/state");
+ state.delete();
+ if (state.exists()) {
+ throw new IllegalStateException("Cannot delete the state");
}
// Check if we need to restart any of the daemons.
@@ -461,29 +478,34 @@
OutputStream out = socket.getOutputStream();
for (String argument : arguments) {
byte[] bytes = argument.getBytes(Charsets.UTF_8);
- if (bytes.length >= 0xFFFF) {
- throw new IllegalArgumentException("argument is too large");
+ if (bytes.length > 0xFFFF) {
+ throw new IllegalArgumentException("Argument is too large");
}
out.write(bytes.length >> 8);
out.write(bytes.length);
out.write(bytes);
checkpoint(false);
}
-
- // Send End-Of-Arguments.
- out.write(0xFF);
- out.write(0xFF);
out.flush();
+ socket.shutdownOutput();
+
+ // Wait for End-of-File.
+ InputStream in = socket.getInputStream();
+ while (true) {
+ try {
+ if (in.read() == -1) {
+ break;
+ }
+ } catch (Exception e) {
+ // ignore
+ }
+ checkpoint(true);
+ }
socket.close();
}
- // Now here is the beast from the old days. We check few
- // properties to figure out the current status. Ideally we
- // can read things back from the sockets and get rid of the
- // properties, but we have no time...
- while (NONE.equals(SystemProperties.get("vpn.dns")) ||
- NONE.equals(SystemProperties.get("vpn.via"))) {
-
+ // Wait for the daemons to create the new state.
+ while (!state.exists()) {
// Check if a running daemon is dead.
for (int i = 0; i < mDaemons.length; ++i) {
String daemon = mDaemons[i];
@@ -495,20 +517,45 @@
checkpoint(true);
}
- // Now we are connected. Get the interface.
- mConfig.interfaze = SystemProperties.get("vpn.via");
+ // Now we are connected. Read and parse the new state.
+ byte[] buffer = new byte[(int) state.length()];
+ if (new FileInputStream(state).read(buffer) != buffer.length) {
+ throw new IllegalStateException("Cannot read the state");
+ }
+ String[] parameters = new String(buffer, Charsets.UTF_8).split("\n", -1);
+ if (parameters.length != 6) {
+ throw new IllegalStateException("Cannot parse the state");
+ }
- // Get the DNS servers if they are not set in config.
+ // Set the interface and the addresses in the config.
+ mConfig.interfaze = parameters[0].trim();
+ mConfig.addresses = parameters[1].trim();
+
+ // Set the routes if they are not set in the config.
+ if (mConfig.routes == null || mConfig.routes.isEmpty()) {
+ mConfig.routes = parameters[2].trim();
+ }
+
+ // Set the DNS servers if they are not set in the config.
if (mConfig.dnsServers == null || mConfig.dnsServers.size() == 0) {
- String dnsServers = SystemProperties.get("vpn.dns").trim();
+ String dnsServers = parameters[3].trim();
if (!dnsServers.isEmpty()) {
mConfig.dnsServers = Arrays.asList(dnsServers.split(" "));
}
}
- // TODO: support search domains from ISAKMP mode config.
+ // Set the search domains if they are not set in the config.
+ if (mConfig.searchDomains == null || mConfig.searchDomains.size() == 0) {
+ String searchDomains = parameters[4].trim();
+ if (!searchDomains.isEmpty()) {
+ mConfig.searchDomains = Arrays.asList(searchDomains.split(" "));
+ }
+ }
- // The final step must be synchronized.
+ // Set the routes.
+ jniSetRoutes(mConfig.interfaze, mConfig.routes);
+
+ // Here is the last step and it must be done synchronously.
synchronized (Vpn.this) {
// Check if the thread is interrupted while we are waiting.
checkpoint(false);
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index d30b66b..0c78fe7 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -24,8 +24,8 @@
import static android.Manifest.permission.READ_PHONE_STATE;
import static android.content.Intent.ACTION_UID_REMOVED;
import static android.content.Intent.EXTRA_UID;
+import static android.net.ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
-import static android.net.ConnectivityManager.*;
import static android.net.ConnectivityManager.TYPE_MOBILE;
import static android.net.NetworkPolicy.LIMIT_DISABLED;
import static android.net.NetworkPolicy.WARNING_DISABLED;
@@ -42,7 +42,7 @@
import static android.net.NetworkPolicyManager.isUidValidForPolicy;
import static android.net.NetworkTemplate.MATCH_MOBILE_3G_LOWER;
import static android.net.NetworkTemplate.MATCH_MOBILE_4G;
-import static android.net.NetworkTemplate.MATCH_MOBILE_ALL;
+import static android.net.NetworkTemplate.buildTemplateMobileAll;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static com.android.internal.util.Preconditions.checkNotNull;
import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED;
@@ -678,7 +678,7 @@
time.setToNow();
final int cycleDay = time.monthDay;
- final NetworkTemplate template = new NetworkTemplate(MATCH_MOBILE_ALL, subscriberId);
+ final NetworkTemplate template = buildTemplateMobileAll(subscriberId);
mNetworkPolicy.add(
new NetworkPolicy(template, cycleDay, 4 * GB_IN_BYTES, LIMIT_DISABLED));
writePolicyLocked();
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index 54e94db..7ec6b81 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -73,11 +73,12 @@
import com.google.android.collect.Maps;
import com.google.android.collect.Sets;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileDescriptor;
-import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -719,10 +720,9 @@
// clear any existing stats and read from disk
mNetworkStats.clear();
- FileInputStream fis = null;
+ DataInputStream in = null;
try {
- fis = mNetworkFile.openRead();
- final DataInputStream in = new DataInputStream(fis);
+ in = new DataInputStream(new BufferedInputStream(mNetworkFile.openRead()));
// verify file magic header intact
final int magic = in.readInt();
@@ -751,7 +751,7 @@
} catch (IOException e) {
Slog.e(TAG, "problem reading network stats", e);
} finally {
- IoUtils.closeQuietly(fis);
+ IoUtils.closeQuietly(in);
}
}
@@ -768,10 +768,9 @@
// clear any existing stats and read from disk
mUidStats.clear();
- FileInputStream fis = null;
+ DataInputStream in = null;
try {
- fis = mUidFile.openRead();
- final DataInputStream in = new DataInputStream(fis);
+ in = new DataInputStream(new BufferedInputStream(mUidFile.openRead()));
// verify file magic header intact
final int magic = in.readInt();
@@ -826,7 +825,7 @@
} catch (IOException e) {
Slog.e(TAG, "problem reading uid stats", e);
} finally {
- IoUtils.closeQuietly(fis);
+ IoUtils.closeQuietly(in);
}
}
@@ -838,7 +837,7 @@
FileOutputStream fos = null;
try {
fos = mNetworkFile.startWrite();
- final DataOutputStream out = new DataOutputStream(fos);
+ final DataOutputStream out = new DataOutputStream(new BufferedOutputStream(fos));
out.writeInt(FILE_MAGIC);
out.writeInt(VERSION_NETWORK_INIT);
@@ -850,6 +849,7 @@
history.writeToStream(out);
}
+ out.flush();
mNetworkFile.finishWrite(fos);
} catch (IOException e) {
if (fos != null) {
@@ -871,7 +871,7 @@
FileOutputStream fos = null;
try {
fos = mUidFile.startWrite();
- final DataOutputStream out = new DataOutputStream(fos);
+ final DataOutputStream out = new DataOutputStream(new BufferedOutputStream(fos));
out.writeInt(FILE_MAGIC);
out.writeInt(VERSION_UID_WITH_TAG);
@@ -895,6 +895,7 @@
}
}
+ out.flush();
mUidFile.finishWrite(fos);
} catch (IOException e) {
if (fos != null) {
diff --git a/services/jni/com_android_server_connectivity_Vpn.cpp b/services/jni/com_android_server_connectivity_Vpn.cpp
index 5f920f1..d28a6b4 100644
--- a/services/jni/com_android_server_connectivity_Vpn.cpp
+++ b/services/jni/com_android_server_connectivity_Vpn.cpp
@@ -18,7 +18,6 @@
#define LOG_TAG "VpnJni"
#include <cutils/log.h>
-#include <cutils/properties.h>
#include <stdio.h>
#include <string.h>
@@ -54,7 +53,7 @@
#define SYSTEM_ERROR -1
#define BAD_ARGUMENT -2
-static int create_interface(char *name, int *index, int mtu)
+static int create_interface(int mtu)
{
int tun = open("/dev/tun", O_RDWR | O_NONBLOCK);
@@ -82,14 +81,6 @@
goto error;
}
- // Get interface index.
- if (ioctl(inet4, SIOGIFINDEX, &ifr4)) {
- LOGE("Cannot get index of %s: %s", ifr4.ifr_name, strerror(errno));
- goto error;
- }
-
- strncpy(name, ifr4.ifr_name, IFNAMSIZ);
- *index = ifr4.ifr_ifindex;
return tun;
error:
@@ -97,12 +88,40 @@
return SYSTEM_ERROR;
}
-static int set_addresses(const char *name, int index, const char *addresses)
+static int get_interface_name(char *name, int tun)
{
ifreq ifr4;
+ if (ioctl(tun, TUNGETIFF, &ifr4)) {
+ LOGE("Cannot get interface name: %s", strerror(errno));
+ return SYSTEM_ERROR;
+ }
+ strncpy(name, ifr4.ifr_name, IFNAMSIZ);
+ return 0;
+}
+
+static int get_interface_index(const char *name)
+{
+ ifreq ifr4;
+ strncpy(ifr4.ifr_name, name, IFNAMSIZ);
+ if (ioctl(inet4, SIOGIFINDEX, &ifr4)) {
+ LOGE("Cannot get index of %s: %s", name, strerror(errno));
+ return SYSTEM_ERROR;
+ }
+ return ifr4.ifr_ifindex;
+}
+
+static int set_addresses(const char *name, const char *addresses)
+{
+ int index = get_interface_index(name);
+ if (index < 0) {
+ return index;
+ }
+
+ ifreq ifr4;
memset(&ifr4, 0, sizeof(ifr4));
strncpy(ifr4.ifr_name, name, IFNAMSIZ);
ifr4.ifr_addr.sa_family = AF_INET;
+ ifr4.ifr_netmask.sa_family = AF_INET;
in6_ifreq ifr6;
memset(&ifr6, 0, sizeof(ifr6));
@@ -146,7 +165,7 @@
}
in_addr_t mask = prefix ? (~0 << (32 - prefix)) : 0;
- *as_in_addr(&ifr4.ifr_addr) = htonl(mask);
+ *as_in_addr(&ifr4.ifr_netmask) = htonl(mask);
if (ioctl(inet4, SIOCSIFNETMASK, &ifr4)) {
count = (errno == EINVAL) ? BAD_ARGUMENT : SYSTEM_ERROR;
break;
@@ -168,8 +187,13 @@
return count;
}
-static int set_routes(const char *name, int index, const char *routes)
+static int set_routes(const char *name, const char *routes)
{
+ int index = get_interface_index(name);
+ if (index < 0) {
+ return index;
+ }
+
rtentry rt4;
memset(&rt4, 0, sizeof(rt4));
rt4.rt_dev = (char *)name;
@@ -253,17 +277,6 @@
return count;
}
-static int get_interface_name(char *name, int tun)
-{
- ifreq ifr4;
- if (ioctl(tun, TUNGETIFF, &ifr4)) {
- LOGE("Cannot get interface name: %s", strerror(errno));
- return SYSTEM_ERROR;
- }
- strncpy(name, ifr4.ifr_name, IFNAMSIZ);
- return 0;
-}
-
static int reset_interface(const char *name)
{
ifreq ifr4;
@@ -309,53 +322,14 @@
}
}
-static jint configure(JNIEnv *env, jobject thiz,
- jint mtu, jstring jAddresses, jstring jRoutes)
+static jint create(JNIEnv *env, jobject thiz, jint mtu)
{
- char name[IFNAMSIZ];
- int index;
- int tun = create_interface(name, &index, mtu);
+ int tun = create_interface(mtu);
if (tun < 0) {
throwException(env, tun, "Cannot create interface");
return -1;
}
-
- const char *addresses = NULL;
- const char *routes = NULL;
- int count;
-
- // At least one address must be set.
- addresses = jAddresses ? env->GetStringUTFChars(jAddresses, NULL) : NULL;
- if (!addresses) {
- jniThrowNullPointerException(env, "address");
- goto error;
- }
- count = set_addresses(name, index, addresses);
- env->ReleaseStringUTFChars(jAddresses, addresses);
- if (count <= 0) {
- throwException(env, count, "Cannot set address");
- goto error;
- }
- LOGD("Configured %d address(es) on %s", count, name);
-
- // On the contrary, routes are optional.
- routes = jRoutes ? env->GetStringUTFChars(jRoutes, NULL) : NULL;
- if (routes) {
- count = set_routes(name, index, routes);
- env->ReleaseStringUTFChars(jRoutes, routes);
- if (count < 0) {
- throwException(env, count, "Cannot set route");
- goto error;
- }
- LOGD("Configured %d route(s) on %s", count, name);
- }
-
return tun;
-
-error:
- close(tun);
- LOGD("%s is destroyed", name);
- return -1;
}
static jstring getName(JNIEnv *env, jobject thiz, jint tun)
@@ -368,6 +342,72 @@
return env->NewStringUTF(name);
}
+static jint setAddresses(JNIEnv *env, jobject thiz, jstring jName,
+ jstring jAddresses)
+{
+ const char *name = NULL;
+ const char *addresses = NULL;
+ int count = -1;
+
+ name = jName ? env->GetStringUTFChars(jName, NULL) : NULL;
+ if (!name) {
+ jniThrowNullPointerException(env, "name");
+ goto error;
+ }
+ addresses = jAddresses ? env->GetStringUTFChars(jAddresses, NULL) : NULL;
+ if (!addresses) {
+ jniThrowNullPointerException(env, "addresses");
+ goto error;
+ }
+ count = set_addresses(name, addresses);
+ if (count < 0) {
+ throwException(env, count, "Cannot set address");
+ count = -1;
+ }
+
+error:
+ if (name) {
+ env->ReleaseStringUTFChars(jName, name);
+ }
+ if (addresses) {
+ env->ReleaseStringUTFChars(jAddresses, addresses);
+ }
+ return count;
+}
+
+static jint setRoutes(JNIEnv *env, jobject thiz, jstring jName,
+ jstring jRoutes)
+{
+ const char *name = NULL;
+ const char *routes = NULL;
+ int count = -1;
+
+ name = jName ? env->GetStringUTFChars(jName, NULL) : NULL;
+ if (!name) {
+ jniThrowNullPointerException(env, "name");
+ goto error;
+ }
+ routes = jRoutes ? env->GetStringUTFChars(jRoutes, NULL) : NULL;
+ if (!routes) {
+ jniThrowNullPointerException(env, "routes");
+ goto error;
+ }
+ count = set_routes(name, routes);
+ if (count < 0) {
+ throwException(env, count, "Cannot set route");
+ count = -1;
+ }
+
+error:
+ if (name) {
+ env->ReleaseStringUTFChars(jName, name);
+ }
+ if (routes) {
+ env->ReleaseStringUTFChars(jRoutes, routes);
+ }
+ return count;
+}
+
static void reset(JNIEnv *env, jobject thiz, jstring jName)
{
const char *name = jName ? env->GetStringUTFChars(jName, NULL) : NULL;
@@ -409,8 +449,10 @@
//------------------------------------------------------------------------------
static JNINativeMethod gMethods[] = {
- {"jniConfigure", "(ILjava/lang/String;Ljava/lang/String;)I", (void *)configure},
+ {"jniCreate", "(I)I", (void *)create},
{"jniGetName", "(I)Ljava/lang/String;", (void *)getName},
+ {"jniSetAddresses", "(Ljava/lang/String;Ljava/lang/String;)I", (void *)setAddresses},
+ {"jniSetRoutes", "(Ljava/lang/String;Ljava/lang/String;)I", (void *)setRoutes},
{"jniReset", "(Ljava/lang/String;)V", (void *)reset},
{"jniCheck", "(Ljava/lang/String;)I", (void *)check},
{"jniProtect", "(ILjava/lang/String;)V", (void *)protect},
diff --git a/services/sensorservice/SensorFusion.cpp b/services/sensorservice/SensorFusion.cpp
index 4ec0c8c..518a1bb7 100644
--- a/services/sensorservice/SensorFusion.cpp
+++ b/services/sensorservice/SensorFusion.cpp
@@ -28,23 +28,25 @@
mEnabled(false), mGyroTime(0)
{
sensor_t const* list;
- size_t count = mSensorDevice.getSensorList(&list);
- for (size_t i=0 ; i<count ; i++) {
- if (list[i].type == SENSOR_TYPE_ACCELEROMETER) {
- mAcc = Sensor(list + i);
+ ssize_t count = mSensorDevice.getSensorList(&list);
+ if (count > 0) {
+ for (size_t i=0 ; i<size_t(count) ; i++) {
+ if (list[i].type == SENSOR_TYPE_ACCELEROMETER) {
+ mAcc = Sensor(list + i);
+ }
+ if (list[i].type == SENSOR_TYPE_MAGNETIC_FIELD) {
+ mMag = Sensor(list + i);
+ }
+ if (list[i].type == SENSOR_TYPE_GYROSCOPE) {
+ mGyro = Sensor(list + i);
+ // 200 Hz for gyro events is a good compromise between precision
+ // and power/cpu usage.
+ mGyroRate = 200;
+ mTargetDelayNs = 1000000000LL/mGyroRate;
+ }
}
- if (list[i].type == SENSOR_TYPE_MAGNETIC_FIELD) {
- mMag = Sensor(list + i);
- }
- if (list[i].type == SENSOR_TYPE_GYROSCOPE) {
- mGyro = Sensor(list + i);
- // 200 Hz for gyro events is a good compromise between precision
- // and power/cpu usage.
- mGyroRate = 200;
- mTargetDelayNs = 1000000000LL/mGyroRate;
- }
+ mFusion.init();
}
- mFusion.init();
}
void SensorFusion::process(const sensors_event_t& event) {
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 64d214b..e0dce1f 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -70,73 +70,76 @@
SensorDevice& dev(SensorDevice::getInstance());
if (dev.initCheck() == NO_ERROR) {
- ssize_t orientationIndex = -1;
- bool hasGyro = false;
- uint32_t virtualSensorsNeeds =
- (1<<SENSOR_TYPE_GRAVITY) |
- (1<<SENSOR_TYPE_LINEAR_ACCELERATION) |
- (1<<SENSOR_TYPE_ROTATION_VECTOR);
sensor_t const* list;
- int count = dev.getSensorList(&list);
- mLastEventSeen.setCapacity(count);
- for (int i=0 ; i<count ; i++) {
- registerSensor( new HardwareSensor(list[i]) );
- switch (list[i].type) {
- case SENSOR_TYPE_ORIENTATION:
- orientationIndex = i;
- break;
- case SENSOR_TYPE_GYROSCOPE:
- hasGyro = true;
- break;
- case SENSOR_TYPE_GRAVITY:
- case SENSOR_TYPE_LINEAR_ACCELERATION:
- case SENSOR_TYPE_ROTATION_VECTOR:
- virtualSensorsNeeds &= ~(1<<list[i].type);
- break;
+ ssize_t count = dev.getSensorList(&list);
+ if (count > 0) {
+ ssize_t orientationIndex = -1;
+ bool hasGyro = false;
+ uint32_t virtualSensorsNeeds =
+ (1<<SENSOR_TYPE_GRAVITY) |
+ (1<<SENSOR_TYPE_LINEAR_ACCELERATION) |
+ (1<<SENSOR_TYPE_ROTATION_VECTOR);
+
+ mLastEventSeen.setCapacity(count);
+ for (ssize_t i=0 ; i<count ; i++) {
+ registerSensor( new HardwareSensor(list[i]) );
+ switch (list[i].type) {
+ case SENSOR_TYPE_ORIENTATION:
+ orientationIndex = i;
+ break;
+ case SENSOR_TYPE_GYROSCOPE:
+ hasGyro = true;
+ break;
+ case SENSOR_TYPE_GRAVITY:
+ case SENSOR_TYPE_LINEAR_ACCELERATION:
+ case SENSOR_TYPE_ROTATION_VECTOR:
+ virtualSensorsNeeds &= ~(1<<list[i].type);
+ break;
+ }
}
- }
- // it's safe to instantiate the SensorFusion object here
- // (it wants to be instantiated after h/w sensors have been
- // registered)
- const SensorFusion& fusion(SensorFusion::getInstance());
+ // it's safe to instantiate the SensorFusion object here
+ // (it wants to be instantiated after h/w sensors have been
+ // registered)
+ const SensorFusion& fusion(SensorFusion::getInstance());
- if (hasGyro) {
- // Always instantiate Android's virtual sensors. Since they are
- // instantiated behind sensors from the HAL, they won't
- // interfere with applications, unless they looks specifically
- // for them (by name).
+ if (hasGyro) {
+ // Always instantiate Android's virtual sensors. Since they are
+ // instantiated behind sensors from the HAL, they won't
+ // interfere with applications, unless they looks specifically
+ // for them (by name).
- registerVirtualSensor( new RotationVectorSensor() );
- registerVirtualSensor( new GravitySensor(list, count) );
- registerVirtualSensor( new LinearAccelerationSensor(list, count) );
+ registerVirtualSensor( new RotationVectorSensor() );
+ registerVirtualSensor( new GravitySensor(list, count) );
+ registerVirtualSensor( new LinearAccelerationSensor(list, count) );
- // these are optional
- registerVirtualSensor( new OrientationSensor() );
- registerVirtualSensor( new CorrectedGyroSensor(list, count) );
+ // these are optional
+ registerVirtualSensor( new OrientationSensor() );
+ registerVirtualSensor( new CorrectedGyroSensor(list, count) );
- // virtual debugging sensors...
- char value[PROPERTY_VALUE_MAX];
- property_get("debug.sensors", value, "0");
- if (atoi(value)) {
- registerVirtualSensor( new GyroDriftSensor() );
+ // virtual debugging sensors...
+ char value[PROPERTY_VALUE_MAX];
+ property_get("debug.sensors", value, "0");
+ if (atoi(value)) {
+ registerVirtualSensor( new GyroDriftSensor() );
+ }
}
- }
- // build the sensor list returned to users
- mUserSensorList = mSensorList;
- if (hasGyro &&
- (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR))) {
- // if we have the fancy sensor fusion, and it's not provided by the
- // HAL, use our own (fused) orientation sensor by removing the
- // HAL supplied one form the user list.
- if (orientationIndex >= 0) {
- mUserSensorList.removeItemsAt(orientationIndex);
+ // build the sensor list returned to users
+ mUserSensorList = mSensorList;
+ if (hasGyro &&
+ (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR))) {
+ // if we have the fancy sensor fusion, and it's not provided by the
+ // HAL, use our own (fused) orientation sensor by removing the
+ // HAL supplied one form the user list.
+ if (orientationIndex >= 0) {
+ mUserSensorList.removeItemsAt(orientationIndex);
+ }
}
- }
- run("SensorService", PRIORITY_URGENT_DISPLAY);
- mInitCheck = NO_ERROR;
+ run("SensorService", PRIORITY_URGENT_DISPLAY);
+ mInitCheck = NO_ERROR;
+ }
}
}
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index 33fd355..504ba42 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -27,7 +27,6 @@
import static android.net.NetworkPolicyManager.computeLastCycleBoundary;
import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
-import static android.net.NetworkTemplate.MATCH_WIFI;
import static org.easymock.EasyMock.anyInt;
import static org.easymock.EasyMock.aryEq;
import static org.easymock.EasyMock.capture;
@@ -88,7 +87,7 @@
private static final long TEST_START = 1194220800000L;
private static final String TEST_IFACE = "test0";
- private static NetworkTemplate sTemplateWifi = new NetworkTemplate(MATCH_WIFI, null);
+ private static NetworkTemplate sTemplateWifi = NetworkTemplate.buildTemplateWifi();
private BroadcastInterceptingContext mServiceContext;
private File mPolicyDir;
diff --git a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
index ac74063..bd80af9 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
@@ -25,8 +25,8 @@
import static android.net.NetworkStats.IFACE_ALL;
import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
-import static android.net.NetworkTemplate.MATCH_MOBILE_ALL;
-import static android.net.NetworkTemplate.MATCH_WIFI;
+import static android.net.NetworkTemplate.buildTemplateMobileAll;
+import static android.net.NetworkTemplate.buildTemplateWifi;
import static android.net.TrafficStats.UID_REMOVED;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
@@ -81,9 +81,9 @@
private static final String IMSI_1 = "310004";
private static final String IMSI_2 = "310260";
- private static NetworkTemplate sTemplateWifi = new NetworkTemplate(MATCH_WIFI, null);
- private static NetworkTemplate sTemplateImsi1 = new NetworkTemplate(MATCH_MOBILE_ALL, IMSI_1);
- private static NetworkTemplate sTemplateImsi2 = new NetworkTemplate(MATCH_MOBILE_ALL, IMSI_2);
+ private static NetworkTemplate sTemplateWifi = buildTemplateWifi();
+ private static NetworkTemplate sTemplateImsi1 = buildTemplateMobileAll(IMSI_1);
+ private static NetworkTemplate sTemplateImsi2 = buildTemplateMobileAll(IMSI_2);
private static final int UID_RED = 1001;
private static final int UID_BLUE = 1002;
@@ -290,7 +290,7 @@
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify service recorded history
- history = mService.getHistoryForNetwork(new NetworkTemplate(MATCH_WIFI, null));
+ history = mService.getHistoryForNetwork(sTemplateWifi);
assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 512L);
assertEquals(HOUR_IN_MILLIS, history.getBucketDuration());
assertEquals(2, history.size());
@@ -307,7 +307,7 @@
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify identical stats, but spread across 4 buckets now
- history = mService.getHistoryForNetwork(new NetworkTemplate(MATCH_WIFI, null));
+ history = mService.getHistoryForNetwork(sTemplateWifi);
assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 512L);
assertEquals(30 * MINUTE_IN_MILLIS, history.getBucketDuration());
assertEquals(4, history.size());
diff --git a/telephony/java/com/android/internal/telephony/DataCallState.java b/telephony/java/com/android/internal/telephony/DataCallState.java
index fba3184..a69ce8b 100644
--- a/telephony/java/com/android/internal/telephony/DataCallState.java
+++ b/telephony/java/com/android/internal/telephony/DataCallState.java
@@ -52,7 +52,7 @@
/**
* Class returned by onSetupConnectionCompleted.
*/
- protected enum SetupResult {
+ public enum SetupResult {
SUCCESS,
ERR_BadCommand,
ERR_UnacceptableParameter,
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index 5c84fdc..1bba8e3 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -17,30 +17,25 @@
package com.android.internal.telephony;
+import com.android.internal.telephony.DataCallState.SetupResult;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Protocol;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
import android.app.PendingIntent;
-import android.net.LinkAddress;
import android.net.LinkCapabilities;
import android.net.LinkProperties;
-import android.net.NetworkUtils;
+import android.net.LinkProperties.CompareAddressesResult;
import android.net.ProxyProperties;
import android.os.AsyncResult;
-import android.os.Bundle;
import android.os.Message;
-import android.os.Parcel;
-import android.os.Parcelable;
import android.os.SystemProperties;
import android.text.TextUtils;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.HashMap;
import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
/**
* {@hide}
@@ -497,8 +492,7 @@
} else {
if (DBG) log("onSetupConnectionCompleted received DataCallState: " + response);
cid = response.cid;
- // set link properties based on data call response
- result = setLinkProperties(response, mLinkProperties);
+ result = updateLinkProperty(response).setupResult;
}
return result;
@@ -527,48 +521,41 @@
return response.setLinkProperties(lp, okToUseSystemPropertyDns);
}
- private DataConnectionAc.LinkPropertyChangeAction updateLinkProperty(
- DataCallState newState) {
- DataConnectionAc.LinkPropertyChangeAction changed =
- DataConnectionAc.LinkPropertyChangeAction.NONE;
+ public static class UpdateLinkPropertyResult {
+ public DataCallState.SetupResult setupResult = DataCallState.SetupResult.SUCCESS;
+ public LinkProperties oldLp;
+ public LinkProperties newLp;
+ public UpdateLinkPropertyResult(LinkProperties curLp) {
+ oldLp = curLp;
+ newLp = curLp;
+ }
+ }
- if (newState == null) return changed;
+ private UpdateLinkPropertyResult updateLinkProperty(DataCallState newState) {
+ UpdateLinkPropertyResult result = new UpdateLinkPropertyResult(mLinkProperties);
- DataCallState.SetupResult result;
- LinkProperties newLp = new LinkProperties();
+ if (newState == null) return result;
+
+ DataCallState.SetupResult setupResult;
+ result.newLp = new LinkProperties();
// set link properties based on data call response
- result = setLinkProperties(newState, newLp);
- if (result != DataCallState.SetupResult.SUCCESS) {
- if (DBG) log("UpdateLinkProperty failed : " + result);
- return changed;
+ result.setupResult = setLinkProperties(newState, result.newLp);
+ if (result.setupResult != DataCallState.SetupResult.SUCCESS) {
+ if (DBG) log("updateLinkProperty failed : " + result.setupResult);
+ return result;
}
// copy HTTP proxy as it is not part DataCallState.
- newLp.setHttpProxy(mLinkProperties.getHttpProxy());
+ result.newLp.setHttpProxy(mLinkProperties.getHttpProxy());
- if (DBG) log("old LP=" + mLinkProperties);
- if (DBG) log("new LP=" + newLp);
-
- // Check consistency of link address. Currently we expect
- // only one "global" address is assigned per each IP type.
- Collection<LinkAddress> oLinks = mLinkProperties.getLinkAddresses();
- Collection<LinkAddress> nLinks = newLp.getLinkAddresses();
- for (LinkAddress oldLink : oLinks) {
- for (LinkAddress newLink : nLinks) {
- if ((NetworkUtils.addressTypeMatches(oldLink.getAddress(),
- newLink.getAddress())) &&
- (oldLink.equals(newLink) == false)) {
- return DataConnectionAc.LinkPropertyChangeAction.RESET;
- }
- }
+ if (DBG && (! result.oldLp.equals(result.newLp))) {
+ if (DBG) log("updateLinkProperty old != new");
+ if (VDBG) log("updateLinkProperty old LP=" + result.oldLp);
+ if (VDBG) log("updateLinkProperty new LP=" + result.newLp);
}
+ mLinkProperties = result.newLp;
- if (mLinkProperties == null || !mLinkProperties.equals(newLp)) {
- mLinkProperties = newLp;
- changed = DataConnectionAc.LinkPropertyChangeAction.CHANGED;
- }
-
- return changed;
+ return result;
}
/**
@@ -643,14 +630,15 @@
}
case DataConnectionAc.REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE: {
DataCallState newState = (DataCallState) msg.obj;
- DataConnectionAc.LinkPropertyChangeAction action = updateLinkProperty(newState);
+ UpdateLinkPropertyResult result =
+ updateLinkProperty(newState);
if (VDBG) {
- log("REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE action="
- + action + " newState=" + newState);
+ log("REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE result="
+ + result + " newState=" + newState);
}
mAc.replyToMessage(msg,
DataConnectionAc.RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE,
- action.ordinal());
+ result);
break;
}
case DataConnectionAc.REQ_GET_LINK_CAPABILITIES: {
@@ -688,7 +676,7 @@
case DataConnectionAc.REQ_GET_APNCONTEXT_LIST: {
if (VDBG) log("REQ_GET_APNCONTEXT_LIST num in list=" + mApnList.size());
mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_APNCONTEXT_LIST,
- new ArrayList(mApnList));
+ new ArrayList<ApnContext>(mApnList));
break;
}
case DataConnectionAc.REQ_SET_RECONNECT_INTENT: {
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionAc.java b/telephony/java/com/android/internal/telephony/DataConnectionAc.java
index 309dbed6..9e185e5 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionAc.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionAc.java
@@ -16,12 +16,14 @@
package com.android.internal.telephony;
+import com.android.internal.telephony.DataConnection.UpdateLinkPropertyResult;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Protocol;
import android.app.PendingIntent;
import android.net.LinkCapabilities;
import android.net.LinkProperties;
+import android.net.LinkProperties.CompareAddressesResult;
import android.net.ProxyProperties;
import android.os.Message;
@@ -310,18 +312,18 @@
if (DBG) log("reqUpdateLinkPropertiesDataCallState");
}
- public LinkPropertyChangeAction rspUpdateLinkPropertiesDataCallState(Message response) {
- LinkPropertyChangeAction retVal = LinkPropertyChangeAction.fromInt(response.arg1);
- if (DBG) log("rspUpdateLinkPropertiesState=" + retVal);
+ public UpdateLinkPropertyResult rspUpdateLinkPropertiesDataCallState(Message response) {
+ UpdateLinkPropertyResult retVal = (UpdateLinkPropertyResult)response.obj;
+ if (DBG) log("rspUpdateLinkPropertiesState: retVal=" + retVal);
return retVal;
}
/**
* Update link properties in the data connection
*
- * @return true if link property has been updated. false otherwise.
+ * @return the removed and added addresses.
*/
- public LinkPropertyChangeAction updateLinkPropertiesDataCallStateSync(DataCallState newState) {
+ public UpdateLinkPropertyResult updateLinkPropertiesDataCallStateSync(DataCallState newState) {
Message response =
sendMessageSynchronously(REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE, newState);
if ((response != null) &&
@@ -329,7 +331,7 @@
return rspUpdateLinkPropertiesDataCallState(response);
} else {
log("getLinkProperties error response=" + response);
- return LinkPropertyChangeAction.NONE;
+ return new UpdateLinkPropertyResult(new LinkProperties());
}
}
diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java
index 48c5318..4b02e8e 100644
--- a/telephony/java/com/android/internal/telephony/Phone.java
+++ b/telephony/java/com/android/internal/telephony/Phone.java
@@ -1430,6 +1430,11 @@
String getMeid();
/**
+ * Retrieves IMEI for phones. Returns null if IMEI is not set.
+ */
+ String getImei();
+
+ /**
* Retrieves the PhoneSubInfo of the Phone
*/
public PhoneSubInfo getPhoneSubInfo();
diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java
index c2212db..b5bfc76f 100644
--- a/telephony/java/com/android/internal/telephony/PhoneProxy.java
+++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java
@@ -685,6 +685,10 @@
return mActivePhone.getMeid();
}
+ public String getImei() {
+ return mActivePhone.getImei();
+ }
+
public PhoneSubInfo getPhoneSubInfo(){
return mActivePhone.getPhoneSubInfo();
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
index a31b704..0d9d27d 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
@@ -136,6 +136,11 @@
}
@Override
+ public String getImei() {
+ return mImei;
+ }
+
+ @Override
protected void log(String s) {
if (DBG)
Log.d(LOG_TAG, "[CDMALTEPhone] " + s);
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index 8a60b5a..286515e 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -122,6 +122,8 @@
//keep track of if phone is in emergency callback mode
private boolean mIsPhoneInEcmState;
private Registrant mEcmExitRespRegistrant;
+ protected String mImei;
+ protected String mImeiSv;
private String mEsn;
private String mMeid;
// string to define how the carrier specifies its own ota sp number
@@ -489,6 +491,11 @@
return mSST.getImsi();
}
+ public String getImei() {
+ Log.e(LOG_TAG, "IMEI is not available in CDMA");
+ return null;
+ }
+
public boolean canConference() {
Log.e(LOG_TAG, "canConference: not possible in CDMA");
return false;
@@ -987,6 +994,8 @@
break;
}
String[] respId = (String[])ar.result;
+ mImei = respId[0];
+ mImeiSv = respId[1];
mEsn = respId[2];
mMeid = respId[3];
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
index d357eac..1db9860 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
@@ -855,6 +855,10 @@
return mImeiSv;
}
+ public String getImei() {
+ return mImei;
+ }
+
public String getEsn() {
Log.e(LOG_TAG, "[GSMPhone] getEsn() is a CDMA method");
return "0";
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index df5898b..bf964b7 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -26,6 +26,9 @@
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.ConnectivityManager;
+import android.net.LinkAddress;
+import android.net.LinkProperties.CompareAddressesResult;
+import android.net.NetworkUtils;
import android.net.ProxyProperties;
import android.net.TrafficStats;
import android.net.Uri;
@@ -53,6 +56,7 @@
import com.android.internal.telephony.ApnSetting;
import com.android.internal.telephony.DataCallState;
import com.android.internal.telephony.DataConnection;
+import com.android.internal.telephony.DataConnection.UpdateLinkPropertyResult;
import com.android.internal.telephony.DataConnectionAc;
import com.android.internal.telephony.DataConnectionTracker;
import com.android.internal.telephony.Phone;
@@ -1037,7 +1041,7 @@
/**
* @param dcacs Collection of DataConnectionAc reported from RIL.
- * @return List of ApnContext whihc is connected, but does not present in
+ * @return List of ApnContext which is connected, but is not present in
* data connection list reported from RIL.
*/
private List<ApnContext> findApnContextToClean(Collection<DataConnectionAc> dcacs) {
@@ -1091,32 +1095,30 @@
if (DBG) log("onDataStateChanged(ar): DataCallState size=" + dataCallStates.size());
// Create a hash map to store the dataCallState of each DataConnectionAc
- // TODO: Depends on how frequent the DATA_CALL_LIST got updated,
- // may cache response to reduce comparison.
- HashMap<DataCallState, DataConnectionAc> response;
- response = new HashMap<DataCallState, DataConnectionAc>();
+ HashMap<DataCallState, DataConnectionAc> dataCallStateToDcac;
+ dataCallStateToDcac = new HashMap<DataCallState, DataConnectionAc>();
for (DataCallState dataCallState : dataCallStates) {
DataConnectionAc dcac = findDataConnectionAcByCid(dataCallState.cid);
- if (dcac != null) response.put(dataCallState, dcac);
+ if (dcac != null) dataCallStateToDcac.put(dataCallState, dcac);
}
- // step1: Find a list of "connected" APN which does not have reference to
- // calls listed in the Data Call List.
- List<ApnContext> apnsToClear = findApnContextToClean(response.values());
+ // A list of apns to cleanup, those that aren't in the list we know we have to cleanup
+ List<ApnContext> apnsToCleanup = findApnContextToClean(dataCallStateToDcac.values());
- // step2: Check status of each calls in Data Call List.
- // Collect list of ApnContext associated with the data call if the link
- // has to be cleared.
+ // Find which connections have changed state and send a notification or cleanup
for (DataCallState newState : dataCallStates) {
- DataConnectionAc dcac = response.get(newState);
+ DataConnectionAc dcac = dataCallStateToDcac.get(newState);
- // no associated DataConnection found. Ignore.
- if (dcac == null) continue;
+ if (dcac == null) {
+ loge("onDataStateChanged(ar): No associated DataConnection ignore");
+ continue;
+ }
+ // The list of apn's associated with this DataConnection
Collection<ApnContext> apns = dcac.getApnListSync();
- // filter out ApnContext with "Connected/Connecting" state.
+ // Find which ApnContexts of this DC are in the "Connected/Connecting" state.
ArrayList<ApnContext> connectedApns = new ArrayList<ApnContext>();
for (ApnContext apnContext : apns) {
if (apnContext.getState() == State.CONNECTED ||
@@ -1125,67 +1127,86 @@
connectedApns.add(apnContext);
}
}
-
- // No "Connected" ApnContext associated with this CID. Ignore.
- if (connectedApns.isEmpty()) {
- continue;
- }
-
- if (DBG) log("onDataStateChanged(ar): Found ConnId=" + newState.cid
- + " newState=" + newState.toString());
- if (newState.active != 0) {
- boolean resetConnection;
- switch (dcac.updateLinkPropertiesDataCallStateSync(newState)) {
- case NONE:
- if (DBG) log("onDataStateChanged(ar): Found but no change, skip");
- resetConnection = false;
- break;
- case CHANGED:
- for (ApnContext apnContext : connectedApns) {
- if (DBG) log("onDataStateChanged(ar): Found and changed, notify (" +
- apnContext.toString() + ")");
- mPhone.notifyDataConnection(Phone.REASON_LINK_PROPERTIES_CHANGED,
- apnContext.getApnType());
+ if (connectedApns.size() == 0) {
+ if (DBG) log("onDataStateChanged(ar): no connected apns");
+ } else {
+ // Determine if the connection/apnContext should be cleaned up
+ // or just a notification should be sent out.
+ if (DBG) log("onDataStateChanged(ar): Found ConnId=" + newState.cid
+ + " newState=" + newState.toString());
+ if (newState.active == 0) {
+ if (DBG) {
+ log("onDataStateChanged(ar): inactive, cleanup apns=" + connectedApns);
}
- // Temporary hack, at this time a transition from CDMA -> Global
- // fails so we'll hope for the best and not reset the connection.
- // @see bug/4455071
- if (SystemProperties.getBoolean("telephony.ignore-state-changes",
- true)) {
- log("onDataStateChanged(ar): STOPSHIP don't reset, continue");
- resetConnection = false;
+ apnsToCleanup.addAll(connectedApns);
+ } else {
+ // Its active so update the DataConnections link properties
+ UpdateLinkPropertyResult result =
+ dcac.updateLinkPropertiesDataCallStateSync(newState);
+ if (result.oldLp.equals(result.newLp)) {
+ if (DBG) log("onDataStateChanged(ar): no change");
} else {
- // Things changed so reset connection, when hack is removed
- // this is the normal path.
- log("onDataStateChanged(ar): changed so resetting connection");
- resetConnection = true;
+ if (result.oldLp.isIdenticalInterfaceName(result.newLp)) {
+ if (! result.oldLp.isIdenticalDnses(result.newLp) ||
+ ! result.oldLp.isIdenticalRoutes(result.newLp) ||
+ ! result.oldLp.isIdenticalHttpProxy(result.newLp) ||
+ ! result.oldLp.isIdenticalAddresses(result.newLp)) {
+ // If the same address type was removed and added we need to cleanup
+ CompareAddressesResult car =
+ result.oldLp.compareAddresses(result.newLp);
+ boolean needToClean = false;
+ for (LinkAddress added : car.added) {
+ for (LinkAddress removed : car.removed) {
+ if (NetworkUtils.addressTypeMatches(removed.getAddress(),
+ added.getAddress())) {
+ needToClean = true;
+ break;
+ }
+ }
+ }
+ if (needToClean) {
+ if (DBG) {
+ log("onDataStateChanged(ar): addr change, cleanup apns=" +
+ connectedApns);
+ }
+ apnsToCleanup.addAll(connectedApns);
+ } else {
+ if (DBG) log("onDataStateChanged(ar): simple change");
+ for (ApnContext apnContext : connectedApns) {
+ mPhone.notifyDataConnection(
+ Phone.REASON_LINK_PROPERTIES_CHANGED,
+ apnContext.getApnType());
+ }
+ }
+ } else {
+ if (DBG) {
+ log("onDataStateChanged(ar): no changes");
+ }
+ }
+ } else {
+ if (DBG) {
+ log("onDataStateChanged(ar): interface change, cleanup apns="
+ + connectedApns);
+ }
+ apnsToCleanup.addAll(connectedApns);
+ }
}
- break;
- case RESET:
- default:
- if (DBG) log("onDataStateChanged(ar): an error, reset connection");
- resetConnection = true;
- break;
}
- if (resetConnection == false) continue;
}
-
- if (DBG) log("onDataStateChanged(ar): reset connection.");
-
- apnsToClear.addAll(connectedApns);
}
- // step3: Clear apn connection if applicable.
- if (!apnsToClear.isEmpty()) {
+ if (apnsToCleanup.size() != 0) {
// Add an event log when the network drops PDP
int cid = getCellLocationId();
EventLog.writeEvent(EventLogTags.PDP_NETWORK_DROP, cid,
TelephonyManager.getDefault().getNetworkType());
}
- for (ApnContext apnContext : apnsToClear) {
+ // Cleanup those dropped connections
+ for (ApnContext apnContext : apnsToCleanup) {
cleanUpConnection(true, apnContext);
}
+
if (DBG) log("onDataStateChanged(ar): X");
}
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java b/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java
index 9dfc015..5c4b446 100755
--- a/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java
@@ -264,6 +264,10 @@
return null;
}
+ public String getImei() {
+ return null;
+ }
+
public String getEsn() {
Log.e(LOG_TAG, "[SipPhone] getEsn() is a CDMA method");
return "0";
diff --git a/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java b/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java
index b9bf526..af5006f 100644
--- a/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java
+++ b/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java
@@ -38,20 +38,20 @@
vg.setUseDefaultMargins(true);
vg.setAlignmentMode(ALIGN_BOUNDS);
- Group row1 = new Group(1, CENTER);
- Group row2 = new Group(2, CENTER);
- Group row3 = new Group(3, BASELINE);
- Group row4 = new Group(4, BASELINE);
- Group row5 = new Group(5, FILL);
- Group row6 = new Group(6, CENTER);
- Group row7 = new Group(7, CENTER);
+ Spec row1 = spec(0, CENTER);
+ Spec row2 = spec(1, CENTER);
+ Spec row3 = spec(2, BASELINE);
+ Spec row4 = spec(3, BASELINE);
+ Spec row5 = spec(4, FILL, CAN_STRETCH);
+ Spec row6 = spec(5, CENTER);
+ Spec row7 = spec(6, CENTER);
- Group col1a = new Group(1, 4, CENTER);
- Group col1b = new Group(1, 4, LEFT);
- Group col1c = new Group(1, RIGHT);
- Group col2 = new Group(2, LEFT);
- Group col3 = new Group(3, FILL);
- Group col4 = new Group(4, FILL);
+ Spec col1a = spec(0, 4, CENTER);
+ Spec col1b = spec(0, 4, LEFT);
+ Spec col1c = spec(0, RIGHT);
+ Spec col2 = spec(1, LEFT);
+ Spec col3 = spec(2, FILL, CAN_STRETCH);
+ Spec col4 = spec(3, FILL);
{
TextView v = new TextView(context);
@@ -96,10 +96,7 @@
{
Space v = new Space(context);
{
- LayoutParams lp = new LayoutParams(row5, col3);
- lp.columnGroup.flexibility = CAN_STRETCH;
- lp.rowGroup.flexibility = CAN_STRETCH;
- vg.addView(v, lp);
+ vg.addView(v, new LayoutParams(row5, col3));
}
}
{
diff --git a/tests/GridLayoutTest/src/com/android/test/layout/AlignmentTest.java b/tests/GridLayoutTest/src/com/android/test/layout/AlignmentTest.java
index 505c83d..b1c4486 100755
--- a/tests/GridLayoutTest/src/com/android/test/layout/AlignmentTest.java
+++ b/tests/GridLayoutTest/src/com/android/test/layout/AlignmentTest.java
@@ -21,7 +21,6 @@
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewParent;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridLayout;
@@ -84,9 +83,7 @@
Alignment va = VERTICAL_ALIGNMENTS[i];
for (int j = 0; j < HORIZONTAL_ALIGNMENTS.length; j++) {
Alignment ha = HORIZONTAL_ALIGNMENTS[j];
- Group rowGroup = new Group(i, va);
- Group colGroup = new Group(j, ha);
- LayoutParams layoutParams = new LayoutParams(rowGroup, colGroup);
+ LayoutParams layoutParams = new LayoutParams(spec(i, va), spec(j, ha));
String name = VERTICAL_NAMES[i] + "-" + HORIZONTAL_NAMES[j];
ViewFactory factory = FACTORIES[(i + j) % FACTORIES.length];
container.addView(factory.create(name, 20), layoutParams);
diff --git a/tests/GridLayoutTest/src/com/android/test/layout/GridLayoutTest.java b/tests/GridLayoutTest/src/com/android/test/layout/GridLayoutTest.java
index c5681e2..4ce449a 100644
--- a/tests/GridLayoutTest/src/com/android/test/layout/GridLayoutTest.java
+++ b/tests/GridLayoutTest/src/com/android/test/layout/GridLayoutTest.java
@@ -33,9 +33,9 @@
int va = VERTICAL_ALIGNMENTS[i];
for (int j = 0; j < HORIZONTAL_ALIGNMENTS.length; j++) {
int ha = HORIZONTAL_ALIGNMENTS[j];
- GridLayout.Group rowGroup = new GridLayout.Group(UNDEFINED, null);
- GridLayout.Group colGroup = new GridLayout.Group(UNDEFINED, null);
- GridLayout.LayoutParams lp = new GridLayout.LayoutParams(rowGroup, colGroup);
+ Spec rowSpec = spec(UNDEFINED, null);
+ Spec colSpec = spec(UNDEFINED, null);
+ GridLayout.LayoutParams lp = new GridLayout.LayoutParams(rowSpec, colSpec);
//GridLayout.LayoutParams lp = new GridLayout.LayoutParams();
lp.setGravity(va | ha);
View v = create(context, VERTICAL_NAMES[i] + "-" + HORIZONTAL_NAMES[j], 20);
diff --git a/tools/aidl/Type.cpp b/tools/aidl/Type.cpp
index a44072d..6b69864 100755
--- a/tools/aidl/Type.cpp
+++ b/tools/aidl/Type.cpp
@@ -198,7 +198,7 @@
}
void
-Type::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+Type::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
{
fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
__FILE__, __LINE__, m_qualifiedName.c_str());
@@ -207,7 +207,7 @@
}
void
-Type::ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+Type::ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
{
fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
__FILE__, __LINE__, m_qualifiedName.c_str());
@@ -226,7 +226,7 @@
void
Type::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel)
+ Variable* parcel, Variable**)
{
fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
__FILE__, __LINE__, m_qualifiedName.c_str());
@@ -235,7 +235,7 @@
}
void
-Type::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+Type::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
{
fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
__FILE__, __LINE__, m_qualifiedName.c_str());
@@ -284,7 +284,7 @@
}
void
-BasicType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+BasicType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
{
addTo->Add(new Assignment(v, new MethodCall(parcel, m_unmarshallMethod)));
}
@@ -303,13 +303,13 @@
void
BasicType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel)
+ Variable* parcel, Variable**)
{
addTo->Add(new Assignment(v, new MethodCall(parcel, m_createArrayMethod)));
}
void
-BasicType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+BasicType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
{
addTo->Add(new MethodCall(parcel, m_readArrayMethod, 1, v));
}
@@ -331,7 +331,7 @@
}
void
-BooleanType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+BooleanType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
{
addTo->Add(new Assignment(v, new Comparison(new LiteralExpression("0"),
"!=", new MethodCall(parcel, "readInt"))));
@@ -351,13 +351,13 @@
void
BooleanType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel)
+ Variable* parcel, Variable**)
{
addTo->Add(new Assignment(v, new MethodCall(parcel, "createBooleanArray")));
}
void
-BooleanType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+BooleanType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
{
addTo->Add(new MethodCall(parcel, "readBooleanArray", 1, v));
}
@@ -378,7 +378,7 @@
}
void
-CharType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+CharType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
{
addTo->Add(new Assignment(v, new MethodCall(parcel, "readInt"), this));
}
@@ -397,13 +397,13 @@
void
CharType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel)
+ Variable* parcel, Variable**)
{
addTo->Add(new Assignment(v, new MethodCall(parcel, "createCharArray")));
}
void
-CharType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+CharType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
{
addTo->Add(new MethodCall(parcel, "readCharArray", 1, v));
}
@@ -428,7 +428,7 @@
}
void
-StringType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+StringType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
{
addTo->Add(new Assignment(v, new MethodCall(parcel, "readString")));
}
@@ -447,13 +447,13 @@
void
StringType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel)
+ Variable* parcel, Variable**)
{
addTo->Add(new Assignment(v, new MethodCall(parcel, "createStringArray")));
}
void
-StringType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+StringType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
{
addTo->Add(new MethodCall(parcel, "readStringArray", 1, v));
}
@@ -496,7 +496,7 @@
void
CharSequenceType::CreateFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel)
+ Variable* parcel, Variable**)
{
// if (0 != parcel.readInt()) {
// v = TextUtils.createFromParcel(parcel)
@@ -532,7 +532,7 @@
}
void
-RemoteExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+RemoteExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
{
fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
}
@@ -551,7 +551,7 @@
}
void
-RuntimeExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+RuntimeExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
{
fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
}
@@ -571,7 +571,7 @@
}
void
-IBinderType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+IBinderType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
{
addTo->Add(new Assignment(v, new MethodCall(parcel, "readStrongBinder")));
}
@@ -584,13 +584,13 @@
void
IBinderType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel)
+ Variable* parcel, Variable**)
{
addTo->Add(new Assignment(v, new MethodCall(parcel, "createBinderArray")));
}
void
-IBinderType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+IBinderType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
{
addTo->Add(new MethodCall(parcel, "readBinderArray", 1, v));
}
@@ -610,7 +610,7 @@
}
void
-IInterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+IInterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
{
fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
}
@@ -631,7 +631,7 @@
void
BinderType::CreateFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel)
+ Variable* parcel, Variable**)
{
fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
}
@@ -652,7 +652,7 @@
void
BinderProxyType::CreateFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel)
+ Variable* parcel, Variable**)
{
fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
}
@@ -672,7 +672,7 @@
}
void
-ParcelType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+ParcelType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
{
fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
}
@@ -691,7 +691,7 @@
}
void
-ParcelableInterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+ParcelableInterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
{
fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
}
@@ -709,25 +709,31 @@
addTo->Add(new MethodCall(parcel, "writeMap", 1, v));
}
-void
-MapType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+static void EnsureClassLoader(StatementBlock* addTo, Variable** cl)
{
- Variable *cl = new Variable(CLASSLOADER_TYPE, "cl");
- addTo->Add(new VariableDeclaration(cl,
- new LiteralExpression("this.getClass().getClassLoader()"),
- CLASSLOADER_TYPE));
- addTo->Add(new Assignment(v, new MethodCall(parcel, "readHashMap", 1, cl)));
+ // We don't want to look up the class loader once for every
+ // collection argument, so ensure we do it at most once per method.
+ if (*cl == NULL) {
+ *cl = new Variable(CLASSLOADER_TYPE, "cl");
+ addTo->Add(new VariableDeclaration(*cl,
+ new LiteralExpression("this.getClass().getClassLoader()"),
+ CLASSLOADER_TYPE));
+ }
+}
+
+void
+MapType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable** cl)
+{
+ EnsureClassLoader(addTo, cl);
+ addTo->Add(new Assignment(v, new MethodCall(parcel, "readHashMap", 1, *cl)));
}
void
MapType::ReadFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel)
+ Variable* parcel, Variable** cl)
{
- Variable *cl = new Variable(CLASSLOADER_TYPE, "cl");
- addTo->Add(new VariableDeclaration(cl,
- new LiteralExpression("this.getClass().getClassLoader()"),
- CLASSLOADER_TYPE));
- addTo->Add(new MethodCall(parcel, "readMap", 2, v, cl));
+ EnsureClassLoader(addTo, cl);
+ addTo->Add(new MethodCall(parcel, "readMap", 2, v, *cl));
}
@@ -751,24 +757,18 @@
}
void
-ListType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+ListType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable** cl)
{
- Variable *cl = new Variable(CLASSLOADER_TYPE, "cl");
- addTo->Add(new VariableDeclaration(cl,
- new LiteralExpression("this.getClass().getClassLoader()"),
- CLASSLOADER_TYPE));
- addTo->Add(new Assignment(v, new MethodCall(parcel, "readArrayList", 1, cl)));
+ EnsureClassLoader(addTo, cl);
+ addTo->Add(new Assignment(v, new MethodCall(parcel, "readArrayList", 1, *cl)));
}
void
ListType::ReadFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel)
+ Variable* parcel, Variable** cl)
{
- Variable *cl = new Variable(CLASSLOADER_TYPE, "cl");
- addTo->Add(new VariableDeclaration(cl,
- new LiteralExpression("this.getClass().getClassLoader()"),
- CLASSLOADER_TYPE));
- addTo->Add(new MethodCall(parcel, "readList", 2, v, cl));
+ EnsureClassLoader(addTo, cl);
+ addTo->Add(new MethodCall(parcel, "readList", 2, v, *cl));
}
@@ -811,7 +811,7 @@
}
void
-ParcelableType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+ParcelableType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
{
// if (0 != parcel.readInt()) {
// v = CLASS.CREATOR.createFromParcel(parcel)
@@ -833,7 +833,7 @@
void
ParcelableType::ReadFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel)
+ Variable* parcel, Variable**)
{
// TODO: really, we don't need to have this extra check, but we
// don't have two separate marshalling code paths
@@ -862,7 +862,7 @@
void
ParcelableType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel)
+ Variable* parcel, Variable**)
{
string creator = v->type->QualifiedName() + ".CREATOR";
addTo->Add(new Assignment(v, new MethodCall(parcel,
@@ -870,7 +870,7 @@
}
void
-ParcelableType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+ParcelableType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
{
string creator = v->type->QualifiedName() + ".CREATOR";
addTo->Add(new MethodCall(parcel, "readTypedArray", 2,
@@ -907,7 +907,7 @@
}
void
-InterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+InterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
{
// v = Interface.asInterface(parcel.readStrongBinder());
string type = v->type->QualifiedName();
@@ -961,14 +961,14 @@
}
void
-GenericType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+GenericType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
{
fprintf(stderr, "implement GenericType::CreateFromParcel\n");
}
void
GenericType::ReadFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel)
+ Variable* parcel, Variable**)
{
fprintf(stderr, "implement GenericType::ReadFromParcel\n");
}
@@ -1009,7 +1009,7 @@
}
void
-GenericListType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel)
+GenericListType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
{
if (m_creator == STRING_TYPE->CreatorName()) {
addTo->Add(new Assignment(v,
@@ -1027,7 +1027,7 @@
void
GenericListType::ReadFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel)
+ Variable* parcel, Variable**)
{
if (m_creator == STRING_TYPE->CreatorName()) {
addTo->Add(new MethodCall(parcel, "readStringList", 1, v));
diff --git a/tools/aidl/Type.h b/tools/aidl/Type.h
index 2ea3ac9..662e3a2 100755
--- a/tools/aidl/Type.h
+++ b/tools/aidl/Type.h
@@ -46,18 +46,18 @@
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
virtual void ReadFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
virtual bool CanBeArray() const;
virtual void WriteArrayToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
virtual void ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
protected:
void SetQualifiedName(const string& qualified);
@@ -89,16 +89,16 @@
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
virtual bool CanBeArray() const;
virtual void WriteArrayToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
virtual void ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
private:
string m_marshallMethod;
@@ -116,16 +116,16 @@
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
virtual bool CanBeArray() const;
virtual void WriteArrayToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
virtual void ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
};
class CharType : public Type
@@ -136,16 +136,16 @@
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
virtual bool CanBeArray() const;
virtual void WriteArrayToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
virtual void ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
};
@@ -159,16 +159,16 @@
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
virtual bool CanBeArray() const;
virtual void WriteArrayToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
virtual void ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
};
class CharSequenceType : public Type
@@ -181,7 +181,7 @@
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
};
class RemoteExceptionType : public Type
@@ -192,7 +192,7 @@
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
};
class RuntimeExceptionType : public Type
@@ -203,7 +203,7 @@
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
};
class IBinderType : public Type
@@ -214,14 +214,14 @@
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
virtual void WriteArrayToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
virtual void ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
};
class IInterfaceType : public Type
@@ -232,7 +232,7 @@
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
};
class BinderType : public Type
@@ -243,7 +243,7 @@
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
};
class BinderProxyType : public Type
@@ -254,7 +254,7 @@
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
};
class ParcelType : public Type
@@ -265,7 +265,7 @@
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
};
class ParcelableInterfaceType : public Type
@@ -276,7 +276,7 @@
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
};
class MapType : public Type
@@ -287,9 +287,9 @@
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
virtual void ReadFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
};
class ListType : public Type
@@ -302,9 +302,9 @@
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
virtual void ReadFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
};
class ParcelableType : public Type
@@ -318,18 +318,18 @@
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
virtual void ReadFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
virtual bool CanBeArray() const;
virtual void WriteArrayToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
virtual void ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
};
class InterfaceType : public Type
@@ -344,7 +344,7 @@
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
private:
bool m_oneway;
@@ -364,9 +364,9 @@
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
virtual void ReadFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
private:
string m_genericArguments;
@@ -387,9 +387,9 @@
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
virtual void ReadFromParcel(StatementBlock* addTo, Variable* v,
- Variable* parcel);
+ Variable* parcel, Variable** cl);
private:
string m_creator;
diff --git a/tools/aidl/aidl.cpp b/tools/aidl/aidl.cpp
index f17f66b..92f5b64 100644
--- a/tools/aidl/aidl.cpp
+++ b/tools/aidl/aidl.cpp
@@ -948,8 +948,6 @@
int
main(int argc, const char **argv)
{
- int err = 0;
-
Options options;
int result = parse_options(argc, argv, &options);
if (result) {
diff --git a/tools/aidl/generate_java.cpp b/tools/aidl/generate_java.cpp
index 0f18132..83e3bbc 100644
--- a/tools/aidl/generate_java.cpp
+++ b/tools/aidl/generate_java.cpp
@@ -286,25 +286,25 @@
static void
generate_create_from_parcel(Type* t, StatementBlock* addTo, Variable* v,
- Variable* parcel)
+ Variable* parcel, Variable** cl)
{
if (v->dimension == 0) {
- t->CreateFromParcel(addTo, v, parcel);
+ t->CreateFromParcel(addTo, v, parcel, cl);
}
if (v->dimension == 1) {
- t->CreateArrayFromParcel(addTo, v, parcel);
+ t->CreateArrayFromParcel(addTo, v, parcel, cl);
}
}
static void
generate_read_from_parcel(Type* t, StatementBlock* addTo, Variable* v,
- Variable* parcel)
+ Variable* parcel, Variable** cl)
{
if (v->dimension == 0) {
- t->ReadFromParcel(addTo, v, parcel);
+ t->ReadFromParcel(addTo, v, parcel, cl);
}
if (v->dimension == 1) {
- t->ReadArrayFromParcel(addTo, v, parcel);
+ t->ReadArrayFromParcel(addTo, v, parcel, cl);
}
}
@@ -362,6 +362,7 @@
"enforceInterface", 1, new LiteralExpression("DESCRIPTOR")));
// args
+ Variable* cl = NULL;
VariableFactory stubArgs("_arg");
arg = method->args;
while (arg != NULL) {
@@ -373,7 +374,7 @@
if (convert_direction(arg->direction.data) & IN_PARAMETER) {
generate_create_from_parcel(t, c->statements, v,
- stubClass->transact_data);
+ stubClass->transact_data, &cl);
} else {
if (arg->type.dimension == 0) {
c->statements->Add(new Assignment(
@@ -531,7 +532,7 @@
if (_reply != NULL) {
if (_result != NULL) {
generate_create_from_parcel(proxy->returnType,
- tryStatement->statements, _result, _reply);
+ tryStatement->statements, _result, _reply, &cl);
}
// the out/inout parameters
@@ -541,7 +542,7 @@
Variable* v = new Variable(t, arg->name.data, arg->type.dimension);
if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
generate_read_from_parcel(t, tryStatement->statements,
- v, _reply);
+ v, _reply, &cl);
}
arg = arg->next;
}