diff options
23 files changed, 414 insertions, 347 deletions
diff --git a/core/java/android/hardware/Usb.java b/core/java/android/hardware/UsbManager.java index 57271d4b72f8..18790d254e00 100644 --- a/core/java/android/hardware/Usb.java +++ b/core/java/android/hardware/UsbManager.java @@ -17,38 +17,22 @@ package android.hardware; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + /** * Class for accessing USB state information. * @hide */ -public class Usb { - /** - * Broadcast Action: A broadcast for USB connected events. - * - * The extras bundle will name/value pairs with the name of the function - * and a value of either {@link #USB_FUNCTION_ENABLED} or {@link #USB_FUNCTION_DISABLED}. - * Possible USB function names include {@link #USB_FUNCTION_MASS_STORAGE}, - * {@link #USB_FUNCTION_ADB}, {@link #USB_FUNCTION_RNDIS} and {@link #USB_FUNCTION_MTP}. - */ - public static final String ACTION_USB_CONNECTED = - "android.hardware.action.USB_CONNECTED"; - - /** - * Broadcast Action: A broadcast for USB disconnected events. - */ - public static final String ACTION_USB_DISCONNECTED = - "android.hardware.action.USB_DISCONNECTED"; - +public class UsbManager { /** * Broadcast Action: A sticky broadcast for USB state change events. * - * This is a sticky broadcast for clients that are interested in both USB connect and - * disconnect events. If you are only concerned with one or the other, you can use - * {@link #ACTION_USB_CONNECTED} or {@link #ACTION_USB_DISCONNECTED} to avoid receiving - * unnecessary broadcasts. The boolean {@link #USB_CONNECTED} extra indicates whether - * USB is connected or disconnected. - * The extras bundle will also contain name/value pairs with the name of the function - * and a value of either {@link #USB_FUNCTION_ENABLED} or {@link #USB_FUNCTION_DISABLED}. + * This is a sticky broadcast for clients that includes USB connected/disconnected state, + * the USB configuration that is currently set and a bundle containing name/value pairs + * with the names of the functions and a value of either {@link #USB_FUNCTION_ENABLED} + * or {@link #USB_FUNCTION_DISABLED}. * Possible USB function names include {@link #USB_FUNCTION_MASS_STORAGE}, * {@link #USB_FUNCTION_ADB}, {@link #USB_FUNCTION_RNDIS} and {@link #USB_FUNCTION_MTP}. */ @@ -62,38 +46,70 @@ public class Usb { public static final String USB_CONNECTED = "connected"; /** + * Integer extra containing currently set USB configuration. + * Used in extras for the {@link #ACTION_USB_STATE} broadcast. + */ + public static final String USB_CONFIGURATION = "configuration"; + + /** * Name of the USB mass storage USB function. - * Used in extras for the {@link #ACTION_USB_CONNECTED} broadcast + * Used in extras for the {@link #ACTION_USB_STATE} broadcast */ public static final String USB_FUNCTION_MASS_STORAGE = "mass_storage"; /** * Name of the adb USB function. - * Used in extras for the {@link #ACTION_USB_CONNECTED} broadcast + * Used in extras for the {@link #ACTION_USB_STATE} broadcast */ public static final String USB_FUNCTION_ADB = "adb"; /** * Name of the RNDIS ethernet USB function. - * Used in extras for the {@link #ACTION_USB_CONNECTED} broadcast + * Used in extras for the {@link #ACTION_USB_STATE} broadcast */ public static final String USB_FUNCTION_RNDIS = "rndis"; /** * Name of the MTP USB function. - * Used in extras for the {@link #ACTION_USB_CONNECTED} broadcast + * Used in extras for the {@link #ACTION_USB_STATE} broadcast */ public static final String USB_FUNCTION_MTP = "mtp"; /** * Value indicating that a USB function is enabled. - * Used in extras for the {@link #ACTION_USB_CONNECTED} broadcast + * Used in extras for the {@link #ACTION_USB_STATE} broadcast */ public static final String USB_FUNCTION_ENABLED = "enabled"; /** * Value indicating that a USB function is disabled. - * Used in extras for the {@link #ACTION_USB_CONNECTED} broadcast + * Used in extras for the {@link #ACTION_USB_STATE} broadcast */ public static final String USB_FUNCTION_DISABLED = "disabled"; + + private static File getFunctionEnableFile(String function) { + return new File("/sys/class/usb_composite/" + function + "/enable"); + } + + /** + * Returns true if the specified USB function is supported by the kernel. + * Note that a USB function maybe supported but disabled. + */ + public static boolean isFunctionSupported(String function) { + return getFunctionEnableFile(function).exists(); + } + + /** + * Returns true if the specified USB function is currently enabled. + */ + public static boolean isFunctionEnabled(String function) { + try { + FileInputStream stream = new FileInputStream(getFunctionEnableFile(function)); + boolean enabled = (stream.read() == '1'); + stream.close(); + return enabled; + } catch (IOException e) { + return false; + } + } } diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index f0e5517e0dd6..060f858c42c2 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -511,7 +511,7 @@ public class ZygoteInit { String args[] = { "--setuid=1000", "--setgid=1000", - "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,3001,3002,3003", + "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003", "--capabilities=130104352,130104352", "--runtime-init", "--nice-name=system_server", diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java index 5c52783d3a9d..1368baaf8caa 100644 --- a/packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java +++ b/packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java @@ -30,7 +30,7 @@ import android.content.DialogInterface.OnCancelListener; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; -import android.hardware.Usb; +import android.hardware.UsbManager; import android.os.Bundle; import android.os.Environment; import android.os.Handler; @@ -83,7 +83,7 @@ public class UsbStorageActivity extends Activity private BroadcastReceiver mUsbStateReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - if (intent.getAction().equals(Usb.ACTION_USB_STATE)) { + if (intent.getAction().equals(UsbManager.ACTION_USB_STATE)) { handleUsbStateChanged(intent); } } @@ -175,7 +175,7 @@ public class UsbStorageActivity extends Activity super.onResume(); mStorageManager.registerListener(mStorageListener); - registerReceiver(mUsbStateReceiver, new IntentFilter(Usb.ACTION_USB_STATE)); + registerReceiver(mUsbStateReceiver, new IntentFilter(UsbManager.ACTION_USB_STATE)); try { mAsyncStorageHandler.post(new Runnable() { @Override @@ -199,7 +199,7 @@ public class UsbStorageActivity extends Activity } private void handleUsbStateChanged(Intent intent) { - boolean connected = intent.getExtras().getBoolean(Usb.USB_CONNECTED); + boolean connected = intent.getExtras().getBoolean(UsbManager.USB_CONNECTED); if (!connected) { // It was disconnected from the plug, so finish finish(); diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java index e8c1613eb440..a5333daafb35 100755 --- a/services/java/com/android/server/NotificationManagerService.java +++ b/services/java/com/android/server/NotificationManagerService.java @@ -38,7 +38,7 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; import android.database.ContentObserver; -import android.hardware.Usb; +import android.hardware.UsbManager; import android.media.AudioManager; import android.net.Uri; import android.os.BatteryManager; @@ -352,14 +352,12 @@ public class NotificationManagerService extends INotificationManager.Stub mBatteryFull = batteryFull; updateLights(); } - } else if (action.equals(Usb.ACTION_USB_STATE)) { + } else if (action.equals(UsbManager.ACTION_USB_STATE)) { Bundle extras = intent.getExtras(); - boolean usbConnected = extras.getBoolean(Usb.USB_CONNECTED); - boolean adbEnabled = (Usb.USB_FUNCTION_ENABLED.equals( - extras.getString(Usb.USB_FUNCTION_ADB))); + boolean usbConnected = extras.getBoolean(UsbManager.USB_CONNECTED); + boolean adbEnabled = (UsbManager.USB_FUNCTION_ENABLED.equals( + extras.getString(UsbManager.USB_FUNCTION_ADB))); updateAdbNotification(usbConnected && adbEnabled); - } else if (action.equals(Usb.ACTION_USB_DISCONNECTED)) { - updateAdbNotification(false); } else if (action.equals(Intent.ACTION_PACKAGE_REMOVED) || action.equals(Intent.ACTION_PACKAGE_RESTARTED) || (queryRestart=action.equals(Intent.ACTION_QUERY_PACKAGE_RESTART)) @@ -464,7 +462,7 @@ public class NotificationManagerService extends INotificationManager.Stub // register for battery changed notifications IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_BATTERY_CHANGED); - filter.addAction(Usb.ACTION_USB_STATE); + filter.addAction(UsbManager.ACTION_USB_STATE); filter.addAction(Intent.ACTION_SCREEN_ON); filter.addAction(Intent.ACTION_SCREEN_OFF); filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED); diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index df69b76c339f..25175e239db6 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -122,7 +122,7 @@ class ServerThread extends Thread { BluetoothA2dpService bluetoothA2dp = null; HeadsetObserver headset = null; DockObserver dock = null; - UsbObserver usb = null; + UsbService usb = null; UiModeManagerService uiMode = null; RecognitionManagerService recognition = null; ThrottleService throttle = null; @@ -399,9 +399,9 @@ class ServerThread extends Thread { try { Slog.i(TAG, "USB Observer"); // Listen for USB changes - usb = new UsbObserver(context); + usb = new UsbService(context); } catch (Throwable e) { - Slog.e(TAG, "Failure starting UsbObserver", e); + Slog.e(TAG, "Failure starting UsbService", e); } try { @@ -493,7 +493,7 @@ class ServerThread extends Thread { final BatteryService batteryF = battery; final ConnectivityService connectivityF = connectivity; final DockObserver dockF = dock; - final UsbObserver usbF = usb; + final UsbService usbF = usb; final ThrottleService throttleF = throttle; final UiModeManagerService uiModeF = uiMode; final AppWidgetService appWidgetF = appWidget; diff --git a/services/java/com/android/server/UsbObserver.java b/services/java/com/android/server/UsbObserver.java deleted file mode 100644 index d08fe9b3964b..000000000000 --- a/services/java/com/android/server/UsbObserver.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (C) 2010 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 com.android.server; - -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.hardware.Usb; -import android.net.Uri; -import android.os.Handler; -import android.os.Message; -import android.os.UEventObserver; -import android.provider.Settings; -import android.util.Log; -import android.util.Slog; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.util.ArrayList; - -/** - * <p>UsbObserver monitors for changes to USB state. - */ -class UsbObserver extends UEventObserver { - private static final String TAG = UsbObserver.class.getSimpleName(); - private static final boolean LOG = false; - - private static final String USB_CONFIGURATION_MATCH = "DEVPATH=/devices/virtual/switch/usb_configuration"; - private static final String USB_FUNCTIONS_MATCH = "DEVPATH=/devices/virtual/usb_composite/"; - private static final String USB_CONFIGURATION_PATH = "/sys/class/switch/usb_configuration/state"; - private static final String USB_COMPOSITE_CLASS_PATH = "/sys/class/usb_composite"; - - private static final int MSG_UPDATE = 0; - - private int mUsbConfig = 0; - private int mPreviousUsbConfig = 0; - - // lists of enabled and disabled USB functions - private final ArrayList<String> mEnabledFunctions = new ArrayList<String>(); - private final ArrayList<String> mDisabledFunctions = new ArrayList<String>(); - - private boolean mSystemReady; - - private final Context mContext; - - private PowerManagerService mPowerManager; - - public UsbObserver(Context context) { - mContext = context; - init(); // set initial status - - startObserving(USB_CONFIGURATION_MATCH); - startObserving(USB_FUNCTIONS_MATCH); - } - - @Override - public void onUEvent(UEventObserver.UEvent event) { - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Slog.v(TAG, "USB UEVENT: " + event.toString()); - } - - synchronized (this) { - String switchState = event.get("SWITCH_STATE"); - if (switchState != null) { - try { - int newConfig = Integer.parseInt(switchState); - if (newConfig != mUsbConfig) { - mPreviousUsbConfig = mUsbConfig; - mUsbConfig = newConfig; - // trigger an Intent broadcast - if (mSystemReady) { - update(); - } - } - } catch (NumberFormatException e) { - Slog.e(TAG, "Could not parse switch state from event " + event); - } - } else { - String function = event.get("FUNCTION"); - String enabledStr = event.get("ENABLED"); - if (function != null && enabledStr != null) { - // Note: we do not broadcast a change when a function is enabled or disabled. - // We just record the state change for the next broadcast. - boolean enabled = "1".equals(enabledStr); - if (enabled) { - if (!mEnabledFunctions.contains(function)) { - mEnabledFunctions.add(function); - } - mDisabledFunctions.remove(function); - } else { - if (!mDisabledFunctions.contains(function)) { - mDisabledFunctions.add(function); - } - mEnabledFunctions.remove(function); - } - } - } - } - } - private final void init() { - char[] buffer = new char[1024]; - - try { - FileReader file = new FileReader(USB_CONFIGURATION_PATH); - int len = file.read(buffer, 0, 1024); - mPreviousUsbConfig = mUsbConfig = Integer.valueOf((new String(buffer, 0, len)).trim()); - - } catch (FileNotFoundException e) { - Slog.w(TAG, "This kernel does not have USB configuration switch support"); - } catch (Exception e) { - Slog.e(TAG, "" , e); - } - - try { - File[] files = new File(USB_COMPOSITE_CLASS_PATH).listFiles(); - for (int i = 0; i < files.length; i++) { - File file = new File(files[i], "enable"); - FileReader reader = new FileReader(file); - int len = reader.read(buffer, 0, 1024); - int value = Integer.valueOf((new String(buffer, 0, len)).trim()); - String functionName = files[i].getName(); - if (value == 1) { - mEnabledFunctions.add(functionName); - } else { - mDisabledFunctions.add(functionName); - } - } - } catch (FileNotFoundException e) { - Slog.w(TAG, "This kernel does not have USB composite class support"); - } catch (Exception e) { - Slog.e(TAG, "" , e); - } - } - - void systemReady() { - synchronized (this) { - update(); - mSystemReady = true; - } - } - - private final void update() { - mHandler.sendEmptyMessage(MSG_UPDATE); - } - - private final Handler mHandler = new Handler() { - private void addEnabledFunctions(Intent intent) { - // include state of all USB functions in our extras - for (int i = 0; i < mEnabledFunctions.size(); i++) { - intent.putExtra(mEnabledFunctions.get(i), Usb.USB_FUNCTION_ENABLED); - } - for (int i = 0; i < mDisabledFunctions.size(); i++) { - intent.putExtra(mDisabledFunctions.get(i), Usb.USB_FUNCTION_DISABLED); - } - } - - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case MSG_UPDATE: - synchronized (this) { - final ContentResolver cr = mContext.getContentResolver(); - - if (Settings.Secure.getInt(cr, - Settings.Secure.DEVICE_PROVISIONED, 0) == 0) { - Slog.i(TAG, "Device not provisioned, skipping USB broadcast"); - return; - } - // Send an Intent containing connected/disconnected state - // and the enabled/disabled state of all USB functions - Intent intent; - boolean usbConnected = (mUsbConfig != 0); - if (usbConnected) { - intent = new Intent(Usb.ACTION_USB_CONNECTED); - addEnabledFunctions(intent); - } else { - intent = new Intent(Usb.ACTION_USB_DISCONNECTED); - } - mContext.sendBroadcast(intent); - - // send a sticky broadcast for clients interested in both connect and disconnect - intent = new Intent(Usb.ACTION_USB_STATE); - intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); - intent.putExtra(Usb.USB_CONNECTED, usbConnected); - addEnabledFunctions(intent); - mContext.sendStickyBroadcast(intent); - } - break; - } - } - }; -} diff --git a/services/java/com/android/server/UsbService.java b/services/java/com/android/server/UsbService.java new file mode 100644 index 000000000000..578db0e73769 --- /dev/null +++ b/services/java/com/android/server/UsbService.java @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2010 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 com.android.server; + +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.hardware.UsbManager; +import android.net.Uri; +import android.os.Handler; +import android.os.Message; +import android.os.UEventObserver; +import android.provider.Settings; +import android.util.Log; +import android.util.Slog; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.util.ArrayList; + +/** + * <p>UsbService monitors for changes to USB state. + */ +class UsbService { + private static final String TAG = UsbService.class.getSimpleName(); + private static final boolean LOG = false; + + private static final String USB_CONNECTED_MATCH = + "DEVPATH=/devices/virtual/switch/usb_connected"; + private static final String USB_CONFIGURATION_MATCH = + "DEVPATH=/devices/virtual/switch/usb_configuration"; + private static final String USB_FUNCTIONS_MATCH = + "DEVPATH=/devices/virtual/usb_composite/"; + private static final String USB_CONNECTED_PATH = + "/sys/class/switch/usb_connected/state"; + private static final String USB_CONFIGURATION_PATH = + "/sys/class/switch/usb_configuration/state"; + private static final String USB_COMPOSITE_CLASS_PATH = + "/sys/class/usb_composite"; + + private static final int MSG_UPDATE = 0; + + // Delay for debouncing USB disconnects. + // We often get rapid connect/disconnect events when enabling USB functions, + // which need debouncing. + private static final int UPDATE_DELAY = 1000; + + // current connected and configuration state + private int mConnected; + private int mConfiguration; + + // last broadcasted connected and configuration state + private int mLastConnected = -1; + private int mLastConfiguration = -1; + + // lists of enabled and disabled USB functions + private final ArrayList<String> mEnabledFunctions = new ArrayList<String>(); + private final ArrayList<String> mDisabledFunctions = new ArrayList<String>(); + + private boolean mSystemReady; + + private final Context mContext; + + private final UEventObserver mUEventObserver = new UEventObserver() { + @Override + public void onUEvent(UEventObserver.UEvent event) { + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Slog.v(TAG, "USB UEVENT: " + event.toString()); + } + + synchronized (this) { + String name = event.get("SWITCH_NAME"); + String state = event.get("SWITCH_STATE"); + if (name != null && state != null) { + try { + int intState = Integer.parseInt(state); + if ("usb_connected".equals(name)) { + mConnected = intState; + // trigger an Intent broadcast + if (mSystemReady) { + // debounce disconnects + update(mConnected == 0); + } + } else if ("usb_configuration".equals(name)) { + mConfiguration = intState; + // trigger an Intent broadcast + if (mSystemReady) { + update(mConnected == 0); + } + } + } catch (NumberFormatException e) { + Slog.e(TAG, "Could not parse switch state from event " + event); + } + } else { + String function = event.get("FUNCTION"); + String enabledStr = event.get("ENABLED"); + if (function != null && enabledStr != null) { + // Note: we do not broadcast a change when a function is enabled or disabled. + // We just record the state change for the next broadcast. + boolean enabled = "1".equals(enabledStr); + if (enabled) { + if (!mEnabledFunctions.contains(function)) { + mEnabledFunctions.add(function); + } + mDisabledFunctions.remove(function); + } else { + if (!mDisabledFunctions.contains(function)) { + mDisabledFunctions.add(function); + } + mEnabledFunctions.remove(function); + } + } + } + } + } + }; + + public UsbService(Context context) { + mContext = context; + init(); // set initial status + + if (mConfiguration >= 0) { + mUEventObserver.startObserving(USB_CONNECTED_MATCH); + mUEventObserver.startObserving(USB_CONFIGURATION_MATCH); + mUEventObserver.startObserving(USB_FUNCTIONS_MATCH); + } + } + + private final void init() { + char[] buffer = new char[1024]; + + mConfiguration = -1; + try { + FileReader file = new FileReader(USB_CONNECTED_PATH); + int len = file.read(buffer, 0, 1024); + file.close(); + mConnected = Integer.valueOf((new String(buffer, 0, len)).trim()); + + file = new FileReader(USB_CONFIGURATION_PATH); + len = file.read(buffer, 0, 1024); + file.close(); + mConfiguration = Integer.valueOf((new String(buffer, 0, len)).trim()); + } catch (FileNotFoundException e) { + Slog.i(TAG, "This kernel does not have USB configuration switch support"); + } catch (Exception e) { + Slog.e(TAG, "" , e); + } + if (mConfiguration < 0) + return; + + try { + File[] files = new File(USB_COMPOSITE_CLASS_PATH).listFiles(); + for (int i = 0; i < files.length; i++) { + File file = new File(files[i], "enable"); + FileReader reader = new FileReader(file); + int len = reader.read(buffer, 0, 1024); + reader.close(); + int value = Integer.valueOf((new String(buffer, 0, len)).trim()); + String functionName = files[i].getName(); + if (value == 1) { + mEnabledFunctions.add(functionName); + } else { + mDisabledFunctions.add(functionName); + } + } + } catch (FileNotFoundException e) { + Slog.w(TAG, "This kernel does not have USB composite class support"); + } catch (Exception e) { + Slog.e(TAG, "" , e); + } + } + + void systemReady() { + synchronized (this) { + update(false); + mSystemReady = true; + } + } + + private final void update(boolean delayed) { + mHandler.removeMessages(MSG_UPDATE); + mHandler.sendEmptyMessageDelayed(MSG_UPDATE, delayed ? UPDATE_DELAY : 0); + } + + private final Handler mHandler = new Handler() { + private void addEnabledFunctions(Intent intent) { + // include state of all USB functions in our extras + for (int i = 0; i < mEnabledFunctions.size(); i++) { + intent.putExtra(mEnabledFunctions.get(i), UsbManager.USB_FUNCTION_ENABLED); + } + for (int i = 0; i < mDisabledFunctions.size(); i++) { + intent.putExtra(mDisabledFunctions.get(i), UsbManager.USB_FUNCTION_DISABLED); + } + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_UPDATE: + synchronized (this) { + if (mConnected != mLastConnected || mConfiguration != mLastConfiguration) { + + final ContentResolver cr = mContext.getContentResolver(); + if (Settings.Secure.getInt(cr, + Settings.Secure.DEVICE_PROVISIONED, 0) == 0) { + Slog.i(TAG, "Device not provisioned, skipping USB broadcast"); + return; + } + + mLastConnected = mConnected; + mLastConfiguration = mConfiguration; + + // send a sticky broadcast containing current USB state + Intent intent = new Intent(UsbManager.ACTION_USB_STATE); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); + intent.putExtra(UsbManager.USB_CONNECTED, mConnected != 0); + intent.putExtra(UsbManager.USB_CONFIGURATION, mConfiguration); + addEnabledFunctions(intent); + mContext.sendStickyBroadcast(intent); + } + } + break; + } + } + }; +} diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java index a73a4ce26485..7652a267b7bd 100644 --- a/services/java/com/android/server/connectivity/Tethering.java +++ b/services/java/com/android/server/connectivity/Tethering.java @@ -26,7 +26,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.content.res.Resources; -import android.hardware.Usb; +import android.hardware.UsbManager; import android.net.ConnectivityManager; import android.net.InterfaceConfiguration; import android.net.IConnectivityManager; @@ -111,14 +111,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub { private boolean mUsbMassStorageOff; // track the status of USB Mass Storage private boolean mUsbConnected; // track the status of USB connection - // mUsbHandler message - static final int USB_STATE_CHANGE = 1; - static final int USB_DISCONNECTED = 0; - static final int USB_CONNECTED = 1; - - // Time to delay before processing USB disconnect events - static final long USB_DISCONNECT_DELAY = 1000; - public Tethering(Context context, Looper looper) { mContext = context; mLooper = looper; @@ -143,7 +135,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { mStateReceiver = new StateReceiver(); IntentFilter filter = new IntentFilter(); - filter.addAction(Usb.ACTION_USB_STATE); + filter.addAction(UsbManager.ACTION_USB_STATE); filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); filter.addAction(Intent.ACTION_BOOT_COMPLETED); mContext.registerReceiver(mStateReceiver, filter); @@ -429,25 +421,12 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } } - private Handler mUsbHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - mUsbConnected = (msg.arg1 == USB_CONNECTED); - updateUsbStatus(); - } - }; - private class StateReceiver extends BroadcastReceiver { public void onReceive(Context content, Intent intent) { String action = intent.getAction(); - if (action.equals(Usb.ACTION_USB_STATE)) { - // process connect events immediately, but delay handling disconnects - // to debounce USB configuration changes - boolean connected = intent.getExtras().getBoolean(Usb.USB_CONNECTED); - Message msg = Message.obtain(mUsbHandler, USB_STATE_CHANGE, - (connected ? USB_CONNECTED : USB_DISCONNECTED), 0); - mUsbHandler.removeMessages(USB_STATE_CHANGE); - mUsbHandler.sendMessageDelayed(msg, connected ? 0 : USB_DISCONNECT_DELAY); + if (action.equals(UsbManager.ACTION_USB_STATE)) { + mUsbConnected = intent.getExtras().getBoolean(UsbManager.USB_CONNECTED); + updateUsbStatus(); } else if (action.equals(Intent.ACTION_MEDIA_SHARED)) { mUsbMassStorageOff = false; updateUsbStatus(); diff --git a/services/jni/Android.mk b/services/jni/Android.mk index c90879d0a166..de8f15891feb 100644 --- a/services/jni/Android.mk +++ b/services/jni/Android.mk @@ -8,6 +8,7 @@ LOCAL_SRC_FILES:= \ com_android_server_LightsService.cpp \ com_android_server_PowerManagerService.cpp \ com_android_server_SystemServer.cpp \ + com_android_server_UsbService.cpp \ com_android_server_VibratorService.cpp \ com_android_server_location_GpsLocationProvider.cpp \ onload.cpp diff --git a/services/jni/com_android_server_UsbService.cpp b/services/jni/com_android_server_UsbService.cpp new file mode 100644 index 000000000000..dff86651c8b6 --- /dev/null +++ b/services/jni/com_android_server_UsbService.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2009 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. + */ + +#define LOG_TAG "UsbService" +#include "utils/Log.h" + +#include "jni.h" +#include "JNIHelp.h" +#include "android_runtime/AndroidRuntime.h" +#include "utils/Vector.h" + +#include <stdio.h> + +namespace android +{ + +int register_android_server_UsbService(JNIEnv *env) +{ + + return 0; +} + +}; diff --git a/services/jni/onload.cpp b/services/jni/onload.cpp index cd4f0a46c517..613683bf96b6 100644 --- a/services/jni/onload.cpp +++ b/services/jni/onload.cpp @@ -9,6 +9,7 @@ int register_android_server_BatteryService(JNIEnv* env); int register_android_server_InputManager(JNIEnv* env); int register_android_server_LightsService(JNIEnv* env); int register_android_server_PowerManagerService(JNIEnv* env); +int register_android_server_UsbService(JNIEnv* env); int register_android_server_VibratorService(JNIEnv* env); int register_android_server_SystemServer(JNIEnv* env); int register_android_server_location_GpsLocationProvider(JNIEnv* env); @@ -32,6 +33,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved) register_android_server_LightsService(env); register_android_server_AlarmManagerService(env); register_android_server_BatteryService(env); + register_android_server_UsbService(env); register_android_server_VibratorService(env); register_android_server_SystemServer(env); register_android_server_location_GpsLocationProvider(env); diff --git a/tools/layoutlib/.gitignore b/tools/layoutlib/.gitignore index 0ec5000668c7..c5e82d74585d 100644 --- a/tools/layoutlib/.gitignore +++ b/tools/layoutlib/.gitignore @@ -1,2 +1 @@ -bridge/bin -create/bin +bin
\ No newline at end of file diff --git a/tools/layoutlib/bridge/.classpath b/tools/layoutlib/bridge/.classpath index 5cfda29ae2e9..9fb000e65653 100644 --- a/tools/layoutlib/bridge/.classpath +++ b/tools/layoutlib/bridge/.classpath @@ -1,9 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> <classpathentry excluding="org/kxml2/io/" kind="src" path="src"/> - <classpathentry kind="src" path="tests"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> - <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/> <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/layoutlib_api/layoutlib_api-prebuilt.jar"/> <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/> <classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/> diff --git a/tools/layoutlib/bridge/Android.mk b/tools/layoutlib/bridge/Android.mk index 7e70f330b7d9..687a91feeb6f 100644 --- a/tools/layoutlib/bridge/Android.mk +++ b/tools/layoutlib/bridge/Android.mk @@ -33,3 +33,6 @@ LOCAL_MODULE := layoutlib include $(BUILD_HOST_JAVA_LIBRARY) +# Build all sub-directories +include $(call all-makefiles-under,$(LOCAL_PATH)) + diff --git a/tools/layoutlib/bridge/tests/.classpath b/tools/layoutlib/bridge/tests/.classpath new file mode 100644 index 000000000000..9cc2433dd7ed --- /dev/null +++ b/tools/layoutlib/bridge/tests/.classpath @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry combineaccessrules="false" kind="src" path="/layoutlib_bridge"/> + <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/> + <classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/> + <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/tools/layoutlib/bridge/tests/.project b/tools/layoutlib/bridge/tests/.project new file mode 100644 index 000000000000..2325eed16627 --- /dev/null +++ b/tools/layoutlib/bridge/tests/.project @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>layoutlib_bridge-tests</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/tools/layoutlib/bridge/tests/Android.mk b/tools/layoutlib/bridge/tests/Android.mk new file mode 100644 index 000000000000..e303638ae821 --- /dev/null +++ b/tools/layoutlib/bridge/tests/Android.mk @@ -0,0 +1,30 @@ +# Copyright (C) 2011 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. + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +# Only compile source java files in this lib. +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_MODULE := layoutlib-tests +LOCAL_MODULE_TAGS := optional + +LOCAL_JAVA_LIBRARIES := layoutlib kxml2-2.3.0 junit + +include $(BUILD_HOST_JAVA_LIBRARY) + +# Build all sub-directories +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/NinePatchTest.java b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/NinePatchTest.java deleted file mode 100644 index a3219e7a0ff6..000000000000 --- a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/NinePatchTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2008 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 com.android.layoutlib.bridge; - -import com.android.ninepatch.NinePatch; - -import java.net.URL; - -import junit.framework.TestCase; - -public class NinePatchTest extends TestCase { - - private NinePatch mPatch; - - @Override - protected void setUp() throws Exception { - URL url = this.getClass().getClassLoader().getResource( - "com/android/layoutlib/testdata/button.9.png"); - - mPatch = NinePatch.load(url, false /* convert */); - } - - public void test9PatchLoad() throws Exception { - assertNotNull(mPatch); - } - - public void test9PatchMinSize() { - int[] padding = new int[4]; - mPatch.getPadding(padding); - assertEquals(13, padding[0]); - assertEquals(3, padding[1]); - assertEquals(13, padding[2]); - assertEquals(4, padding[3]); - assertEquals(36, mPatch.getWidth()); - assertEquals(25, mPatch.getHeight()); - } -} diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/testdata/button.9.png b/tools/layoutlib/bridge/tests/com/android/layoutlib/testdata/button.9.png Binary files differdeleted file mode 100644 index 9d52f40d00fd..000000000000 --- a/tools/layoutlib/bridge/tests/com/android/layoutlib/testdata/button.9.png +++ /dev/null diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/AndroidGraphicsTests.java b/tools/layoutlib/bridge/tests/src/android/graphics/Matrix_DelegateTest.java index ba3c51a6c6ac..ec4edacca5eb 100644 --- a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/AndroidGraphicsTests.java +++ b/tools/layoutlib/bridge/tests/src/android/graphics/Matrix_DelegateTest.java @@ -14,17 +14,14 @@ * limitations under the License. */ -package com.android.layoutlib.bridge; - -import android.graphics.Matrix; -import android.text.TextPaint; +package android.graphics; import junit.framework.TestCase; /** * */ -public class AndroidGraphicsTests extends TestCase { +public class Matrix_DelegateTest extends TestCase { @Override protected void setUp() throws Exception { @@ -36,14 +33,17 @@ public class AndroidGraphicsTests extends TestCase { super.tearDown(); } - public void testMatrix() { + public void testIdentity() { Matrix m1 = new Matrix(); assertTrue(m1.isIdentity()); m1.setValues(new float[] { 1,0,0, 0,1,0, 0,0,1 }); assertTrue(m1.isIdentity()); + } + public void testCopyConstructor() { + Matrix m1 = new Matrix(); Matrix m2 = new Matrix(m1); float[] v1 = new float[9]; @@ -55,9 +55,4 @@ public class AndroidGraphicsTests extends TestCase { assertEquals(v1[i], v2[i]); } } - - public void textTextPaint() { - TextPaint p = new TextPaint(); - assertNotNull(p); - } } diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/TestDelegates.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java index d3218dbd5bd3..d3218dbd5bd3 100644 --- a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/TestDelegates.java +++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java index 3252fb497714..3252fb497714 100644 --- a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java +++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/testdata/layout1.xml b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/testdata/layout1.xml index b8fc9472ed83..b8fc9472ed83 100644 --- a/tools/layoutlib/bridge/tests/com/android/layoutlib/testdata/layout1.xml +++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/testdata/layout1.xml |