diff options
3 files changed, 69 insertions, 47 deletions
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java index 7f61c6351842..fd0320198998 100644 --- a/services/java/com/android/server/MountService.java +++ b/services/java/com/android/server/MountService.java @@ -89,7 +89,8 @@ import javax.crypto.spec.PBEKeySpec; * @hide - Applications should use android.os.storage.StorageManager * to access the MountService. */ -class MountService extends IMountService.Stub implements INativeDaemonConnectorCallbacks { +class MountService extends IMountService.Stub + implements INativeDaemonConnectorCallbacks, Watchdog.Monitor { private static final boolean LOCAL_LOGD = false; private static final boolean DEBUG_UNMOUNT = false; @@ -474,7 +475,8 @@ class MountService extends IMountService.Stub implements INativeDaemonConnectorC // it is not safe to call vold with mVolumeStates locked // so we make a copy of the paths and states and process them // outside the lock - String[] paths, states; + String[] paths; + String[] states; int count; synchronized (mVolumeStates) { Set<String> keys = mVolumeStates.keySet(); @@ -1179,6 +1181,9 @@ class MountService extends IMountService.Stub implements INativeDaemonConnectorC mReady = false; Thread thread = new Thread(mConnector, VOLD_TAG); thread.start(); + + // Add ourself to the Watchdog monitors. + Watchdog.getInstance().addMonitor(this); } /** @@ -2379,5 +2384,11 @@ class MountService extends IMountService.Stub implements INativeDaemonConnectorC } } } -} + /** {@inheritDoc} */ + public void monitor() { + if (mConnector != null) { + mConnector.monitor(); + } + } +} diff --git a/services/java/com/android/server/NativeDaemonConnector.java b/services/java/com/android/server/NativeDaemonConnector.java index fed554cce31c..43d938cea3d8 100644 --- a/services/java/com/android/server/NativeDaemonConnector.java +++ b/services/java/com/android/server/NativeDaemonConnector.java @@ -16,24 +16,18 @@ package com.android.server; -import android.net.LocalSocketAddress; import android.net.LocalSocket; -import android.os.Environment; +import android.net.LocalSocketAddress; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; import android.os.SystemClock; -import android.os.SystemProperties; import android.util.Slog; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.net.Socket; - -import java.util.List; import java.util.ArrayList; -import java.util.ListIterator; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; @@ -42,7 +36,7 @@ import java.util.concurrent.LinkedBlockingQueue; * daemon which uses the libsysutils FrameworkListener * protocol. */ -final class NativeDaemonConnector implements Runnable, Handler.Callback { +final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdog.Monitor { private static final boolean LOCAL_LOGD = false; private BlockingQueue<String> mResponseQueue; @@ -52,6 +46,9 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback { private INativeDaemonConnectorCallbacks mCallbacks; private Handler mCallbackHandler; + /** Lock held whenever communicating with native daemon. */ + private Object mDaemonLock = new Object(); + private final int BUFFER_SIZE = 4096; class ResponseCode { @@ -177,7 +174,7 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback { Slog.e(TAG, "Communications error", ex); throw ex; } finally { - synchronized (this) { + synchronized (mDaemonLock) { if (mOutputStream != null) { try { mOutputStream.close(); @@ -198,9 +195,8 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback { } } - private void sendCommand(String command) - throws NativeDaemonConnectorException { - sendCommand(command, null); + private void sendCommandLocked(String command) throws NativeDaemonConnectorException { + sendCommandLocked(command, null); } /** @@ -209,25 +205,23 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback { * @param command The command to send to the daemon * @param argument The argument to send with the command (or null) */ - private void sendCommand(String command, String argument) - throws NativeDaemonConnectorException { - synchronized (this) { - if (LOCAL_LOGD) Slog.d(TAG, String.format("SND -> {%s} {%s}", command, argument)); - if (mOutputStream == null) { - Slog.e(TAG, "No connection to daemon", new IllegalStateException()); - throw new NativeDaemonConnectorException("No output stream!"); - } else { - StringBuilder builder = new StringBuilder(command); - if (argument != null) { - builder.append(argument); - } - builder.append('\0'); + private void sendCommandLocked(String command, String argument) + throws NativeDaemonConnectorException { + if (LOCAL_LOGD) Slog.d(TAG, String.format("SND -> {%s} {%s}", command, argument)); + if (mOutputStream == null) { + Slog.e(TAG, "No connection to daemon", new IllegalStateException()); + throw new NativeDaemonConnectorException("No output stream!"); + } else { + StringBuilder builder = new StringBuilder(command); + if (argument != null) { + builder.append(argument); + } + builder.append('\0'); - try { - mOutputStream.write(builder.toString().getBytes()); - } catch (IOException ex) { - Slog.e(TAG, "IOException in sendCommand", ex); - } + try { + mOutputStream.write(builder.toString().getBytes()); + } catch (IOException ex) { + Slog.e(TAG, "IOException in sendCommand", ex); } } } @@ -235,10 +229,15 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback { /** * Issue a command to the native daemon and return the responses */ - public synchronized ArrayList<String> doCommand(String cmd) - throws NativeDaemonConnectorException { + public ArrayList<String> doCommand(String cmd) throws NativeDaemonConnectorException { + synchronized (mDaemonLock) { + return doCommandLocked(cmd); + } + } + + private ArrayList<String> doCommandLocked(String cmd) throws NativeDaemonConnectorException { mResponseQueue.clear(); - sendCommand(cmd); + sendCommandLocked(cmd); ArrayList<String> response = new ArrayList<String>(); boolean complete = false; @@ -278,7 +277,7 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback { return response; } - /* + /** * Issues a list command and returns the cooked list */ public String[] doListCommand(String cmd, int expectedResponseCode) @@ -317,4 +316,9 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback { } throw new NativeDaemonConnectorException("Got an empty response"); } + + /** {@inheritDoc} */ + public void monitor() { + synchronized (mDaemonLock) { } + } } diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java index 782e7d7acdd5..2fd9b21a694f 100644 --- a/services/java/com/android/server/NetworkManagementService.java +++ b/services/java/com/android/server/NetworkManagementService.java @@ -68,7 +68,7 @@ import libcore.io.IoUtils; /** * @hide */ -class NetworkManagementService extends INetworkManagementService.Stub { +class NetworkManagementService extends INetworkManagementService.Stub implements Watchdog.Monitor { private static final String TAG = "NetworkManagementService"; private static final boolean DBG = false; private static final String NETD_TAG = "NetdConnector"; @@ -139,7 +139,7 @@ class NetworkManagementService extends INetworkManagementService.Stub { /** Set of UIDs with active reject rules. */ private SparseBooleanArray mUidRejectOnQuota = new SparseBooleanArray(); - private boolean mBandwidthControlEnabled; + private volatile boolean mBandwidthControlEnabled; /** * Constructs a new NetworkManagementService instance @@ -162,6 +162,9 @@ class NetworkManagementService extends INetworkManagementService.Stub { mConnector = new NativeDaemonConnector( new NetdCallbackReceiver(), "netd", 10, NETD_TAG); mThread = new Thread(mConnector, NETD_TAG); + + // Add ourself to the Watchdog monitors. + Watchdog.getInstance().addMonitor(this); } public static NetworkManagementService create(Context context) throws InterruptedException { @@ -185,14 +188,12 @@ class NetworkManagementService extends INetworkManagementService.Stub { } public void systemReady() { - // only enable bandwidth control when support exists, and requested by // system setting. final boolean hasKernelSupport = new File("/proc/net/xt_qtaguid/ctrl").exists(); final boolean shouldEnable = Settings.Secure.getInt(mContext.getContentResolver(), NETSTATS_ENABLED, 1) != 0; - mBandwidthControlEnabled = false; if (hasKernelSupport && shouldEnable) { Slog.d(TAG, "enabling bandwidth control"); try { @@ -288,7 +289,7 @@ class NetworkManagementService extends INetworkManagementService.Stub { /** * Let us know the daemon is connected */ - protected void onConnected() { + protected void onDaemonConnected() { if (DBG) Slog.d(TAG, "onConnected"); mConnectedSignal.countDown(); } @@ -299,13 +300,12 @@ class NetworkManagementService extends INetworkManagementService.Stub { // class NetdCallbackReceiver implements INativeDaemonConnectorCallbacks { + /** {@inheritDoc} */ public void onDaemonConnected() { - NetworkManagementService.this.onConnected(); - new Thread() { - public void run() { - } - }.start(); + NetworkManagementService.this.onDaemonConnected(); } + + /** {@inheritDoc} */ public boolean onEvent(int code, String raw, String[] cooked) { switch (code) { case NetdResponseCode.InterfaceChange: @@ -1556,4 +1556,11 @@ class NetworkManagementService extends INetworkManagementService.Stub { "Error communicating with native daemon to flush interface " + iface, e); } } + + /** {@inheritDoc} */ + public void monitor() { + if (mConnector != null) { + mConnector.monitor(); + } + } } |