diff options
Diffstat (limited to 'services/java/com')
| -rw-r--r-- | services/java/com/android/server/ConnectivityService.java | 3 | ||||
| -rw-r--r-- | services/java/com/android/server/SystemServer.java | 1 | ||||
| -rw-r--r-- | services/java/com/android/server/UsbService.java | 133 | ||||
| -rw-r--r-- | services/java/com/android/server/WifiService.java | 65 | ||||
| -rw-r--r--[-rwxr-xr-x] | services/java/com/android/server/am/ActivityManagerService.java | 2 | ||||
| -rw-r--r-- | services/java/com/android/server/connectivity/Tethering.java | 9 |
6 files changed, 141 insertions, 72 deletions
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index e689654..26397bb 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -2142,7 +2142,8 @@ public class ConnectivityService extends IConnectivityManager.Stub { if (proxy == null) proxy = new ProxyProperties("", 0, ""); log("sending Proxy Broadcast for " + proxy); Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION); - intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING | + Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); intent.putExtra(Proxy.EXTRA_PROXY_INFO, proxy); mContext.sendStickyBroadcast(intent); } diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 978946f..62ff064 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -405,6 +405,7 @@ class ServerThread extends Thread { Slog.i(TAG, "USB Observer"); // Listen for USB changes usb = new UsbService(context); + ServiceManager.addService(Context.USB_SERVICE, usb); } catch (Throwable e) { Slog.e(TAG, "Failure starting UsbService", e); } diff --git a/services/java/com/android/server/UsbService.java b/services/java/com/android/server/UsbService.java index 8ef03d4..5c03fb2 100644 --- a/services/java/com/android/server/UsbService.java +++ b/services/java/com/android/server/UsbService.java @@ -19,10 +19,18 @@ package com.android.server; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; +import android.hardware.IUsbManager; +import android.hardware.UsbConstants; +import android.hardware.UsbDevice; +import android.hardware.UsbEndpoint; +import android.hardware.UsbInterface; import android.hardware.UsbManager; import android.net.Uri; +import android.os.Bundle; import android.os.Handler; import android.os.Message; +import android.os.Parcelable; +import android.os.ParcelFileDescriptor; import android.os.UEventObserver; import android.provider.Settings; import android.util.Log; @@ -32,11 +40,12 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.util.ArrayList; +import java.util.HashMap; /** * <p>UsbService monitors for changes to USB state. */ -class UsbService { +class UsbService extends IUsbManager.Stub { private static final String TAG = UsbService.class.getSimpleName(); private static final boolean LOG = false; @@ -68,10 +77,12 @@ class UsbService { private int mLastConnected = -1; private int mLastConfiguration = -1; - // lists of enabled and disabled USB functions + // lists of enabled and disabled USB functions (for USB device mode) private final ArrayList<String> mEnabledFunctions = new ArrayList<String>(); private final ArrayList<String> mDisabledFunctions = new ArrayList<String>(); + private final HashMap<String,UsbDevice> mDevices = new HashMap<String,UsbDevice>(); + private boolean mSystemReady; private final Context mContext; @@ -186,8 +197,106 @@ class UsbService { } } + // called from JNI in monitorUsbHostBus() + private void usbDeviceAdded(String deviceName, int vendorID, int productID, + int deviceClass, int deviceSubclass, int deviceProtocol, + /* array of quintuples containing id, class, subclass, protocol + and number of endpoints for each interface */ + int[] interfaceValues, + /* array of quadruples containing address, attributes, max packet size + and interval for each endpoint */ + int[] endpointValues) { + + // ignore hubs + if (deviceClass == UsbConstants.USB_CLASS_HUB) { + return; + } + + synchronized (mDevices) { + if (mDevices.get(deviceName) != null) { + Log.w(TAG, "device already on mDevices list: " + deviceName); + return; + } + + int numInterfaces = interfaceValues.length / 5; + Parcelable[] interfaces = new UsbInterface[numInterfaces]; + try { + // repackage interfaceValues as an array of UsbInterface + int intf, endp, ival = 0, eval = 0; + boolean hasGoodInterface = false; + for (intf = 0; intf < numInterfaces; intf++) { + int interfaceId = interfaceValues[ival++]; + int interfaceClass = interfaceValues[ival++]; + int interfaceSubclass = interfaceValues[ival++]; + int interfaceProtocol = interfaceValues[ival++]; + int numEndpoints = interfaceValues[ival++]; + + Parcelable[] endpoints = new UsbEndpoint[numEndpoints]; + for (endp = 0; endp < numEndpoints; endp++) { + int address = endpointValues[eval++]; + int attributes = endpointValues[eval++]; + int maxPacketSize = endpointValues[eval++]; + int interval = endpointValues[eval++]; + endpoints[endp] = new UsbEndpoint(address, attributes, + maxPacketSize, interval); + } + + if (interfaceClass != UsbConstants.USB_CLASS_HUB) { + hasGoodInterface = true; + } + interfaces[intf] = new UsbInterface(interfaceId, interfaceClass, + interfaceSubclass, interfaceProtocol, endpoints); + } + + if (!hasGoodInterface) { + return; + } + } catch (Exception e) { + // beware of index out of bound exceptions, which might happen if + // a device does not set bNumEndpoints correctly + Log.e(TAG, "error parsing USB descriptors", e); + return; + } + + UsbDevice device = new UsbDevice(deviceName, vendorID, productID, + deviceClass, deviceSubclass, deviceProtocol, interfaces); + mDevices.put(deviceName, device); + + Intent intent = new Intent(UsbManager.ACTION_USB_DEVICE_ATTACHED); + intent.putExtra(UsbManager.EXTRA_DEVICE_NAME, deviceName); + intent.putExtra(UsbManager.EXTRA_VENDOR_ID, vendorID); + intent.putExtra(UsbManager.EXTRA_PRODUCT_ID, productID); + intent.putExtra(UsbManager.EXTRA_DEVICE_CLASS, deviceClass); + intent.putExtra(UsbManager.EXTRA_DEVICE_SUBCLASS, deviceSubclass); + intent.putExtra(UsbManager.EXTRA_DEVICE_PROTOCOL, deviceProtocol); + intent.putExtra(UsbManager.EXTRA_DEVICE, device); + Log.d(TAG, "usbDeviceAdded, sending " + intent); + mContext.sendBroadcast(intent); + } + } + + // called from JNI in monitorUsbHostBus() + private void usbDeviceRemoved(String deviceName) { + synchronized (mDevices) { + UsbDevice device = mDevices.remove(deviceName); + if (device != null) { + Intent intent = new Intent(UsbManager.ACTION_USB_DEVICE_DETACHED); + intent.putExtra(UsbManager.EXTRA_DEVICE_NAME, deviceName); + Log.d(TAG, "usbDeviceRemoved, sending " + intent); + mContext.sendBroadcast(intent); + } + } + } + private void initHostSupport() { - // temporarily disabled + // Create a thread to call into native code to wait for USB host events. + // This thread will call us back on usbDeviceAdded and usbDeviceRemoved. + Runnable runnable = new Runnable() { + public void run() { + monitorUsbHostBus(); + } + }; + new Thread(null, runnable, "UsbService host thread").start(); } void systemReady() { @@ -208,6 +317,21 @@ class UsbService { mHandler.sendEmptyMessageDelayed(MSG_UPDATE, delayed ? UPDATE_DELAY : 0); } + /* Returns a list of all currently attached USB devices */ + public void getDeviceList(Bundle devices) { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_USB, null); + synchronized (mDevices) { + for (String name : mDevices.keySet()) { + devices.putParcelable(name, mDevices.get(name)); + } + } + } + + public ParcelFileDescriptor openDevice(String deviceName) { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_USB, null); + return nativeOpenDevice(deviceName); + } + private final Handler mHandler = new Handler() { private void addEnabledFunctions(Intent intent) { // include state of all USB functions in our extras @@ -249,4 +373,7 @@ class UsbService { } } }; + + private native void monitorUsbHostBus(); + private native ParcelFileDescriptor nativeOpenDevice(String deviceName); } diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java index cf07239..04f4e4e 100644 --- a/services/java/com/android/server/WifiService.java +++ b/services/java/com/android/server/WifiService.java @@ -39,7 +39,6 @@ import android.net.wifi.WifiConfiguration.KeyMgmt; import android.net.wifi.WpsConfiguration; import android.net.wifi.WpsResult; import android.net.ConnectivityManager; -import android.net.InterfaceConfiguration; import android.net.DhcpInfo; import android.net.NetworkInfo; import android.net.NetworkInfo.State; @@ -56,7 +55,6 @@ import android.provider.Settings; import android.text.TextUtils; import android.util.Slog; -import java.net.InetAddress; import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -113,9 +111,6 @@ public class WifiService extends IWifiManager.Stub { private final IBatteryStats mBatteryStats; - ConnectivityManager mCm; - private String[] mWifiRegexs; - /** * See {@link Settings.Secure#WIFI_IDLE_MS}. This is the default value if a * Settings.Secure value is not present. This timeout value is chosen as @@ -256,20 +251,6 @@ public class WifiService extends IWifiManager.Stub { }, new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED)); - mContext.registerReceiver( - new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - - ArrayList<String> available = intent.getStringArrayListExtra( - ConnectivityManager.EXTRA_AVAILABLE_TETHER); - ArrayList<String> active = intent.getStringArrayListExtra( - ConnectivityManager.EXTRA_ACTIVE_TETHER); - updateTetherState(available, active); - - } - },new IntentFilter(ConnectivityManager.ACTION_TETHER_STATE_CHANGED)); - IntentFilter filter = new IntentFilter(); filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); @@ -322,52 +303,6 @@ public class WifiService extends IWifiManager.Stub { setWifiEnabled(wifiEnabled); } - private void updateTetherState(ArrayList<String> available, ArrayList<String> tethered) { - - boolean wifiTethered = false; - boolean wifiAvailable = false; - - IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); - INetworkManagementService service = INetworkManagementService.Stub.asInterface(b); - - if (mCm == null) { - mCm = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE); - } - - mWifiRegexs = mCm.getTetherableWifiRegexs(); - - for (String intf : available) { - for (String regex : mWifiRegexs) { - if (intf.matches(regex)) { - - InterfaceConfiguration ifcg = null; - try { - ifcg = service.getInterfaceConfig(intf); - if (ifcg != null) { - /* IP/netmask: 192.168.43.1/255.255.255.0 */ - ifcg.addr = InetAddress.getByName("192.168.43.1"); - ifcg.mask = InetAddress.getByName("255.255.255.0"); - ifcg.interfaceFlags = "[up]"; - - service.setInterfaceConfig(intf, ifcg); - } - } catch (Exception e) { - Slog.e(TAG, "Error configuring interface " + intf + ", :" + e); - setWifiApEnabled(null, false); - return; - } - - if(mCm.tether(intf) != ConnectivityManager.TETHER_ERROR_NO_ERROR) { - Slog.e(TAG, "Error tethering on " + intf); - setWifiApEnabled(null, false); - return; - } - break; - } - } - } - } - private boolean testAndClearWifiSavedState() { final ContentResolver cr = mContext.getContentResolver(); int wifiSavedState = 0; diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 2bf90b5..da70f61 100755..100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -9637,7 +9637,7 @@ public final class ActivityManagerService extends ActivityManagerNative // r.record is null if findServiceLocked() failed the caller permission check if (r.record == null) { throw new SecurityException( - "Permission Denial: Accessing service " + "Permission Denial: Accessing service " + r.record.name + " from pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() + " requires " + r.permission); diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java index 26c7e71..4bc3b06 100644 --- a/services/java/com/android/server/connectivity/Tethering.java +++ b/services/java/com/android/server/connectivity/Tethering.java @@ -1188,8 +1188,13 @@ public class Tethering extends INetworkManagementEventObserver.Stub { try { service.startTethering(mDhcpRange); } catch (Exception e) { - transitionTo(mStartTetheringErrorState); - return false; + try { + service.stopTethering(); + service.startTethering(mDhcpRange); + } catch (Exception ee) { + transitionTo(mStartTetheringErrorState); + return false; + } } try { service.setDnsForwarders(mDnsServers); |
