Merge "Adds invocable functions to ScriptGroup"
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 0eb52cb..c9b44be 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -800,7 +800,7 @@
if (args.niceName != null) {
String property = "wrap." + args.niceName;
if (property.length() > 31) {
- // Avoid creating an illegal property name when truncating.
+ // Properties with a trailing "." are illegal.
if (property.charAt(30) != '.') {
property = property.substring(0, 31);
} else {
diff --git a/core/tests/coretests/src/android/net/StaticIpConfigurationTest.java b/core/tests/coretests/src/android/net/StaticIpConfigurationTest.java
new file mode 100644
index 0000000..59f780f
--- /dev/null
+++ b/core/tests/coretests/src/android/net/StaticIpConfigurationTest.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.net.IpPrefix;
+import android.net.LinkAddress;
+import android.net.RouteInfo;
+import android.net.StaticIpConfiguration;
+import android.os.Parcel;
+
+import java.net.InetAddress;
+import java.util.HashSet;
+
+import junit.framework.TestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import static org.junit.Assert.*;
+
+
+public class StaticIpConfigurationTest extends TestCase {
+
+ private static final String ADDRSTR = "192.0.2.2/25";
+ private static final LinkAddress ADDR = new LinkAddress(ADDRSTR);
+ private static final InetAddress GATEWAY = IpAddress("192.0.2.1");
+ private static final InetAddress OFFLINKGATEWAY = IpAddress("192.0.2.129");
+ private static final InetAddress DNS1 = IpAddress("8.8.8.8");
+ private static final InetAddress DNS2 = IpAddress("8.8.4.4");
+ private static final InetAddress DNS3 = IpAddress("4.2.2.2");
+ private static final String IFACE = "eth0";
+
+ private static InetAddress IpAddress(String addr) {
+ return InetAddress.parseNumericAddress(addr);
+ }
+
+ private void checkEmpty(StaticIpConfiguration s) {
+ assertNull(s.ipAddress);
+ assertNull(s.gateway);
+ assertNull(s.domains);
+ assertEquals(0, s.dnsServers.size());
+ }
+
+ private boolean isEqual(StaticIpConfiguration s1, StaticIpConfiguration s2) {
+ return s1.equals(s2);
+ }
+
+ private void assertEquals(StaticIpConfiguration s1, StaticIpConfiguration s2) {
+ assertTrue(isEqual(s1, s2));
+ }
+
+ private void assertNotEquals(StaticIpConfiguration s1, StaticIpConfiguration s2) {
+ assertFalse(isEqual(s1, s2));
+ }
+
+ private StaticIpConfiguration makeTestObject() {
+ StaticIpConfiguration s = new StaticIpConfiguration();
+ s.ipAddress = ADDR;
+ s.gateway = GATEWAY;
+ s.dnsServers.add(DNS1);
+ s.dnsServers.add(DNS2);
+ s.dnsServers.add(DNS3);
+ s.domains = "google.com";
+ return s;
+ }
+
+ @SmallTest
+ public void testConstructor() {
+ StaticIpConfiguration s = new StaticIpConfiguration();
+ checkEmpty(s);
+ }
+
+ @SmallTest
+ public void testCopyAndClear() {
+ StaticIpConfiguration empty = new StaticIpConfiguration((StaticIpConfiguration) null);
+ checkEmpty(empty);
+
+ StaticIpConfiguration s1 = makeTestObject();
+ StaticIpConfiguration s2 = new StaticIpConfiguration(s1);
+ assertEquals(s1, s2);
+ s2.clear();
+ assertEquals(empty, s2);
+ }
+
+ @SmallTest
+ public void testHashCodeAndEquals() {
+ HashSet<Integer> hashCodes = new HashSet();
+ hashCodes.add(0);
+
+ StaticIpConfiguration s = new StaticIpConfiguration();
+ // Check that this hash code is nonzero and different from all the ones seen so far.
+ assertTrue(hashCodes.add(s.hashCode()));
+
+ s.ipAddress = ADDR;
+ assertTrue(hashCodes.add(s.hashCode()));
+
+ s.gateway = GATEWAY;
+ assertTrue(hashCodes.add(s.hashCode()));
+
+ s.dnsServers.add(DNS1);
+ assertTrue(hashCodes.add(s.hashCode()));
+
+ s.dnsServers.add(DNS2);
+ assertTrue(hashCodes.add(s.hashCode()));
+
+ s.dnsServers.add(DNS3);
+ assertTrue(hashCodes.add(s.hashCode()));
+
+ s.domains = "example.com";
+ assertTrue(hashCodes.add(s.hashCode()));
+
+ assertFalse(s.equals(null));
+ assertEquals(s, s);
+
+ StaticIpConfiguration s2 = new StaticIpConfiguration(s);
+ assertEquals(s, s2);
+
+ s.ipAddress = new LinkAddress(DNS1, 32);
+ assertNotEquals(s, s2);
+
+ s2 = new StaticIpConfiguration(s);
+ s.domains = "foo";
+ assertNotEquals(s, s2);
+
+ s2 = new StaticIpConfiguration(s);
+ s.gateway = DNS2;
+ assertNotEquals(s, s2);
+
+ s2 = new StaticIpConfiguration(s);
+ s.dnsServers.add(DNS3);
+ assertNotEquals(s, s2);
+ }
+
+ @SmallTest
+ public void testToLinkProperties() {
+ LinkProperties expected = new LinkProperties();
+ expected.setInterfaceName(IFACE);
+
+ StaticIpConfiguration s = new StaticIpConfiguration();
+ assertEquals(expected, s.toLinkProperties(IFACE));
+
+ final RouteInfo connectedRoute = new RouteInfo(new IpPrefix(ADDRSTR), null, IFACE);
+ s.ipAddress = ADDR;
+ expected.addLinkAddress(ADDR);
+ expected.addRoute(connectedRoute);
+ assertEquals(expected, s.toLinkProperties(IFACE));
+
+ s.gateway = GATEWAY;
+ RouteInfo defaultRoute = new RouteInfo(new IpPrefix("0.0.0.0/0"), GATEWAY, IFACE);
+ expected.addRoute(defaultRoute);
+ assertEquals(expected, s.toLinkProperties(IFACE));
+
+ s.gateway = OFFLINKGATEWAY;
+ expected.removeRoute(defaultRoute);
+ defaultRoute = new RouteInfo(new IpPrefix("0.0.0.0/0"), OFFLINKGATEWAY, IFACE);
+ expected.addRoute(defaultRoute);
+
+ RouteInfo gatewayRoute = new RouteInfo(new IpPrefix("192.0.2.129/32"), null, IFACE);
+ expected.addRoute(gatewayRoute);
+ assertEquals(expected, s.toLinkProperties(IFACE));
+
+ s.dnsServers.add(DNS1);
+ expected.addDnsServer(DNS1);
+ assertEquals(expected, s.toLinkProperties(IFACE));
+
+ s.dnsServers.add(DNS2);
+ s.dnsServers.add(DNS3);
+ expected.addDnsServer(DNS2);
+ expected.addDnsServer(DNS3);
+ assertEquals(expected, s.toLinkProperties(IFACE));
+
+ s.domains = "google.com";
+ expected.setDomains("google.com");
+ assertEquals(expected, s.toLinkProperties(IFACE));
+
+ s.gateway = null;
+ expected.removeRoute(defaultRoute);
+ expected.removeRoute(gatewayRoute);
+ assertEquals(expected, s.toLinkProperties(IFACE));
+
+ // Without knowing the IP address, we don't have a directly-connected route, so we can't
+ // tell if the gateway is off-link or not and we don't add a host route. This isn't a real
+ // configuration, but we should at least not crash.
+ s.gateway = OFFLINKGATEWAY;
+ s.ipAddress = null;
+ expected.removeLinkAddress(ADDR);
+ expected.removeRoute(connectedRoute);
+ expected.addRoute(defaultRoute);
+ assertEquals(expected, s.toLinkProperties(IFACE));
+ }
+
+ private StaticIpConfiguration passThroughParcel(StaticIpConfiguration s) {
+ Parcel p = Parcel.obtain();
+ StaticIpConfiguration s2 = null;
+ try {
+ s.writeToParcel(p, 0);
+ p.setDataPosition(0);
+ s2 = StaticIpConfiguration.CREATOR.createFromParcel(p);
+ } finally {
+ p.recycle();
+ }
+ assertNotNull(s2);
+ return s2;
+ }
+
+ @SmallTest
+ public void testParceling() {
+ StaticIpConfiguration s = makeTestObject();
+ StaticIpConfiguration s2 = passThroughParcel(s);
+ assertEquals(s, s2);
+ }
+}
+
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index a3d7019..302d1a9 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -493,7 +493,9 @@
if (mProcessor == NULL) {
mProcessor = new PathProcessor(Caches::getInstance());
}
- mProcessor->add(task);
+ if (!mProcessor->add(task)) {
+ mProcessor->process(task);
+ }
}
}
diff --git a/libs/hwui/TessellationCache.cpp b/libs/hwui/TessellationCache.cpp
index 1e38f9e..bc956be 100644
--- a/libs/hwui/TessellationCache.cpp
+++ b/libs/hwui/TessellationCache.cpp
@@ -385,7 +385,9 @@
if (mShadowProcessor == NULL) {
mShadowProcessor = new ShadowProcessor(Caches::getInstance());
}
- mShadowProcessor->add(task);
+ if (!mShadowProcessor->add(task)) {
+ mShadowProcessor->process(task);
+ }
task->incStrong(NULL); // not using sp<>s, so manually ref while in the cache
mShadowCache.put(key, task.get());
@@ -421,7 +423,9 @@
if (mProcessor == NULL) {
mProcessor = new TessellationProcessor(Caches::getInstance());
}
- mProcessor->add(task);
+ if (!mProcessor->add(task)) {
+ mProcessor->process(task);
+ }
mCache.put(entry, buffer);
}
return buffer;
diff --git a/libs/hwui/thread/TaskManager.cpp b/libs/hwui/thread/TaskManager.cpp
index 3c30aab..c69b2fd 100644
--- a/libs/hwui/thread/TaskManager.cpp
+++ b/libs/hwui/thread/TaskManager.cpp
@@ -105,6 +105,8 @@
bool TaskManager::WorkerThread::addTask(TaskWrapper task) {
if (!isRunning()) {
run(mName.string(), PRIORITY_DEFAULT);
+ } else if (exitPending()) {
+ return false;
}
Mutex::Autolock l(mLock);
@@ -120,10 +122,6 @@
}
void TaskManager::WorkerThread::exit() {
- {
- Mutex::Autolock l(mLock);
- mTasks.clear();
- }
requestExit();
mSignal.signal();
}
diff --git a/libs/hwui/thread/TaskProcessor.h b/libs/hwui/thread/TaskProcessor.h
index d1269f0..30b3719 100644
--- a/libs/hwui/thread/TaskProcessor.h
+++ b/libs/hwui/thread/TaskProcessor.h
@@ -30,9 +30,6 @@
TaskProcessorBase() { }
virtual ~TaskProcessorBase() { };
-private:
- friend class TaskManager;
-
virtual void process(const sp<TaskBase>& task) = 0;
};
@@ -44,9 +41,6 @@
bool add(const sp<Task<T> >& task);
- virtual void onProcess(const sp<Task<T> >& task) = 0;
-
-private:
virtual void process(const sp<TaskBase>& task) {
sp<Task<T> > realTask = static_cast<Task<T>* >(task.get());
// This is the right way to do it but sp<> doesn't play nice
@@ -54,6 +48,8 @@
onProcess(realTask);
}
+ virtual void onProcess(const sp<Task<T> >& task) = 0;
+
TaskManager* mManager;
};
diff --git a/media/jni/android_media_Utils.cpp b/media/jni/android_media_Utils.cpp
index ea33a2f..e101709 100644
--- a/media/jni/android_media_Utils.cpp
+++ b/media/jni/android_media_Utils.cpp
@@ -232,28 +232,28 @@
env,
hashMap,
hashMapPutID,
- StringPrintf("%s-left", key).c_str(),
+ AStringPrintf("%s-left", key).c_str(),
left);
SetMapInt32(
env,
hashMap,
hashMapPutID,
- StringPrintf("%s-top", key).c_str(),
+ AStringPrintf("%s-top", key).c_str(),
top);
SetMapInt32(
env,
hashMap,
hashMapPutID,
- StringPrintf("%s-right", key).c_str(),
+ AStringPrintf("%s-right", key).c_str(),
right);
SetMapInt32(
env,
hashMap,
hashMapPutID,
- StringPrintf("%s-bottom", key).c_str(),
+ AStringPrintf("%s-bottom", key).c_str(),
bottom);
break;
}
diff --git a/rs/java/android/renderscript/Allocation.java b/rs/java/android/renderscript/Allocation.java
index 3cda6de..69103e8 100644
--- a/rs/java/android/renderscript/Allocation.java
+++ b/rs/java/android/renderscript/Allocation.java
@@ -1878,4 +1878,15 @@
}
}
+ /**
+ * For USAGE_IO_OUTPUT, destroy() implies setSurface(null).
+ *
+ */
+ @Override
+ public void destroy() {
+ if((mUsage & USAGE_IO_OUTPUT) != 0) {
+ setSurface(null);
+ }
+ super.destroy();
+ }
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f7d6e8a..91736f3 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -15155,30 +15155,6 @@
// BROADCASTS
// =========================================================
- private final List getStickiesLocked(String action, IntentFilter filter,
- List cur, int userId) {
- final ContentResolver resolver = mContext.getContentResolver();
- ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
- if (stickies == null) {
- return cur;
- }
- final ArrayList<Intent> list = stickies.get(action);
- if (list == null) {
- return cur;
- }
- int N = list.size();
- for (int i=0; i<N; i++) {
- Intent intent = list.get(i);
- if (filter.match(resolver, intent, true, TAG) >= 0) {
- if (cur == null) {
- cur = new ArrayList<Intent>();
- }
- cur.add(intent);
- }
- }
- return cur;
- }
-
boolean isPendingBroadcastProcessLocked(int pid) {
return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
|| mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
@@ -15203,10 +15179,11 @@
public Intent registerReceiver(IApplicationThread caller, String callerPackage,
IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
enforceNotIsolatedCaller("registerReceiver");
+ ArrayList<Intent> stickyIntents = null;
+ ProcessRecord callerApp = null;
int callingUid;
int callingPid;
synchronized(this) {
- ProcessRecord callerApp = null;
if (caller != null) {
callerApp = getRecordForAppLocked(caller);
if (callerApp == null) {
@@ -15229,39 +15206,66 @@
callingPid = Binder.getCallingPid();
}
- userId = this.handleIncomingUser(callingPid, callingUid, userId,
+ userId = handleIncomingUser(callingPid, callingUid, userId,
true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
- List allSticky = null;
+ Iterator<String> actions = filter.actionsIterator();
+ if (actions == null) {
+ ArrayList<String> noAction = new ArrayList<String>(1);
+ noAction.add(null);
+ actions = noAction.iterator();
+ }
- // Look for any matching sticky broadcasts...
- Iterator actions = filter.actionsIterator();
- if (actions != null) {
- while (actions.hasNext()) {
- String action = (String)actions.next();
- allSticky = getStickiesLocked(action, filter, allSticky,
- UserHandle.USER_ALL);
- allSticky = getStickiesLocked(action, filter, allSticky,
- UserHandle.getUserId(callingUid));
+ // Collect stickies of users
+ int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
+ while (actions.hasNext()) {
+ String action = actions.next();
+ for (int id : userIds) {
+ ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
+ if (stickies != null) {
+ ArrayList<Intent> intents = stickies.get(action);
+ if (intents != null) {
+ if (stickyIntents == null) {
+ stickyIntents = new ArrayList<Intent>();
+ }
+ stickyIntents.addAll(intents);
+ }
+ }
}
- } else {
- allSticky = getStickiesLocked(null, filter, allSticky,
- UserHandle.USER_ALL);
- allSticky = getStickiesLocked(null, filter, allSticky,
- UserHandle.getUserId(callingUid));
}
+ }
- // The first sticky in the list is returned directly back to
- // the client.
- Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
-
- if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
- + ": " + sticky);
-
- if (receiver == null) {
- return sticky;
+ ArrayList<Intent> allSticky = null;
+ if (stickyIntents != null) {
+ final ContentResolver resolver = mContext.getContentResolver();
+ // Look for any matching sticky broadcasts...
+ for (int i = 0, N = stickyIntents.size(); i < N; i++) {
+ Intent intent = stickyIntents.get(i);
+ // If intent has scheme "content", it will need to acccess
+ // provider that needs to lock mProviderMap in ActivityThread
+ // and also it may need to wait application response, so we
+ // cannot lock ActivityManagerService here.
+ if (filter.match(resolver, intent, true, TAG) >= 0) {
+ if (allSticky == null) {
+ allSticky = new ArrayList<Intent>();
+ }
+ allSticky.add(intent);
+ }
}
+ }
+ // The first sticky in the list is returned directly back to the client.
+ Intent sticky = allSticky != null ? allSticky.get(0) : null;
+ if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter + ": " + sticky);
+ if (receiver == null) {
+ return sticky;
+ }
+
+ synchronized (this) {
+ if (callerApp != null && callerApp.pid == 0) {
+ // Caller already died
+ return null;
+ }
ReceiverList rl
= (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
if (rl == null) {