Merge "Add USB tethering to PMC app"
diff --git a/PMC/AndroidManifest.xml b/PMC/AndroidManifest.xml
index 127e11d..d8485b9 100644
--- a/PMC/AndroidManifest.xml
+++ b/PMC/AndroidManifest.xml
@@ -1,4 +1,20 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2017 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.
+-->
+
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.pmc"
     android:versionCode="3"
@@ -19,6 +35,12 @@
     <uses-permission android:name="android.permission.BLUETOOTH" />
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
+    <uses-permission android:name="android.permission.MANAGE_USB" />
+    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+    <uses-permission android:name="android.permission.TETHER_PRIVILEGED" />
 
     <application
         android:allowBackup="true"
diff --git a/PMC/res/layout/activity_linear.xml b/PMC/res/layout/activity_linear.xml
index 6461b4d..0df847b 100644
--- a/PMC/res/layout/activity_linear.xml
+++ b/PMC/res/layout/activity_linear.xml
@@ -1,4 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2017 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.
+-->
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
@@ -66,6 +81,12 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:text="@string/iperf_client" />
+
+        <RadioButton
+            android:id="@+id/rb_usb_tethering"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/usb_tethering" />
     </RadioGroup>
 
     <Button
diff --git a/PMC/res/values/strings.xml b/PMC/res/values/strings.xml
index 2d37c06..1114856 100644
--- a/PMC/res/values/strings.xml
+++ b/PMC/res/values/strings.xml
@@ -1,4 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2017 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.
+-->
 <resources>
 
     <string name="app_name">PMC</string>
@@ -23,5 +38,6 @@
     <string name="interval">Download/Scan Interval (seconds)</string>
     <string name="iperf_bandwidth">Iperf Bandwidth</string>
     <string name="iperf_logfile">Iperf Logfile</string>
+    <string name="usb_tethering">USB Tethering</string>
 
 </resources>
diff --git a/PMC/src/com/android/pmc/PMCMainActivity.java b/PMC/src/com/android/pmc/PMCMainActivity.java
index d134bdc..8f59ef2 100644
--- a/PMC/src/com/android/pmc/PMCMainActivity.java
+++ b/PMC/src/com/android/pmc/PMCMainActivity.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.net.ConnectivityManager;
 import android.net.wifi.WifiScanner;
 import android.net.wifi.WifiScanner.ChannelSpec;
 import android.net.wifi.WifiScanner.ScanSettings;
@@ -68,6 +69,7 @@
     private WifiGScanReceiver mGScanR = null;
     private WifiDownloadReceiver mDR = null;
     private IperfClient mIperfClient = null;
+    private boolean mTethered = false;
     private RadioGroup mRadioGroup;
     private Button mBtnStart;
     private Button mBtnStop;
@@ -77,13 +79,23 @@
     private A2dpReceiver mA2dpReceiver;
     private AlarmManager mAlarmManager;
     private PowerManager.WakeLock mWakeLock;
+    private ConnectivityManager mConnManager;
+    private int mProvisionCheckSleep = 1250;
 
+    class OnStartTetheringCallback extends ConnectivityManager.OnStartTetheringCallback {
+        @Override
+        public void onTetheringStarted() {
+            mTethered = true;
+        }
+    }
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         //Initiate wifi service manger
         mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
+        mConnManager = (ConnectivityManager)
+                this.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
         mPIGScan = PendingIntent.getBroadcast(this, 0, new Intent(sGScanAction), 0);
         mPIDownload = PendingIntent.getBroadcast(this, 0, new Intent(sDownloadAction), 0);
         mPIConnScan = PendingIntent.getBroadcast(this, 0, new Intent(sConnScanAction), 0);
@@ -145,6 +157,9 @@
                     case R.id.rb_iperf_client:
                         startIperfClient();
                         break;
+                    case R.id.rb_usb_tethering:
+                        startUSBTethering();
+                        break;
                     default:
                         return;
                 }
@@ -158,6 +173,7 @@
                 stopDownloadFile();
                 stopGScan();
                 stopIperfClient();
+                stopUSBTethering();
                 mBtnStart.setEnabled(true);
             }
         });
@@ -286,6 +302,32 @@
         }
     }
 
+    private void startUSBTethering() {
+        OnStartTetheringCallback tetherCallback = new OnStartTetheringCallback();
+        mConnManager.startTethering(ConnectivityManager.TETHERING_USB, true, tetherCallback);
+        // sleep until provisioning check for tethering is done
+        try {
+            Thread.sleep(mProvisionCheckSleep);
+        } catch (InterruptedException e) {
+            Log.d(TAG, "Sleep exception after enabling USB tethering");
+        }
+        if (mTethered) {
+            mBtnStart.setEnabled(false);
+            mRadioGroup.setFocusable(false);
+            mTextView.setText("Started usb tethering");
+        }
+    }
+
+    private void stopUSBTethering() {
+        if (mTethered) {
+            mConnManager.stopTethering(ConnectivityManager.TETHERING_USB);
+            mTethered = false;
+            mBtnStart.setEnabled(true);
+            mRadioGroup.setFocusable(true);
+            mTextView.setText("Stopped usb tethering");
+        }
+    }
+
     private void turnScreenOn(Context context) {
         if (mWakeLock == null) {
             PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
@@ -395,6 +437,10 @@
                             startIperfClient();
                         } else if (actionstring.equalsIgnoreCase("StopIperfClient")) {
                             stopIperfClient();
+                        } else if (actionstring.equalsIgnoreCase("StartUSBTethering")) {
+                            startUSBTethering();
+                        } else if (actionstring.equalsIgnoreCase("StopUSBTethering")) {
+                            stopUSBTethering();
                         } else if (actionstring.equalsIgnoreCase("TurnScreenOn")) {
                             turnScreenOn(context);
                         } else if (actionstring.equalsIgnoreCase("TurnScreenOff")) {