Merge "Fixed a possible infinite loop in JsonReader#skipValue()"
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 816ae69..f73a92b 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -91,6 +91,7 @@
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -384,18 +385,37 @@
}
class ShutdownCallBack extends UnmountCallBack {
- IMountShutdownObserver observer;
- ShutdownCallBack(String path, IMountShutdownObserver observer) {
+ MountShutdownLatch mMountShutdownLatch;
+ ShutdownCallBack(String path, final MountShutdownLatch mountShutdownLatch) {
super(path, true, false);
- this.observer = observer;
+ mMountShutdownLatch = mountShutdownLatch;
}
@Override
void handleFinished() {
int ret = doUnmountVolume(path, true, removeEncryption);
- if (observer != null) {
+ Slog.i(TAG, "Unmount completed: " + path + ", result code: " + ret);
+ mMountShutdownLatch.countDown();
+ }
+ }
+
+ static class MountShutdownLatch {
+ private IMountShutdownObserver mObserver;
+ private AtomicInteger mCount;
+
+ MountShutdownLatch(final IMountShutdownObserver observer, int count) {
+ mObserver = observer;
+ mCount = new AtomicInteger(count);
+ }
+
+ void countDown() {
+ boolean sendShutdown = false;
+ if (mCount.decrementAndGet() == 0) {
+ sendShutdown = true;
+ }
+ if (sendShutdown && mObserver != null) {
try {
- observer.onShutDownComplete(ret);
+ mObserver.onShutDownComplete(StorageResultCode.OperationSucceeded);
} catch (RemoteException e) {
Slog.w(TAG, "RemoteException when shutting down");
}
@@ -1426,6 +1446,10 @@
Slog.i(TAG, "Shutting down");
synchronized (mVolumesLock) {
+ // Get all volumes to be unmounted.
+ MountShutdownLatch mountShutdownLatch = new MountShutdownLatch(observer,
+ mVolumeStates.size());
+
for (String path : mVolumeStates.keySet()) {
String state = mVolumeStates.get(path);
@@ -1461,19 +1485,16 @@
if (state.equals(Environment.MEDIA_MOUNTED)) {
// Post a unmount message.
- ShutdownCallBack ucb = new ShutdownCallBack(path, observer);
+ ShutdownCallBack ucb = new ShutdownCallBack(path, mountShutdownLatch);
mHandler.sendMessage(mHandler.obtainMessage(H_UNMOUNT_PM_UPDATE, ucb));
} else if (observer != null) {
/*
- * Observer is waiting for onShutDownComplete when we are done.
- * Since nothing will be done send notification directly so shutdown
- * sequence can continue.
+ * Count down, since nothing will be done. The observer will be
+ * notified when we are done so shutdown sequence can continue.
*/
- try {
- observer.onShutDownComplete(StorageResultCode.OperationSucceeded);
- } catch (RemoteException e) {
- Slog.w(TAG, "RemoteException when shutting down");
- }
+ mountShutdownLatch.countDown();
+ Slog.i(TAG, "Unmount completed: " + path +
+ ", result code: " + StorageResultCode.OperationSucceeded);
}
}
}
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index ad7ec99..e6c5422 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -82,6 +82,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
@@ -1022,6 +1023,15 @@
}
}
+ private List<InterfaceAddress> excludeLinkLocal(List<InterfaceAddress> addresses) {
+ ArrayList<InterfaceAddress> filtered = new ArrayList<InterfaceAddress>(addresses.size());
+ for (InterfaceAddress ia : addresses) {
+ if (!ia.getAddress().isLinkLocalAddress())
+ filtered.add(ia);
+ }
+ return filtered;
+ }
+
private void modifyNat(String action, String internalInterface, String externalInterface)
throws SocketException {
final Command cmd = new Command("nat", action, internalInterface, externalInterface);
@@ -1031,8 +1041,10 @@
if (internalNetworkInterface == null) {
cmd.appendArg("0");
} else {
- Collection<InterfaceAddress> interfaceAddresses = internalNetworkInterface
- .getInterfaceAddresses();
+ // Don't touch link-local routes, as link-local addresses aren't routable,
+ // kernel creates link-local routes on all interfaces automatically
+ List<InterfaceAddress> interfaceAddresses = excludeLinkLocal(
+ internalNetworkInterface.getInterfaceAddresses());
cmd.appendArg(interfaceAddresses.size());
for (InterfaceAddress ia : interfaceAddresses) {
InetAddress addr = NetworkUtils.getNetworkPart(
diff --git a/services/jni/com_android_server_UsbHostManager.cpp b/services/jni/com_android_server_UsbHostManager.cpp
index f1fa6cf..fc6de60 100644
--- a/services/jni/com_android_server_UsbHostManager.cpp
+++ b/services/jni/com_android_server_UsbHostManager.cpp
@@ -163,8 +163,10 @@
return NULL;
int fd = usb_device_get_fd(device);
- if (fd < 0)
+ if (fd < 0) {
+ usb_device_close(device);
return NULL;
+ }
int newFD = dup(fd);
usb_device_close(device);