Add error reporting for Tethering.

Also make the usb interface configuration more robust so retries are possible.

Makes all Tethering errors recoverable - no harm letting them try again anyway.  Worst case
is they need to reboot.
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index c76aca1..a6668e7 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -364,7 +364,7 @@
     /**
      * Sets the persisted value for enabling/disabling Mobile data.
      *
-     * @param allowMobileData Whether the mobile data connection should be
+     * @param enabled Whether the mobile data connection should be
      *            used or not.
      * @hide
      */
@@ -418,22 +418,35 @@
     /**
      * {@hide}
      */
-    public boolean tether(String iface) {
+    public String[] getTetheringErroredIfaces() {
         try {
-            return mService.tether(iface);
+            return mService.getTetheringErroredIfaces();
         } catch (RemoteException e) {
-            return false;
+            return new String[0];
         }
     }
 
     /**
+     * @return error A TETHER_ERROR value indicating success or failure type
      * {@hide}
      */
-    public boolean untether(String iface) {
+    public int tether(String iface) {
+        try {
+            return mService.tether(iface);
+        } catch (RemoteException e) {
+            return TETHER_ERROR_SERVICE_UNAVAIL;
+        }
+    }
+
+    /**
+     * @return error A TETHER_ERROR value indicating success or failure type
+     * {@hide}
+     */
+    public int untether(String iface) {
         try {
             return mService.untether(iface);
         } catch (RemoteException e) {
-            return false;
+            return TETHER_ERROR_SERVICE_UNAVAIL;
         }
     }
 
@@ -469,4 +482,41 @@
             return new String[0];
         }
     }
+
+    /** {@hide} */
+    public static final int TETHER_ERROR_NO_ERROR           = 0;
+    /** {@hide} */
+    public static final int TETHER_ERROR_UNKNOWN_IFACE      = 1;
+    /** {@hide} */
+    public static final int TETHER_ERROR_SERVICE_UNAVAIL    = 2;
+    /** {@hide} */
+    public static final int TETHER_ERROR_UNSUPPORTED        = 3;
+    /** {@hide} */
+    public static final int TETHER_ERROR_UNAVAIL_IFACE      = 4;
+    /** {@hide} */
+    public static final int TETHER_ERROR_MASTER_ERROR       = 5;
+    /** {@hide} */
+    public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6;
+    /** {@hide} */
+    public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7;
+    /** {@hide} */
+    public static final int TETHER_ERROR_ENABLE_NAT_ERROR     = 8;
+    /** {@hide} */
+    public static final int TETHER_ERROR_DISABLE_NAT_ERROR    = 9;
+    /** {@hide} */
+    public static final int TETHER_ERROR_IFACE_CFG_ERROR      = 10;
+
+    /**
+     * @param iface The name of the interface we're interested in
+     * @return error The error code of the last error tethering or untethering the named
+     *               interface
+     * {@hide}
+     */
+    public int getLastTetherError(String iface) {
+        try {
+            return mService.getLastTetherError(iface);
+        } catch (RemoteException e) {
+            return TETHER_ERROR_SERVICE_UNAVAIL;
+        }
+   }
 }
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 2514693..b05c2ed 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -55,9 +55,11 @@
 
     void setMobileDataEnabled(boolean enabled);
 
-    boolean tether(String iface);
+    int tether(String iface);
 
-    boolean untether(String iface);
+    int untether(String iface);
+
+    int getLastTetherError(String iface);
 
     boolean isTetheringSupported();
 
@@ -65,6 +67,8 @@
 
     String[] getTetheredIfaces();
 
+    String[] getTetheringErroredIfaces();
+
     String[] getTetherableUsbRegexs();
 
     String[] getTetherableWifiRegexs();
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 67b6200..a1c45dc 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -1457,15 +1457,36 @@
     }
 
     // javadoc from interface
-    public boolean tether(String iface) {
+    public int tether(String iface) {
         enforceTetherChangePermission();
-        return isTetheringSupported() && mTethering.tether(iface);
+
+        if (isTetheringSupported()) {
+            return mTethering.tether(iface);
+        } else {
+            return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
+        }
     }
 
     // javadoc from interface
-    public boolean untether(String iface) {
+    public int untether(String iface) {
         enforceTetherChangePermission();
-        return isTetheringSupported() && mTethering.untether(iface);
+
+        if (isTetheringSupported()) {
+            return mTethering.untether(iface);
+        } else {
+            return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
+        }
+    }
+
+    // javadoc from interface
+    public int getLastTetherError(String iface) {
+        enforceTetherAccessPermission();
+
+        if (isTetheringSupported()) {
+            return mTethering.getLastTetherError(iface);
+        } else {
+            return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
+        }
     }
 
     // TODO - proper iface API for selection by property, inspection, etc
@@ -1499,6 +1520,11 @@
         return mTethering.getTetheredIfaces();
     }
 
+    public String[] getTetheringErroredIfaces() {
+        enforceTetherAccessPermission();
+        return mTethering.getErroredIfaces();
+    }
+
     // if ro.tether.denied = true we default to no tethering
     // gservices could set the secure setting to 1 though to enable it on a build where it
     // had previously been turned off.