summaryrefslogtreecommitdiffstats
path: root/services/java/com
diff options
context:
space:
mode:
Diffstat (limited to 'services/java/com')
-rw-r--r--services/java/com/android/server/ConnectivityService.java3
-rw-r--r--services/java/com/android/server/SystemServer.java1
-rw-r--r--services/java/com/android/server/UsbService.java133
-rw-r--r--services/java/com/android/server/WifiService.java65
-rw-r--r--[-rwxr-xr-x]services/java/com/android/server/am/ActivityManagerService.java2
-rw-r--r--services/java/com/android/server/connectivity/Tethering.java9
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);