1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.google.android.car.usb.aoap.host;
17
18import android.app.Activity;
19import android.content.BroadcastReceiver;
20import android.content.Context;
21import android.content.Intent;
22import android.content.IntentFilter;
23import android.hardware.usb.UsbDevice;
24import android.hardware.usb.UsbDeviceConnection;
25import android.hardware.usb.UsbManager;
26import android.os.Bundle;
27import android.text.TextUtils;
28import android.text.method.ScrollingMovementMethod;
29import android.util.Log;
30import android.widget.TextView;
31
32import java.util.ArrayList;
33import java.util.List;
34
35/**
36 * Host activity for AOAP test app.
37 */
38public class UsbAoapHostActivity extends Activity
39        implements SpeedMeasurementController.SpeedMeasurementControllerCallback {
40
41    private static final String TAG = UsbAoapHostActivity.class.getSimpleName();
42
43    private final List<String> mLogMessages = new ArrayList<>();
44
45    private UsbManager mUsbManager;
46    private UsbStateReceiver mReceiver;
47    private UsbDevice mUsbDevice;
48    private UsbDeviceConnection mUsbConnection;
49    private TextView mLog;
50
51    @Override
52    protected void onCreate(Bundle savedInstanceState) {
53        super.onCreate(savedInstanceState);
54
55        setContentView(R.layout.host);
56        mLog = (TextView) findViewById(R.id.usb_log);
57        mLog.setMovementMethod(new ScrollingMovementMethod());
58
59
60        mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
61        IntentFilter filter = new IntentFilter();
62        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
63        mReceiver = new UsbStateReceiver();
64        registerReceiver(mReceiver, filter);
65
66        Intent intent = getIntent();
67        if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
68            mUsbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
69            mUsbConnection = mUsbManager.openDevice(mUsbDevice);
70        } else {
71            finish();
72        }
73    }
74
75    @Override
76    protected void onResume() {
77        super.onResume();
78        SpeedMeasurementController testController =
79                new SpeedMeasurementController(this, mUsbDevice, mUsbConnection, this);
80        testController.start();
81    }
82
83    @Override
84    protected void onDestroy() {
85        super.onDestroy();
86        unregisterReceiver(mReceiver);
87        if (mUsbConnection != null) {
88            mUsbConnection.close();
89        }
90    }
91
92    private String getTestModeString(int mode) {
93        if (mode == SpeedMeasurementController.TEST_MODE_SYNC) {
94            return "Sync";
95        } else if (mode == SpeedMeasurementController.TEST_MODE_ASYNC) {
96            return "Async";
97        } else {
98            return "Unknown mode: " + mode;
99        }
100    }
101
102    private synchronized void addLog(String message) {
103        mLogMessages.add(message);
104        runOnUiThread(new Runnable() {
105                @Override
106                public void run() {
107                    mLog.setText(TextUtils.join("\n", mLogMessages));
108                }
109            });
110    }
111
112    @Override
113    public void testStarted(int mode, int bufferSize) {
114        addLog("Starting " + getTestModeString(mode) + " mode test with buffer size " + bufferSize
115                + " bytes");
116    }
117
118    @Override
119    public void testFinished(int mode, int bufferSize) {
120        addLog("Completed " + getTestModeString(mode) + " mode test with buffer size " + bufferSize
121                + " bytes");
122    }
123
124    @Override
125    public void testResult(int mode, String update) {
126        Log.i(TAG, "Test result " + mode + " update: " + update);
127        addLog("Test result for " + getTestModeString(mode) + " mode: " + update);
128    }
129
130    @Override
131    public void testSuiteFinished() {
132        Log.i(TAG, "All tests finished");
133        addLog("All tests are completed");
134    }
135
136    private static boolean isDevicesMatching(UsbDevice l, UsbDevice r) {
137        if (l.getVendorId() == r.getVendorId() && l.getProductId() == r.getProductId()
138                && TextUtils.equals(l.getSerialNumber(), r.getSerialNumber())) {
139            return true;
140        }
141        return false;
142    }
143
144    private class UsbStateReceiver extends BroadcastReceiver {
145        @Override
146        public void onReceive(Context context, Intent intent) {
147            if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(intent.getAction())) {
148                UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
149                if (isDevicesMatching(mUsbDevice, device)) {
150                    finish();
151                }
152            }
153        }
154    }
155}
156