146d0adf8256a42416584765625852b6e48497c90Mike Lockwood/*
246d0adf8256a42416584765625852b6e48497c90Mike Lockwood * Copyright (C) 2011 The Android Open Source Project
346d0adf8256a42416584765625852b6e48497c90Mike Lockwood *
446d0adf8256a42416584765625852b6e48497c90Mike Lockwood * Licensed under the Apache License, Version 2.0 (the "License");
546d0adf8256a42416584765625852b6e48497c90Mike Lockwood * you may not use this file except in compliance with the License.
646d0adf8256a42416584765625852b6e48497c90Mike Lockwood * You may obtain a copy of the License at
746d0adf8256a42416584765625852b6e48497c90Mike Lockwood *
846d0adf8256a42416584765625852b6e48497c90Mike Lockwood *      http://www.apache.org/licenses/LICENSE-2.0
946d0adf8256a42416584765625852b6e48497c90Mike Lockwood *
1046d0adf8256a42416584765625852b6e48497c90Mike Lockwood * Unless required by applicable law or agreed to in writing, software
1146d0adf8256a42416584765625852b6e48497c90Mike Lockwood * distributed under the License is distributed on an "AS IS" BASIS,
1246d0adf8256a42416584765625852b6e48497c90Mike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1346d0adf8256a42416584765625852b6e48497c90Mike Lockwood * See the License for the specific language governing permissions an
1446d0adf8256a42416584765625852b6e48497c90Mike Lockwood * limitations under the License.
1546d0adf8256a42416584765625852b6e48497c90Mike Lockwood */
1646d0adf8256a42416584765625852b6e48497c90Mike Lockwood
1746d0adf8256a42416584765625852b6e48497c90Mike Lockwoodpackage com.android.server.usb;
1846d0adf8256a42416584765625852b6e48497c90Mike Lockwood
19541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwoodimport android.app.Notification;
20541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwoodimport android.app.NotificationManager;
21fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkeyimport android.app.PendingIntent;
228338ed00ae44635d099b530b3360e6d1f7041827Jason Monkimport android.content.BroadcastReceiver;
23541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwoodimport android.content.ComponentName;
2446d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.content.ContentResolver;
2546d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.content.Context;
2646d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.content.Intent;
278338ed00ae44635d099b530b3360e6d1f7041827Jason Monkimport android.content.IntentFilter;
2846d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.content.pm.PackageManager;
29541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwoodimport android.content.res.Resources;
30541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwoodimport android.database.ContentObserver;
3146d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.hardware.usb.UsbAccessory;
3246d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.hardware.usb.UsbManager;
338338ed00ae44635d099b530b3360e6d1f7041827Jason Monkimport android.hardware.usb.UsbPort;
348338ed00ae44635d099b530b3360e6d1f7041827Jason Monkimport android.hardware.usb.UsbPortStatus;
3502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwoodimport android.os.FileUtils;
3646d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.os.Handler;
3702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwoodimport android.os.Looper;
3846d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.os.Message;
3946d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.os.ParcelFileDescriptor;
40dab2072365565b4892be7910b0cdb870e83689f6RoboErikimport android.os.SystemClock;
41541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwoodimport android.os.SystemProperties;
4246d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.os.UEventObserver;
43fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkeyimport android.os.UserHandle;
441848d31c2cbb5404be383ad44049e58e36b258baEmily Bernierimport android.os.UserManager;
45fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkeyimport android.os.storage.StorageManager;
46fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkeyimport android.os.storage.StorageVolume;
4746d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.provider.Settings;
48afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondoimport android.util.Pair;
4946d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.util.Slog;
5046d0adf8256a42416584765625852b6e48497c90Mike Lockwood
518b2c3a14603d163d7564e6f60286995079687690Jeff Sharkeyimport com.android.internal.annotations.GuardedBy;
529ebf2a5683db3dfd956f68b80f3f0a10b9705891Philip P. Moltmannimport com.android.internal.os.SomeArgs;
532dbccc1926ea2d3e27c5cfd2d61d2b3d5ed787c0Jeff Brownimport com.android.internal.util.IndentingPrintWriter;
548d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackbornimport com.android.server.FgThread;
558b2c3a14603d163d7564e6f60286995079687690Jeff Sharkey
5646d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport java.io.File;
5746d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport java.io.FileNotFoundException;
5802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwoodimport java.io.IOException;
59fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkeyimport java.util.HashMap;
60afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondoimport java.util.LinkedList;
6146d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport java.util.List;
62fea17de7aaa5729d3111102b2734b158403d2780Jeff Sharkeyimport java.util.Locale;
63afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondoimport java.util.Map;
649d5a4be05b6d51ebb768e5fbcfa27ed9a39269b3Mike Lockwoodimport java.util.Scanner;
6548b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsudaimport java.util.Set;
6646d0adf8256a42416584765625852b6e48497c90Mike Lockwood
6746d0adf8256a42416584765625852b6e48497c90Mike Lockwood/**
6846d0adf8256a42416584765625852b6e48497c90Mike Lockwood * UsbDeviceManager manages USB state in device mode.
6946d0adf8256a42416584765625852b6e48497c90Mike Lockwood */
7046d0adf8256a42416584765625852b6e48497c90Mike Lockwoodpublic class UsbDeviceManager {
7102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood
72460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown    private static final String TAG = "UsbDeviceManager";
73fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood    private static final boolean DEBUG = false;
7446d0adf8256a42416584765625852b6e48497c90Mike Lockwood
75460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown    /**
76460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown     * The persistent property which stores whether adb is enabled or not.
77460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown     * May also contain vendor-specific default functions for testing purposes.
78460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown     */
79460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown    private static final String USB_PERSISTENT_CONFIG_PROPERTY = "persist.sys.usb.config";
80460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown
81460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown    /**
82460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown     * The non-persistent property which stores the current USB settings.
83460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown     */
84460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown    private static final String USB_CONFIG_PROPERTY = "sys.usb.config";
85460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown
86460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown    /**
87460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown     * The non-persistent property which stores the current USB actual state.
88460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown     */
89460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown    private static final String USB_STATE_PROPERTY = "sys.usb.state";
90460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown
9102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood    private static final String USB_STATE_MATCH =
9202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            "DEVPATH=/devices/virtual/android_usb/android0";
9302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood    private static final String ACCESSORY_START_MATCH =
9402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            "DEVPATH=/devices/virtual/misc/usb_accessory";
9502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood    private static final String FUNCTIONS_PATH =
9602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            "/sys/class/android_usb/android0/functions";
9702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood    private static final String STATE_PATH =
9802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            "/sys/class/android_usb/android0/state";
99629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood    private static final String RNDIS_ETH_ADDR_PATH =
100629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood            "/sys/class/android_usb/android0/f_rndis/ethaddr";
1019d5a4be05b6d51ebb768e5fbcfa27ed9a39269b3Mike Lockwood    private static final String AUDIO_SOURCE_PCM_PATH =
1029d5a4be05b6d51ebb768e5fbcfa27ed9a39269b3Mike Lockwood            "/sys/class/android_usb/android0/f_audio_source/pcm";
1032a57bc7fd602853dc1a22dcee1ff50f92cc29060Mike Lockwood    private static final String MIDI_ALSA_PATH =
1042a57bc7fd602853dc1a22dcee1ff50f92cc29060Mike Lockwood            "/sys/class/android_usb/android0/f_midi/alsa";
10546d0adf8256a42416584765625852b6e48497c90Mike Lockwood
10646d0adf8256a42416584765625852b6e48497c90Mike Lockwood    private static final int MSG_UPDATE_STATE = 0;
10702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood    private static final int MSG_ENABLE_ADB = 1;
108166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood    private static final int MSG_SET_CURRENT_FUNCTIONS = 2;
109f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood    private static final int MSG_SYSTEM_READY = 3;
110d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood    private static final int MSG_BOOT_COMPLETED = 4;
11127bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey    private static final int MSG_USER_SWITCHED = 5;
112674019065bceb4150190bfb1aa63cda9de0a8560Nick Kralevich    private static final int MSG_SET_USB_DATA_UNLOCKED = 6;
113460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown    private static final int MSG_UPDATE_USER_RESTRICTIONS = 7;
1148338ed00ae44635d099b530b3360e6d1f7041827Jason Monk    private static final int MSG_UPDATE_HOST_STATE = 8;
11546d0adf8256a42416584765625852b6e48497c90Mike Lockwood
116166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood    private static final int AUDIO_MODE_SOURCE = 1;
117166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood
11846d0adf8256a42416584765625852b6e48497c90Mike Lockwood    // Delay for debouncing USB disconnects.
11946d0adf8256a42416584765625852b6e48497c90Mike Lockwood    // We often get rapid connect/disconnect events when enabling USB functions,
12046d0adf8256a42416584765625852b6e48497c90Mike Lockwood    // which need debouncing.
12146d0adf8256a42416584765625852b6e48497c90Mike Lockwood    private static final int UPDATE_DELAY = 1000;
12246d0adf8256a42416584765625852b6e48497c90Mike Lockwood
123c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood    // Time we received a request to enter USB accessory mode
124c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood    private long mAccessoryModeRequestTime = 0;
125c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood
126c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood    // Timeout for entering USB request mode.
127c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood    // Request is cancelled if host does not configure device within 10 seconds.
128c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood    private static final int ACCESSORY_REQUEST_TIMEOUT = 10 * 1000;
129c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood
1302fedc4df5127d1a2eaf178e835d9f5398ce8f879Nick Kralevich    private static final String BOOT_MODE_PROPERTY = "ro.bootmode";
1312fedc4df5127d1a2eaf178e835d9f5398ce8f879Nick Kralevich
13202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood    private UsbHandler mHandler;
133d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood    private boolean mBootCompleted;
13446d0adf8256a42416584765625852b6e48497c90Mike Lockwood
135fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    private final Object mLock = new Object();
136fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey
13746d0adf8256a42416584765625852b6e48497c90Mike Lockwood    private final Context mContext;
13802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood    private final ContentResolver mContentResolver;
1398b2c3a14603d163d7564e6f60286995079687690Jeff Sharkey    @GuardedBy("mLock")
140fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    private UsbSettingsManager mCurrentSettings;
141541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood    private NotificationManager mNotificationManager;
14246d0adf8256a42416584765625852b6e48497c90Mike Lockwood    private final boolean mHasUsbAccessory;
1435787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood    private boolean mUseUsbNotification;
144541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood    private boolean mAdbEnabled;
1459d5a4be05b6d51ebb768e5fbcfa27ed9a39269b3Mike Lockwood    private boolean mAudioSourceEnabled;
1462a57bc7fd602853dc1a22dcee1ff50f92cc29060Mike Lockwood    private boolean mMidiEnabled;
147b7ce094c9e546c4a802bd8ce3a43592979a5e3dfMike Lockwood    private int mMidiCard;
148b7ce094c9e546c4a802bd8ce3a43592979a5e3dfMike Lockwood    private int mMidiDevice;
149afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo    private Map<String, List<Pair<String, String>>> mOemModeMap;
150166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood    private String[] mAccessoryStrings;
1514e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby    private UsbDebuggingManager mDebuggingManager;
1522e3434149e00f921ca3555ae55cba04d3c64eeb1Mike Lockwood    private final UsbAlsaManager mUsbAlsaManager;
15348b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda    private Intent mBroadcastedIntent;
154541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood
155541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood    private class AdbSettingsObserver extends ContentObserver {
156541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood        public AdbSettingsObserver() {
157541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood            super(null);
158541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood        }
159541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood        @Override
160541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood        public void onChange(boolean selfChange) {
161bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown            boolean enable = (Settings.Global.getInt(mContentResolver,
162bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown                    Settings.Global.ADB_ENABLED, 0) > 0);
16302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            mHandler.sendMessage(MSG_ENABLE_ADB, enable);
164541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood        }
165541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood    }
166541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood
16746d0adf8256a42416584765625852b6e48497c90Mike Lockwood    /*
16846d0adf8256a42416584765625852b6e48497c90Mike Lockwood     * Listens for uevent messages from the kernel to monitor the USB state
16946d0adf8256a42416584765625852b6e48497c90Mike Lockwood     */
17046d0adf8256a42416584765625852b6e48497c90Mike Lockwood    private final UEventObserver mUEventObserver = new UEventObserver() {
17146d0adf8256a42416584765625852b6e48497c90Mike Lockwood        @Override
17246d0adf8256a42416584765625852b6e48497c90Mike Lockwood        public void onUEvent(UEventObserver.UEvent event) {
173fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood            if (DEBUG) Slog.v(TAG, "USB UEVENT: " + event.toString());
17446d0adf8256a42416584765625852b6e48497c90Mike Lockwood
17502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            String state = event.get("USB_STATE");
17602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            String accessory = event.get("ACCESSORY");
17702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            if (state != null) {
17802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                mHandler.updateState(state);
17902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            } else if ("START".equals(accessory)) {
180fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood                if (DEBUG) Slog.d(TAG, "got accessory start");
181205a3ea0e2c49bc4d0ed534469f3a6920c14c4feMike Lockwood                startAccessoryMode();
18246d0adf8256a42416584765625852b6e48497c90Mike Lockwood            }
18346d0adf8256a42416584765625852b6e48497c90Mike Lockwood        }
18446d0adf8256a42416584765625852b6e48497c90Mike Lockwood    };
18546d0adf8256a42416584765625852b6e48497c90Mike Lockwood
1868338ed00ae44635d099b530b3360e6d1f7041827Jason Monk    private final BroadcastReceiver mHostReceiver = new BroadcastReceiver() {
1878338ed00ae44635d099b530b3360e6d1f7041827Jason Monk        @Override
1888338ed00ae44635d099b530b3360e6d1f7041827Jason Monk        public void onReceive(Context context, Intent intent) {
1898338ed00ae44635d099b530b3360e6d1f7041827Jason Monk            UsbPort port = intent.getParcelableExtra(UsbManager.EXTRA_PORT);
1908338ed00ae44635d099b530b3360e6d1f7041827Jason Monk            UsbPortStatus status = intent.getParcelableExtra(UsbManager.EXTRA_PORT_STATUS);
1918338ed00ae44635d099b530b3360e6d1f7041827Jason Monk            mHandler.updateHostState(port, status);
1928338ed00ae44635d099b530b3360e6d1f7041827Jason Monk        }
1938338ed00ae44635d099b530b3360e6d1f7041827Jason Monk    };
1948338ed00ae44635d099b530b3360e6d1f7041827Jason Monk
1952e3434149e00f921ca3555ae55cba04d3c64eeb1Mike Lockwood    public UsbDeviceManager(Context context, UsbAlsaManager alsaManager) {
19646d0adf8256a42416584765625852b6e48497c90Mike Lockwood        mContext = context;
1972e3434149e00f921ca3555ae55cba04d3c64eeb1Mike Lockwood        mUsbAlsaManager = alsaManager;
198541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood        mContentResolver = context.getContentResolver();
19946d0adf8256a42416584765625852b6e48497c90Mike Lockwood        PackageManager pm = mContext.getPackageManager();
20046d0adf8256a42416584765625852b6e48497c90Mike Lockwood        mHasUsbAccessory = pm.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY);
201629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood        initRndisAddress();
20246d0adf8256a42416584765625852b6e48497c90Mike Lockwood
203afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo        readOemUsbOverrideConfig();
204afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo
2058d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        mHandler = new UsbHandler(FgThread.get().getLooper());
206d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood
207d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood        if (nativeIsStartRequested()) {
208d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood            if (DEBUG) Slog.d(TAG, "accessory attached at boot");
209205a3ea0e2c49bc4d0ed534469f3a6920c14c4feMike Lockwood            startAccessoryMode();
210d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood        }
2114e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby
21278a9687fc2eab03b9d764cd27eaa1d56c66960beBenoit Goby        boolean secureAdbEnabled = SystemProperties.getBoolean("ro.adb.secure", false);
21378a9687fc2eab03b9d764cd27eaa1d56c66960beBenoit Goby        boolean dataEncrypted = "1".equals(SystemProperties.get("vold.decrypt"));
21478a9687fc2eab03b9d764cd27eaa1d56c66960beBenoit Goby        if (secureAdbEnabled && !dataEncrypted) {
2154e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby            mDebuggingManager = new UsbDebuggingManager(context);
2164e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby        }
2178338ed00ae44635d099b530b3360e6d1f7041827Jason Monk        mContext.registerReceiver(mHostReceiver,
2188338ed00ae44635d099b530b3360e6d1f7041827Jason Monk                new IntentFilter(UsbManager.ACTION_USB_PORT_CHANGED));
21902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood    }
22002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood
221fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    private UsbSettingsManager getCurrentSettings() {
222fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        synchronized (mLock) {
223fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey            return mCurrentSettings;
224fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        }
225fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey    }
226fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey
22702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood    public void systemReady() {
228d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood        if (DEBUG) Slog.d(TAG, "systemReady");
22902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood
23002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        mNotificationManager = (NotificationManager)
23102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                mContext.getSystemService(Context.NOTIFICATION_SERVICE);
23246d0adf8256a42416584765625852b6e48497c90Mike Lockwood
2335787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood        // We do not show the USB notification if the primary volume supports mass storage.
2345787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood        // The legacy mass storage UI will be used instead.
2355787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood        boolean massStorageSupported = false;
236b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey        final StorageManager storageManager = StorageManager.from(mContext);
237b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey        final StorageVolume primary = storageManager.getPrimaryVolume();
238b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey        massStorageSupported = primary != null && primary.allowMassStorage();
239e753361508a51ecea4bc2c84ffba68fd5a8cdd4bGus Prevas        mUseUsbNotification = !massStorageSupported && mContext.getResources().getBoolean(
240e753361508a51ecea4bc2c84ffba68fd5a8cdd4bGus Prevas                com.android.internal.R.bool.config_usbChargingMessage);
2415787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood
24202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        // make sure the ADB_ENABLED setting value matches the current state
243b66252fb4288ae7e3fa6f1214455e46b9a2e56b2Geoffrey Borggaard        try {
244b66252fb4288ae7e3fa6f1214455e46b9a2e56b2Geoffrey Borggaard            Settings.Global.putInt(mContentResolver,
245b66252fb4288ae7e3fa6f1214455e46b9a2e56b2Geoffrey Borggaard                    Settings.Global.ADB_ENABLED, mAdbEnabled ? 1 : 0);
246b66252fb4288ae7e3fa6f1214455e46b9a2e56b2Geoffrey Borggaard        } catch (SecurityException e) {
247b66252fb4288ae7e3fa6f1214455e46b9a2e56b2Geoffrey Borggaard            // If UserManager.DISALLOW_DEBUGGING_FEATURES is on, that this setting can't be changed.
248b66252fb4288ae7e3fa6f1214455e46b9a2e56b2Geoffrey Borggaard            Slog.d(TAG, "ADB_ENABLED is restricted.");
249b66252fb4288ae7e3fa6f1214455e46b9a2e56b2Geoffrey Borggaard        }
25002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        mHandler.sendEmptyMessage(MSG_SYSTEM_READY);
25102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood    }
252541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood
253460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown    public void bootCompleted() {
254460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown        if (DEBUG) Slog.d(TAG, "boot completed");
255460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown        mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED);
256460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown    }
257460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown
258460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown    public void setCurrentUser(int userId, UsbSettingsManager settings) {
259460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown        synchronized (mLock) {
260460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            mCurrentSettings = settings;
261460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            mHandler.obtainMessage(MSG_USER_SWITCHED, userId, 0).sendToTarget();
262460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown        }
263460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown    }
264460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown
265460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown    public void updateUserRestrictions() {
266460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown        mHandler.sendEmptyMessage(MSG_UPDATE_USER_RESTRICTIONS);
267460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown    }
268460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown
269166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood    private void startAccessoryMode() {
270c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood        if (!mHasUsbAccessory) return;
271c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood
272166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood        mAccessoryStrings = nativeGetAccessoryStrings();
273166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood        boolean enableAudio = (nativeGetAudioMode() == AUDIO_MODE_SOURCE);
274166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood        // don't start accessory mode if our mandatory strings have not been set
275166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood        boolean enableAccessory = (mAccessoryStrings != null &&
276166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood                        mAccessoryStrings[UsbAccessory.MANUFACTURER_STRING] != null &&
277166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood                        mAccessoryStrings[UsbAccessory.MODEL_STRING] != null);
278166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood        String functions = null;
279166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood
280166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood        if (enableAccessory && enableAudio) {
281166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood            functions = UsbManager.USB_FUNCTION_ACCESSORY + ","
282166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood                    + UsbManager.USB_FUNCTION_AUDIO_SOURCE;
283166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood        } else if (enableAccessory) {
284166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood            functions = UsbManager.USB_FUNCTION_ACCESSORY;
285166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood        } else if (enableAudio) {
286166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood            functions = UsbManager.USB_FUNCTION_AUDIO_SOURCE;
287166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood        }
288166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood
289166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood        if (functions != null) {
290c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood            mAccessoryModeRequestTime = SystemClock.elapsedRealtime();
291fcf10f7c12cb3107bdfedce6f76a8c866d154f3cNick Kralevich            setCurrentFunctions(functions);
292166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood        }
293166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood    }
294166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood
295629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood    private static void initRndisAddress() {
296629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood        // configure RNDIS ethernet address based on our serial number using the same algorithm
297629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood        // we had been previously using in kernel board files
298629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood        final int ETH_ALEN = 6;
299629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood        int address[] = new int[ETH_ALEN];
300629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood        // first byte is 0x02 to signify a locally administered address
301629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood        address[0] = 0x02;
302629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood
303629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood        String serial = SystemProperties.get("ro.serialno", "1234567890ABCDEF");
304629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood        int serialLength = serial.length();
305629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood        // XOR the USB serial across the remaining 5 bytes
306629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood        for (int i = 0; i < serialLength; i++) {
307629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood            address[i % (ETH_ALEN - 1) + 1] ^= (int)serial.charAt(i);
308629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood        }
309fea17de7aaa5729d3111102b2734b158403d2780Jeff Sharkey        String addrString = String.format(Locale.US, "%02X:%02X:%02X:%02X:%02X:%02X",
310629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood            address[0], address[1], address[2], address[3], address[4], address[5]);
311629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood        try {
312629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood            FileUtils.stringToFile(RNDIS_ETH_ADDR_PATH, addrString);
313629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood        } catch (IOException e) {
314629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood           Slog.e(TAG, "failed to write to " + RNDIS_ETH_ADDR_PATH);
315629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood        }
316629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood    }
317629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood
31802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood    private final class UsbHandler extends Handler {
31902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood
32002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        // current USB state
32102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        private boolean mConnected;
3228338ed00ae44635d099b530b3360e6d1f7041827Jason Monk        private boolean mHostConnected;
3230be6800b0feba50fa2c1be7852ee2eb02c38afc0Vincent Palatin        private boolean mSourcePower;
3249ebf2a5683db3dfd956f68b80f3f0a10b9705891Philip P. Moltmann        private boolean mSinkPower;
32502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        private boolean mConfigured;
326674019065bceb4150190bfb1aa63cda9de0a8560Nick Kralevich        private boolean mUsbDataUnlocked;
32702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        private String mCurrentFunctions;
328460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown        private boolean mCurrentFunctionsApplied;
32902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        private UsbAccessory mCurrentAccessory;
330d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood        private int mUsbNotificationId;
331d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood        private boolean mAdbNotificationShown;
33227bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey        private int mCurrentUser = UserHandle.USER_NULL;
333d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood
3343fd13eb6322e09f1ffe5476e28d55732da391151Mike Lockwood        public UsbHandler(Looper looper) {
3353fd13eb6322e09f1ffe5476e28d55732da391151Mike Lockwood            super(looper);
33602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            try {
337460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                // Restore default functions.
338460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                mCurrentFunctions = SystemProperties.get(USB_CONFIG_PROPERTY,
339460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                        UsbManager.USB_FUNCTION_NONE);
3401a008c1ca04871386830f511ee4b47299b92b01fNick Kralevich                if (UsbManager.USB_FUNCTION_NONE.equals(mCurrentFunctions)) {
3411a008c1ca04871386830f511ee4b47299b92b01fNick Kralevich                    mCurrentFunctions = UsbManager.USB_FUNCTION_MTP;
3421a008c1ca04871386830f511ee4b47299b92b01fNick Kralevich                }
343460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                mCurrentFunctionsApplied = mCurrentFunctions.equals(
344460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                        SystemProperties.get(USB_STATE_PROPERTY));
345460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                mAdbEnabled = UsbManager.containsFunction(getDefaultFunctions(),
346fcf10f7c12cb3107bdfedce6f76a8c866d154f3cNick Kralevich                        UsbManager.USB_FUNCTION_ADB);
347460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                setEnabledFunctions(null, false);
348de296f64483713fdf164f3e8bf41dc12d1cff59eMike Lockwood
34902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim();
35002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                updateState(state);
35102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood
35202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                // register observer to listen for settings changes
35302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                mContentResolver.registerContentObserver(
354bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown                        Settings.Global.getUriFor(Settings.Global.ADB_ENABLED),
35502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                                false, new AdbSettingsObserver());
35602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood
35702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                // Watch for USB configuration changes
35802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                mUEventObserver.startObserving(USB_STATE_MATCH);
35902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                mUEventObserver.startObserving(ACCESSORY_START_MATCH);
36002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            } catch (Exception e) {
36102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                Slog.e(TAG, "Error initializing UsbHandler", e);
36202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            }
36346d0adf8256a42416584765625852b6e48497c90Mike Lockwood        }
36402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood
36502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        public void sendMessage(int what, boolean arg) {
36602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            removeMessages(what);
36702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            Message m = Message.obtain(this, what);
36802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            m.arg1 = (arg ? 1 : 0);
36902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            sendMessage(m);
37046d0adf8256a42416584765625852b6e48497c90Mike Lockwood        }
37146d0adf8256a42416584765625852b6e48497c90Mike Lockwood
37202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        public void sendMessage(int what, Object arg) {
37302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            removeMessages(what);
37402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            Message m = Message.obtain(this, what);
37502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            m.obj = arg;
37602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            sendMessage(m);
37702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        }
37802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood
37902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        public void updateState(String state) {
38002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            int connected, configured;
38102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood
38202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            if ("DISCONNECTED".equals(state)) {
38302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                connected = 0;
38402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                configured = 0;
38502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            } else if ("CONNECTED".equals(state)) {
38602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                connected = 1;
38702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                configured = 0;
38802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            } else if ("CONFIGURED".equals(state)) {
38902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                connected = 1;
39002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                configured = 1;
39102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            } else {
39202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                Slog.e(TAG, "unknown state " + state);
39302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                return;
39402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            }
39502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            removeMessages(MSG_UPDATE_STATE);
39602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            Message msg = Message.obtain(this, MSG_UPDATE_STATE);
39702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            msg.arg1 = connected;
39802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            msg.arg2 = configured;
39902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            // debounce disconnects to avoid problems bringing up USB tethering
40002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            sendMessageDelayed(msg, (connected == 0) ? UPDATE_DELAY : 0);
40102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        }
40202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood
4038338ed00ae44635d099b530b3360e6d1f7041827Jason Monk        public void updateHostState(UsbPort port, UsbPortStatus status) {
4048338ed00ae44635d099b530b3360e6d1f7041827Jason Monk            boolean hostConnected = status.getCurrentDataRole() == UsbPort.DATA_ROLE_HOST;
4050be6800b0feba50fa2c1be7852ee2eb02c38afc0Vincent Palatin            boolean sourcePower = status.getCurrentPowerRole() == UsbPort.POWER_ROLE_SOURCE;
4069ebf2a5683db3dfd956f68b80f3f0a10b9705891Philip P. Moltmann            boolean sinkPower = status.getCurrentPowerRole() == UsbPort.POWER_ROLE_SINK;
4079ebf2a5683db3dfd956f68b80f3f0a10b9705891Philip P. Moltmann
4089ebf2a5683db3dfd956f68b80f3f0a10b9705891Philip P. Moltmann            if (DEBUG) {
4099ebf2a5683db3dfd956f68b80f3f0a10b9705891Philip P. Moltmann                Slog.i(TAG, "updateHostState " + port + " status=" + status);
4109ebf2a5683db3dfd956f68b80f3f0a10b9705891Philip P. Moltmann            }
4119ebf2a5683db3dfd956f68b80f3f0a10b9705891Philip P. Moltmann
4129ebf2a5683db3dfd956f68b80f3f0a10b9705891Philip P. Moltmann            SomeArgs args = SomeArgs.obtain();
4139ebf2a5683db3dfd956f68b80f3f0a10b9705891Philip P. Moltmann            args.argi1 = hostConnected ? 1 :0;
4149ebf2a5683db3dfd956f68b80f3f0a10b9705891Philip P. Moltmann            args.argi2 = sourcePower ? 1 :0;
4159ebf2a5683db3dfd956f68b80f3f0a10b9705891Philip P. Moltmann            args.argi3 = sinkPower ? 1 :0;
4169ebf2a5683db3dfd956f68b80f3f0a10b9705891Philip P. Moltmann
4179ebf2a5683db3dfd956f68b80f3f0a10b9705891Philip P. Moltmann            obtainMessage(MSG_UPDATE_HOST_STATE, args).sendToTarget();
4188338ed00ae44635d099b530b3360e6d1f7041827Jason Monk        }
4198338ed00ae44635d099b530b3360e6d1f7041827Jason Monk
420f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood        private boolean waitForState(String state) {
42102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            // wait for the transition to complete.
42202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            // give up after 1 second.
423460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            String value = null;
42402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            for (int i = 0; i < 20; i++) {
42568736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood                // State transition is done when sys.usb.state is set to the new configuration
426460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                value = SystemProperties.get(USB_STATE_PROPERTY);
427460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                if (state.equals(value)) return true;
428dab2072365565b4892be7910b0cdb870e83689f6RoboErik                SystemClock.sleep(50);
42902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            }
430460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            Slog.e(TAG, "waitForState(" + state + ") FAILED: got " + value);
43102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            return false;
43202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        }
43302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood
434f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood        private boolean setUsbConfig(String config) {
435fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood            if (DEBUG) Slog.d(TAG, "setUsbConfig(" + config + ")");
436f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood            // set the new configuration
437823e805c1c72b34bed8439e269f96b2f3a5cbe4eTim Kilbourn            // we always set it due to b/23631400, where adbd was getting killed
438823e805c1c72b34bed8439e269f96b2f3a5cbe4eTim Kilbourn            // and not restarted due to property timeouts on some devices
439823e805c1c72b34bed8439e269f96b2f3a5cbe4eTim Kilbourn            SystemProperties.set(USB_CONFIG_PROPERTY, config);
440f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood            return waitForState(config);
441f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood        }
442f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood
4431a008c1ca04871386830f511ee4b47299b92b01fNick Kralevich        private void setUsbDataUnlocked(boolean enable) {
4441a008c1ca04871386830f511ee4b47299b92b01fNick Kralevich            if (DEBUG) Slog.d(TAG, "setUsbDataUnlocked: " + enable);
4451a008c1ca04871386830f511ee4b47299b92b01fNick Kralevich            mUsbDataUnlocked = enable;
4461a008c1ca04871386830f511ee4b47299b92b01fNick Kralevich            updateUsbNotification();
44748b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda            updateUsbStateBroadcastIfNeeded();
4481a008c1ca04871386830f511ee4b47299b92b01fNick Kralevich            setEnabledFunctions(mCurrentFunctions, true);
4491a008c1ca04871386830f511ee4b47299b92b01fNick Kralevich        }
4501a008c1ca04871386830f511ee4b47299b92b01fNick Kralevich
45102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        private void setAdbEnabled(boolean enable) {
452de296f64483713fdf164f3e8bf41dc12d1cff59eMike Lockwood            if (DEBUG) Slog.d(TAG, "setAdbEnabled: " + enable);
45302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            if (enable != mAdbEnabled) {
45402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                mAdbEnabled = enable;
455460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown
456f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood                // Due to the persist.sys.usb.config property trigger, changing adb state requires
457469c15d6afc295af513f3136de4bfce63e165978Zoltan Szatmary-Ban                // persisting default function
458460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                String oldFunctions = getDefaultFunctions();
459460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                String newFunctions = applyAdbFunction(oldFunctions);
460460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                if (!oldFunctions.equals(newFunctions)) {
461460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                    SystemProperties.set(USB_PERSISTENT_CONFIG_PROPERTY, newFunctions);
462460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                }
463460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown
464469c15d6afc295af513f3136de4bfce63e165978Zoltan Szatmary-Ban                // After persisting them use the lock-down aware function set
465460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                setEnabledFunctions(mCurrentFunctions, false);
466d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood                updateAdbNotification();
46702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            }
468460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown
4694e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby            if (mDebuggingManager != null) {
4704e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby                mDebuggingManager.setAdbEnabled(mAdbEnabled);
4714e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby            }
47202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        }
47302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood
474674019065bceb4150190bfb1aa63cda9de0a8560Nick Kralevich        /**
475460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown         * Evaluates USB function policies and applies the change accordingly.
476674019065bceb4150190bfb1aa63cda9de0a8560Nick Kralevich         */
477460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown        private void setEnabledFunctions(String functions, boolean forceRestart) {
478460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            if (DEBUG) Slog.d(TAG, "setEnabledFunctions functions=" + functions + ", "
479460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                    + "forceRestart=" + forceRestart);
480460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown
481460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            // Try to set the enabled functions.
482460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            final String oldFunctions = mCurrentFunctions;
483460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            final boolean oldFunctionsApplied = mCurrentFunctionsApplied;
484460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            if (trySetEnabledFunctions(functions, forceRestart)) {
485460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                return;
486460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            }
487674019065bceb4150190bfb1aa63cda9de0a8560Nick Kralevich
488460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            // Didn't work.  Try to revert changes.
489460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            // We always reapply the policy in case certain constraints changed such as
490460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            // user restrictions independently of any other new functions we were
491460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            // trying to activate.
492460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            if (oldFunctionsApplied && !oldFunctions.equals(functions)) {
493460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                Slog.e(TAG, "Failsafe 1: Restoring previous USB functions.");
494460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                if (trySetEnabledFunctions(oldFunctions, false)) {
495460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                    return;
496460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                }
497460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            }
498afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo
499460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            // Still didn't work.  Try to restore the default functions.
500460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            Slog.e(TAG, "Failsafe 2: Restoring default USB functions.");
501460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            if (trySetEnabledFunctions(null, false)) {
502460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                return;
503460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            }
504460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown
505460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            // Now we're desperate.  Ignore the default functions.
506460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            // Try to get ADB working if enabled.
507460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            Slog.e(TAG, "Failsafe 3: Restoring empty function list (with ADB if enabled).");
508460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            if (trySetEnabledFunctions(UsbManager.USB_FUNCTION_NONE, false)) {
509460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                return;
510460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            }
511460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown
512460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            // Ouch.
513460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            Slog.e(TAG, "Unable to set any USB functions!");
514460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown        }
515460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown
516460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown        private boolean trySetEnabledFunctions(String functions, boolean forceRestart) {
517fcf10f7c12cb3107bdfedce6f76a8c866d154f3cNick Kralevich            if (functions == null) {
51843965fe5cecd2bc8e139f4cbd012e5d6407ac7f6Nick Kralevich                functions = getDefaultFunctions();
519fcf10f7c12cb3107bdfedce6f76a8c866d154f3cNick Kralevich            }
520460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            functions = applyAdbFunction(functions);
5212fedc4df5127d1a2eaf178e835d9f5398ce8f879Nick Kralevich            functions = applyOemOverrideFunction(functions);
522460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown
523460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            if (!mCurrentFunctions.equals(functions) || !mCurrentFunctionsApplied
524460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                    || forceRestart) {
525460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                Slog.i(TAG, "Setting USB config to " + functions);
526460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                mCurrentFunctions = functions;
527460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                mCurrentFunctionsApplied = false;
528460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown
529460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                // Kick the USB stack to close existing connections.
530460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                setUsbConfig(UsbManager.USB_FUNCTION_NONE);
531460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown
532460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                // Set the new USB configuration.
533460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                if (!setUsbConfig(functions)) {
534460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                    Slog.e(TAG, "Failed to switch USB config to " + functions);
535460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                    return false;
536460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                }
537460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown
538460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                mCurrentFunctionsApplied = true;
539460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            }
540460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            return true;
541460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown        }
542afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo
543460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown        private String applyAdbFunction(String functions) {
544fcf10f7c12cb3107bdfedce6f76a8c866d154f3cNick Kralevich            if (mAdbEnabled) {
545460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                functions = UsbManager.addFunction(functions, UsbManager.USB_FUNCTION_ADB);
54668736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood            } else {
547460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                functions = UsbManager.removeFunction(functions, UsbManager.USB_FUNCTION_ADB);
548fcf10f7c12cb3107bdfedce6f76a8c866d154f3cNick Kralevich            }
549460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            return functions;
550460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown        }
551460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown
5521a008c1ca04871386830f511ee4b47299b92b01fNick Kralevich        private boolean isUsbTransferAllowed() {
553460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
5541a008c1ca04871386830f511ee4b47299b92b01fNick Kralevich            return !userManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER);
55502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        }
55602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood
55702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        private void updateCurrentAccessory() {
558c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood            // We are entering accessory mode if we have received a request from the host
559c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood            // and the request has not timed out yet.
560c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood            boolean enteringAccessoryMode =
561c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood                    mAccessoryModeRequestTime > 0 &&
562c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood                        SystemClock.elapsedRealtime() <
563c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood                            mAccessoryModeRequestTime + ACCESSORY_REQUEST_TIMEOUT;
564c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood
565c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood            if (mConfigured && enteringAccessoryMode) {
566c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood                // successfully entered accessory mode
56702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood
568166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood                if (mAccessoryStrings != null) {
569166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood                    mCurrentAccessory = new UsbAccessory(mAccessoryStrings);
570fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood                    Slog.d(TAG, "entering USB accessory mode: " + mCurrentAccessory);
57102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                    // defer accessoryAttached if system is not ready
572d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood                    if (mBootCompleted) {
573fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey                        getCurrentSettings().accessoryAttached(mCurrentAccessory);
574460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                    } // else handle in boot completed
57502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                } else {
576fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood                    Slog.e(TAG, "nativeGetAccessoryStrings failed");
57702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                }
578c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood            } else if (!enteringAccessoryMode) {
57902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                // make sure accessory mode is off
58002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                // and restore default functions
581fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood                Slog.d(TAG, "exited USB accessory mode");
582460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                setEnabledFunctions(null, false);
58302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood
58402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                if (mCurrentAccessory != null) {
585d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood                    if (mBootCompleted) {
586fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey                        getCurrentSettings().accessoryDetached(mCurrentAccessory);
58702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                    }
58802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                    mCurrentAccessory = null;
589166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood                    mAccessoryStrings = null;
59046d0adf8256a42416584765625852b6e48497c90Mike Lockwood                }
59146d0adf8256a42416584765625852b6e48497c90Mike Lockwood            }
59246d0adf8256a42416584765625852b6e48497c90Mike Lockwood        }
59346d0adf8256a42416584765625852b6e48497c90Mike Lockwood
59448b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda        private boolean isUsbStateChanged(Intent intent) {
59548b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda            final Set<String> keySet = intent.getExtras().keySet();
59648b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda            if (mBroadcastedIntent == null) {
59748b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                for (String key : keySet) {
59848b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                    if (intent.getBooleanExtra(key, false)) {
59948b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                        // MTP function is enabled by default.
60048b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                        if (UsbManager.USB_FUNCTION_MTP.equals(key)) {
60148b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                            continue;
60248b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                        }
60348b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                        return true;
60448b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                    }
60548b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                }
60648b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda            } else {
60748b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                if (!keySet.equals(mBroadcastedIntent.getExtras().keySet())) {
60848b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                    return true;
60948b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                }
61048b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                for (String key : keySet) {
61148b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                    if (intent.getBooleanExtra(key, false) !=
61248b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                        mBroadcastedIntent.getBooleanExtra(key, false)) {
61348b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                        return true;
61448b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                    }
61548b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                }
61648b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda            }
61748b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda            return false;
61848b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda        }
61948b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda
62048b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda        private void updateUsbStateBroadcastIfNeeded() {
62102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            // send a sticky broadcast containing current USB state
62202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            Intent intent = new Intent(UsbManager.ACTION_USB_STATE);
623460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
624460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                    | Intent.FLAG_RECEIVER_FOREGROUND);
62502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            intent.putExtra(UsbManager.USB_CONNECTED, mConnected);
626618fa6ffc154fd131697b6107b431b4557ec118cDaichi Hirono            intent.putExtra(UsbManager.USB_HOST_CONNECTED, mHostConnected);
62702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            intent.putExtra(UsbManager.USB_CONFIGURED, mConfigured);
6281a008c1ca04871386830f511ee4b47299b92b01fNick Kralevich            intent.putExtra(UsbManager.USB_DATA_UNLOCKED, isUsbTransferAllowed() && mUsbDataUnlocked);
62902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood
63002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            if (mCurrentFunctions != null) {
63102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                String[] functions = mCurrentFunctions.split(",");
63202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                for (int i = 0; i < functions.length; i++) {
63348b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                    final String function = functions[i];
63448b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                    if (UsbManager.USB_FUNCTION_NONE.equals(function)) {
63548b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                        continue;
63648b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                    }
63748b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                    intent.putExtra(function, true);
63802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                }
63946d0adf8256a42416584765625852b6e48497c90Mike Lockwood            }
64002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood
64148b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda            // send broadcast intent only if the USB state has changed
64248b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda            if (!isUsbStateChanged(intent)) {
64348b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                if (DEBUG) {
64448b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                    Slog.d(TAG, "skip broadcasting " + intent + " extras: " + intent.getExtras());
64548b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                }
64648b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                return;
64748b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda            }
64848b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda
64948b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda            if (DEBUG) Slog.d(TAG, "broadcasting " + intent + " extras: " + intent.getExtras());
6505ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn            mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
65148b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda            mBroadcastedIntent = intent;
65246d0adf8256a42416584765625852b6e48497c90Mike Lockwood        }
65346d0adf8256a42416584765625852b6e48497c90Mike Lockwood
654460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown        private void updateUsbFunctions() {
655460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            updateAudioSourceFunction();
656460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            updateMidiFunction();
657460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown        }
658460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown
659bf91046872dd711019e8dec543441601576cc950Mike Lockwood        private void updateAudioSourceFunction() {
660460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            boolean enabled = UsbManager.containsFunction(mCurrentFunctions,
661bf91046872dd711019e8dec543441601576cc950Mike Lockwood                    UsbManager.USB_FUNCTION_AUDIO_SOURCE);
662bf91046872dd711019e8dec543441601576cc950Mike Lockwood            if (enabled != mAudioSourceEnabled) {
6632e3434149e00f921ca3555ae55cba04d3c64eeb1Mike Lockwood                int card = -1;
6642e3434149e00f921ca3555ae55cba04d3c64eeb1Mike Lockwood                int device = -1;
6652e3434149e00f921ca3555ae55cba04d3c64eeb1Mike Lockwood
666bf91046872dd711019e8dec543441601576cc950Mike Lockwood                if (enabled) {
6672a39c6ff73f3e2610f7624bf5966f2ee2f6e1923Michael Ollanketo                    Scanner scanner = null;
668bf91046872dd711019e8dec543441601576cc950Mike Lockwood                    try {
6692a39c6ff73f3e2610f7624bf5966f2ee2f6e1923Michael Ollanketo                        scanner = new Scanner(new File(AUDIO_SOURCE_PCM_PATH));
6702e3434149e00f921ca3555ae55cba04d3c64eeb1Mike Lockwood                        card = scanner.nextInt();
6712e3434149e00f921ca3555ae55cba04d3c64eeb1Mike Lockwood                        device = scanner.nextInt();
672bf91046872dd711019e8dec543441601576cc950Mike Lockwood                    } catch (FileNotFoundException e) {
673bf91046872dd711019e8dec543441601576cc950Mike Lockwood                        Slog.e(TAG, "could not open audio source PCM file", e);
6742a39c6ff73f3e2610f7624bf5966f2ee2f6e1923Michael Ollanketo                    } finally {
6752a39c6ff73f3e2610f7624bf5966f2ee2f6e1923Michael Ollanketo                        if (scanner != null) {
6762a39c6ff73f3e2610f7624bf5966f2ee2f6e1923Michael Ollanketo                            scanner.close();
6772a39c6ff73f3e2610f7624bf5966f2ee2f6e1923Michael Ollanketo                        }
678bf91046872dd711019e8dec543441601576cc950Mike Lockwood                    }
6799d5a4be05b6d51ebb768e5fbcfa27ed9a39269b3Mike Lockwood                }
6802e3434149e00f921ca3555ae55cba04d3c64eeb1Mike Lockwood                mUsbAlsaManager.setAccessoryAudioState(enabled, card, device);
681bf91046872dd711019e8dec543441601576cc950Mike Lockwood                mAudioSourceEnabled = enabled;
6829d5a4be05b6d51ebb768e5fbcfa27ed9a39269b3Mike Lockwood            }
6839d5a4be05b6d51ebb768e5fbcfa27ed9a39269b3Mike Lockwood        }
6849d5a4be05b6d51ebb768e5fbcfa27ed9a39269b3Mike Lockwood
6852a57bc7fd602853dc1a22dcee1ff50f92cc29060Mike Lockwood        private void updateMidiFunction() {
686460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown            boolean enabled = UsbManager.containsFunction(mCurrentFunctions,
687460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                    UsbManager.USB_FUNCTION_MIDI);
6882a57bc7fd602853dc1a22dcee1ff50f92cc29060Mike Lockwood            if (enabled != mMidiEnabled) {
6892a57bc7fd602853dc1a22dcee1ff50f92cc29060Mike Lockwood                if (enabled) {
6902a57bc7fd602853dc1a22dcee1ff50f92cc29060Mike Lockwood                    Scanner scanner = null;
6912a57bc7fd602853dc1a22dcee1ff50f92cc29060Mike Lockwood                    try {
6922a57bc7fd602853dc1a22dcee1ff50f92cc29060Mike Lockwood                        scanner = new Scanner(new File(MIDI_ALSA_PATH));
693b7ce094c9e546c4a802bd8ce3a43592979a5e3dfMike Lockwood                        mMidiCard = scanner.nextInt();
694b7ce094c9e546c4a802bd8ce3a43592979a5e3dfMike Lockwood                        mMidiDevice = scanner.nextInt();
6952a57bc7fd602853dc1a22dcee1ff50f92cc29060Mike Lockwood                    } catch (FileNotFoundException e) {
6962a57bc7fd602853dc1a22dcee1ff50f92cc29060Mike Lockwood                        Slog.e(TAG, "could not open MIDI PCM file", e);
697b7ce094c9e546c4a802bd8ce3a43592979a5e3dfMike Lockwood                        enabled = false;
6982a57bc7fd602853dc1a22dcee1ff50f92cc29060Mike Lockwood                    } finally {
6992a57bc7fd602853dc1a22dcee1ff50f92cc29060Mike Lockwood                        if (scanner != null) {
7002a57bc7fd602853dc1a22dcee1ff50f92cc29060Mike Lockwood                            scanner.close();
7012a57bc7fd602853dc1a22dcee1ff50f92cc29060Mike Lockwood                        }
7022a57bc7fd602853dc1a22dcee1ff50f92cc29060Mike Lockwood                    }
7032a57bc7fd602853dc1a22dcee1ff50f92cc29060Mike Lockwood                }
7042a57bc7fd602853dc1a22dcee1ff50f92cc29060Mike Lockwood                mMidiEnabled = enabled;
7052a57bc7fd602853dc1a22dcee1ff50f92cc29060Mike Lockwood            }
706b7ce094c9e546c4a802bd8ce3a43592979a5e3dfMike Lockwood            mUsbAlsaManager.setPeripheralMidiState(mMidiEnabled && mConfigured, mMidiCard, mMidiDevice);
7072a57bc7fd602853dc1a22dcee1ff50f92cc29060Mike Lockwood        }
7082a57bc7fd602853dc1a22dcee1ff50f92cc29060Mike Lockwood
70902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        @Override
71002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        public void handleMessage(Message msg) {
71102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            switch (msg.what) {
71202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                case MSG_UPDATE_STATE:
71302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                    mConnected = (msg.arg1 == 1);
71402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                    mConfigured = (msg.arg2 == 1);
715674019065bceb4150190bfb1aa63cda9de0a8560Nick Kralevich                    if (!mConnected) {
716674019065bceb4150190bfb1aa63cda9de0a8560Nick Kralevich                        // When a disconnect occurs, relock access to sensitive user data
717674019065bceb4150190bfb1aa63cda9de0a8560Nick Kralevich                        mUsbDataUnlocked = false;
718674019065bceb4150190bfb1aa63cda9de0a8560Nick Kralevich                    }
719d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood                    updateUsbNotification();
720d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood                    updateAdbNotification();
721460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                    if (UsbManager.containsFunction(mCurrentFunctions,
72202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                            UsbManager.USB_FUNCTION_ACCESSORY)) {
72302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                        updateCurrentAccessory();
724c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood                    } else if (!mConnected) {
72502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                        // restore defaults when USB is disconnected
726460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                        setEnabledFunctions(null, false);
72702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                    }
728d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood                    if (mBootCompleted) {
72948b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                        updateUsbStateBroadcastIfNeeded();
730460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                        updateUsbFunctions();
73102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                    }
73202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                    break;
7338338ed00ae44635d099b530b3360e6d1f7041827Jason Monk                case MSG_UPDATE_HOST_STATE:
7349ebf2a5683db3dfd956f68b80f3f0a10b9705891Philip P. Moltmann                    SomeArgs args = (SomeArgs) msg.obj;
7359ebf2a5683db3dfd956f68b80f3f0a10b9705891Philip P. Moltmann                    mHostConnected = (args.argi1 == 1);
7369ebf2a5683db3dfd956f68b80f3f0a10b9705891Philip P. Moltmann                    mSourcePower = (args.argi2 == 1);
7379ebf2a5683db3dfd956f68b80f3f0a10b9705891Philip P. Moltmann                    mSinkPower = (args.argi3 == 1);
7389ebf2a5683db3dfd956f68b80f3f0a10b9705891Philip P. Moltmann                    args.recycle();
7398338ed00ae44635d099b530b3360e6d1f7041827Jason Monk                    updateUsbNotification();
740618fa6ffc154fd131697b6107b431b4557ec118cDaichi Hirono                    if (mBootCompleted) {
741618fa6ffc154fd131697b6107b431b4557ec118cDaichi Hirono                        updateUsbStateBroadcastIfNeeded();
742618fa6ffc154fd131697b6107b431b4557ec118cDaichi Hirono                    }
7438338ed00ae44635d099b530b3360e6d1f7041827Jason Monk                    break;
74402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                case MSG_ENABLE_ADB:
74502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                    setAdbEnabled(msg.arg1 == 1);
74602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                    break;
747166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood                case MSG_SET_CURRENT_FUNCTIONS:
748166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood                    String functions = (String)msg.obj;
749460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                    setEnabledFunctions(functions, false);
750460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                    break;
751460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                case MSG_UPDATE_USER_RESTRICTIONS:
752460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                    setEnabledFunctions(mCurrentFunctions, false);
75302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                    break;
754674019065bceb4150190bfb1aa63cda9de0a8560Nick Kralevich                case MSG_SET_USB_DATA_UNLOCKED:
7551a008c1ca04871386830f511ee4b47299b92b01fNick Kralevich                    setUsbDataUnlocked(msg.arg1 == 1);
756674019065bceb4150190bfb1aa63cda9de0a8560Nick Kralevich                    break;
75702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                case MSG_SYSTEM_READY:
758d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood                    updateUsbNotification();
759d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood                    updateAdbNotification();
76048b9a7c70acff8f1469e487d08bbcb7e6a47ad8aYasuhiro Matsuda                    updateUsbStateBroadcastIfNeeded();
761460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                    updateUsbFunctions();
762d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood                    break;
763d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood                case MSG_BOOT_COMPLETED:
764d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood                    mBootCompleted = true;
765d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood                    if (mCurrentAccessory != null) {
766fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey                        getCurrentSettings().accessoryAttached(mCurrentAccessory);
76702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                    }
7684e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby                    if (mDebuggingManager != null) {
7694e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby                        mDebuggingManager.setAdbEnabled(mAdbEnabled);
7704e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby                    }
77102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood                    break;
77227bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey                case MSG_USER_SWITCHED: {
773460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                    if (mCurrentUser != msg.arg1) {
774460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                        // Restart the USB stack and re-apply user restrictions for MTP or PTP.
775460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                        final boolean active = UsbManager.containsFunction(mCurrentFunctions,
776460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                                        UsbManager.USB_FUNCTION_MTP)
777460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                                || UsbManager.containsFunction(mCurrentFunctions,
778460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                                        UsbManager.USB_FUNCTION_PTP);
779dabd6b8f45e464a83fee96c69076abb78dbc862fFyodor Kupolov                        if (mUsbDataUnlocked && active && mCurrentUser != UserHandle.USER_NULL) {
780460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                            Slog.v(TAG, "Current user switched to " + mCurrentUser
781460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                                    + "; resetting USB host stack for MTP or PTP");
7825701321701a319d3f2d98365a82266eeddaed895Nick Kralevich                            // avoid leaking sensitive data from previous user
7835701321701a319d3f2d98365a82266eeddaed895Nick Kralevich                            mUsbDataUnlocked = false;
784460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                            setEnabledFunctions(mCurrentFunctions, true);
785460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                        }
7869769ef9f8ac86ef69d08afbadb7a00aceeadc5a6Emily Bernier                        mCurrentUser = msg.arg1;
78727bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey                    }
78827bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey                    break;
78927bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey                }
79046d0adf8256a42416584765625852b6e48497c90Mike Lockwood            }
79146d0adf8256a42416584765625852b6e48497c90Mike Lockwood        }
79246d0adf8256a42416584765625852b6e48497c90Mike Lockwood
79302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        public UsbAccessory getCurrentAccessory() {
79402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood            return mCurrentAccessory;
79502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        }
79602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood
797d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood        private void updateUsbNotification() {
798c35d7759d8ee8b4a55f4b5b58151f46db47537f4Chris Wren            if (mNotificationManager == null || !mUseUsbNotification
799c35d7759d8ee8b4a55f4b5b58151f46db47537f4Chris Wren                    || ("0".equals(SystemProperties.get("persist.charging.notify")))) return;
800fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood            int id = 0;
801a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood            Resources r = mContext.getResources();
802b6abccc8f3d8a870a97cb5f07f7561097670e134Daichi Hirono            if (mConnected) {
803674019065bceb4150190bfb1aa63cda9de0a8560Nick Kralevich                if (!mUsbDataUnlocked) {
8040be6800b0feba50fa2c1be7852ee2eb02c38afc0Vincent Palatin                    if (mSourcePower) {
8050be6800b0feba50fa2c1be7852ee2eb02c38afc0Vincent Palatin                        id = com.android.internal.R.string.usb_supplying_notification_title;
8060be6800b0feba50fa2c1be7852ee2eb02c38afc0Vincent Palatin                    } else {
8070be6800b0feba50fa2c1be7852ee2eb02c38afc0Vincent Palatin                        id = com.android.internal.R.string.usb_charging_notification_title;
8080be6800b0feba50fa2c1be7852ee2eb02c38afc0Vincent Palatin                    }
809460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                } else if (UsbManager.containsFunction(mCurrentFunctions,
810460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                        UsbManager.USB_FUNCTION_MTP)) {
811fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood                    id = com.android.internal.R.string.usb_mtp_notification_title;
812460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                } else if (UsbManager.containsFunction(mCurrentFunctions,
813460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                        UsbManager.USB_FUNCTION_PTP)) {
814fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood                    id = com.android.internal.R.string.usb_ptp_notification_title;
815460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                } else if (UsbManager.containsFunction(mCurrentFunctions,
816460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                        UsbManager.USB_FUNCTION_MIDI)) {
817c3c2ff70a23ff31bec72e7794ea33552ca106438Mike Lockwood                    id = com.android.internal.R.string.usb_midi_notification_title;
818460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                } else if (UsbManager.containsFunction(mCurrentFunctions,
819460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown                        UsbManager.USB_FUNCTION_ACCESSORY)) {
820fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood                    id = com.android.internal.R.string.usb_accessory_notification_title;
8210be6800b0feba50fa2c1be7852ee2eb02c38afc0Vincent Palatin                } else if (mSourcePower) {
8220be6800b0feba50fa2c1be7852ee2eb02c38afc0Vincent Palatin                    id = com.android.internal.R.string.usb_supplying_notification_title;
823d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood                } else {
824fcf10f7c12cb3107bdfedce6f76a8c866d154f3cNick Kralevich                    id = com.android.internal.R.string.usb_charging_notification_title;
825d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood                }
8260be6800b0feba50fa2c1be7852ee2eb02c38afc0Vincent Palatin            } else if (mSourcePower) {
827b6abccc8f3d8a870a97cb5f07f7561097670e134Daichi Hirono                id = com.android.internal.R.string.usb_supplying_notification_title;
8289ebf2a5683db3dfd956f68b80f3f0a10b9705891Philip P. Moltmann            } else if (mHostConnected && mSinkPower) {
8299ebf2a5683db3dfd956f68b80f3f0a10b9705891Philip P. Moltmann                id = com.android.internal.R.string.usb_charging_notification_title;
830a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood            }
831a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood            if (id != mUsbNotificationId) {
832a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood                // clear notification if title needs changing
833fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood                if (mUsbNotificationId != 0) {
83450cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn                    mNotificationManager.cancelAsUser(null, mUsbNotificationId,
83550cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn                            UserHandle.ALL);
836fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood                    mUsbNotificationId = 0;
837a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood                }
838fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood                if (id != 0) {
839d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood                    CharSequence message = r.getText(
840d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood                            com.android.internal.R.string.usb_notification_message);
841fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood                    CharSequence title = r.getText(id);
842d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood
843765f97d5e608031bc1de4156c6e681e4d178c7eeChristopher Tate                    Intent intent = Intent.makeRestartActivityTask(
844765f97d5e608031bc1de4156c6e681e4d178c7eeChristopher Tate                            new ComponentName("com.android.settings",
845fcf10f7c12cb3107bdfedce6f76a8c866d154f3cNick Kralevich                                    "com.android.settings.deviceinfo.UsbModeChooserActivity"));
84650cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn                    PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0,
84750cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn                            intent, 0, null, UserHandle.CURRENT);
8486d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren
8496d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren                    Notification notification = new Notification.Builder(mContext)
8506d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
8516d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren                            .setWhen(0)
8526d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren                            .setOngoing(true)
8536d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren                            .setTicker(title)
8546d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren                            .setDefaults(0)  // please be quiet
8556d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren                            .setPriority(Notification.PRIORITY_MIN)
8566d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren                            .setColor(mContext.getColor(
8576d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren                                    com.android.internal.R.color.system_notification_accent_color))
8586d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren                            .setContentTitle(title)
8596d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren                            .setContentText(message)
8606d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren                            .setContentIntent(pi)
8616d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren                            .setVisibility(Notification.VISIBILITY_PUBLIC)
8626d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren                            .build();
86350cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn                    mNotificationManager.notifyAsUser(null, id, notification,
86450cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn                            UserHandle.ALL);
865d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood                    mUsbNotificationId = id;
866d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood                }
867d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood            }
868d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood        }
869d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood
870d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood        private void updateAdbNotification() {
871d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood            if (mNotificationManager == null) return;
872fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood            final int id = com.android.internal.R.string.adb_active_notification_title;
873d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood            if (mAdbEnabled && mConnected) {
874d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood                if ("0".equals(SystemProperties.get("persist.adb.notify"))) return;
875d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood
876d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood                if (!mAdbNotificationShown) {
877d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood                    Resources r = mContext.getResources();
878fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood                    CharSequence title = r.getText(id);
879d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood                    CharSequence message = r.getText(
880d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood                            com.android.internal.R.string.adb_active_notification_message);
881d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood
882765f97d5e608031bc1de4156c6e681e4d178c7eeChristopher Tate                    Intent intent = Intent.makeRestartActivityTask(
883765f97d5e608031bc1de4156c6e681e4d178c7eeChristopher Tate                            new ComponentName("com.android.settings",
884765f97d5e608031bc1de4156c6e681e4d178c7eeChristopher Tate                                    "com.android.settings.DevelopmentSettings"));
88550cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn                    PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0,
88650cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn                            intent, 0, null, UserHandle.CURRENT);
8876d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren
8886d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren                    Notification notification = new Notification.Builder(mContext)
8896d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
8906d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren                            .setWhen(0)
8916d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren                            .setOngoing(true)
8926d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren                            .setTicker(title)
8936d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren                            .setDefaults(0)  // please be quiet
894d1d533610aad279f7ae9037f0e4b3dd865bb0a24Julia Reynolds                            .setPriority(Notification.PRIORITY_DEFAULT)
8956d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren                            .setColor(mContext.getColor(
8966d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren                                    com.android.internal.R.color.system_notification_accent_color))
8976d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren                            .setContentTitle(title)
8986d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren                            .setContentText(message)
8996d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren                            .setContentIntent(pi)
9006d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren                            .setVisibility(Notification.VISIBILITY_PUBLIC)
9016d8e413a63c6ab054557f81d53bb8b35f0816679Chris Wren                            .build();
902d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood                    mAdbNotificationShown = true;
90350cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn                    mNotificationManager.notifyAsUser(null, id, notification,
90450cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn                            UserHandle.ALL);
905d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood                }
906d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood            } else if (mAdbNotificationShown) {
907d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood                mAdbNotificationShown = false;
90850cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn                mNotificationManager.cancelAsUser(null, id, UserHandle.ALL);
909d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood            }
910d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood        }
911d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood
912469c15d6afc295af513f3136de4bfce63e165978Zoltan Szatmary-Ban        private String getDefaultFunctions() {
9131a008c1ca04871386830f511ee4b47299b92b01fNick Kralevich            String func = SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY,
9141a008c1ca04871386830f511ee4b47299b92b01fNick Kralevich                    UsbManager.USB_FUNCTION_NONE);
9151a008c1ca04871386830f511ee4b47299b92b01fNick Kralevich            if (UsbManager.USB_FUNCTION_NONE.equals(func)) {
9161a008c1ca04871386830f511ee4b47299b92b01fNick Kralevich                func = UsbManager.USB_FUNCTION_MTP;
9171a008c1ca04871386830f511ee4b47299b92b01fNick Kralevich            }
9181a008c1ca04871386830f511ee4b47299b92b01fNick Kralevich            return func;
919469c15d6afc295af513f3136de4bfce63e165978Zoltan Szatmary-Ban        }
920469c15d6afc295af513f3136de4bfce63e165978Zoltan Szatmary-Ban
9212dbccc1926ea2d3e27c5cfd2d61d2b3d5ed787c0Jeff Brown        public void dump(IndentingPrintWriter pw) {
9222dbccc1926ea2d3e27c5cfd2d61d2b3d5ed787c0Jeff Brown            pw.println("USB Device State:");
9232dbccc1926ea2d3e27c5cfd2d61d2b3d5ed787c0Jeff Brown            pw.println("  mCurrentFunctions: " + mCurrentFunctions);
9242dbccc1926ea2d3e27c5cfd2d61d2b3d5ed787c0Jeff Brown            pw.println("  mCurrentFunctionsApplied: " + mCurrentFunctionsApplied);
9252dbccc1926ea2d3e27c5cfd2d61d2b3d5ed787c0Jeff Brown            pw.println("  mConnected: " + mConnected);
9262dbccc1926ea2d3e27c5cfd2d61d2b3d5ed787c0Jeff Brown            pw.println("  mConfigured: " + mConfigured);
9271a008c1ca04871386830f511ee4b47299b92b01fNick Kralevich            pw.println("  mUsbDataUnlocked: " + mUsbDataUnlocked);
9282dbccc1926ea2d3e27c5cfd2d61d2b3d5ed787c0Jeff Brown            pw.println("  mCurrentAccessory: " + mCurrentAccessory);
9299ebf2a5683db3dfd956f68b80f3f0a10b9705891Philip P. Moltmann            pw.println("  mHostConnected: " + mHostConnected);
9309ebf2a5683db3dfd956f68b80f3f0a10b9705891Philip P. Moltmann            pw.println("  mSourcePower: " + mSourcePower);
9319ebf2a5683db3dfd956f68b80f3f0a10b9705891Philip P. Moltmann            pw.println("  mSinkPower: " + mSinkPower);
9326ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood            try {
9332dbccc1926ea2d3e27c5cfd2d61d2b3d5ed787c0Jeff Brown                pw.println("  Kernel state: "
9346ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood                        + FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim());
9352dbccc1926ea2d3e27c5cfd2d61d2b3d5ed787c0Jeff Brown                pw.println("  Kernel function list: "
9366ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood                        + FileUtils.readTextFile(new File(FUNCTIONS_PATH), 0, null).trim());
9376ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood            } catch (IOException e) {
9386ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood                pw.println("IOException: " + e);
9396ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood            }
94002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        }
94146d0adf8256a42416584765625852b6e48497c90Mike Lockwood    }
94246d0adf8256a42416584765625852b6e48497c90Mike Lockwood
94302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood    /* returns the currently attached USB accessory */
94446d0adf8256a42416584765625852b6e48497c90Mike Lockwood    public UsbAccessory getCurrentAccessory() {
94502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        return mHandler.getCurrentAccessory();
94646d0adf8256a42416584765625852b6e48497c90Mike Lockwood    }
94746d0adf8256a42416584765625852b6e48497c90Mike Lockwood
94802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood    /* opens the currently attached USB accessory */
949abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood    public ParcelFileDescriptor openAccessory(UsbAccessory accessory) {
950abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood        UsbAccessory currentAccessory = mHandler.getCurrentAccessory();
951abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood        if (currentAccessory == null) {
952abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood            throw new IllegalArgumentException("no accessory attached");
95346d0adf8256a42416584765625852b6e48497c90Mike Lockwood        }
954abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood        if (!currentAccessory.equals(accessory)) {
955abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood            String error = accessory.toString()
956abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood                    + " does not match current accessory "
957abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood                    + currentAccessory;
958abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood            throw new IllegalArgumentException(error);
959abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood        }
960fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey        getCurrentSettings().checkPermission(accessory);
961abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood        return nativeOpenAccessory();
962abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood    }
96302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood
964460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown    public boolean isFunctionEnabled(String function) {
965460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown        return UsbManager.containsFunction(SystemProperties.get(USB_CONFIG_PROPERTY), function);
966460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown    }
967460a146eb8f827e4e70f2dd93d1ba852d0feb06bJeff Brown
968fcf10f7c12cb3107bdfedce6f76a8c866d154f3cNick Kralevich    public void setCurrentFunctions(String functions) {
969fcf10f7c12cb3107bdfedce6f76a8c866d154f3cNick Kralevich        if (DEBUG) Slog.d(TAG, "setCurrentFunctions(" + functions + ")");
970fcf10f7c12cb3107bdfedce6f76a8c866d154f3cNick Kralevich        mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions);
97102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood    }
97246d0adf8256a42416584765625852b6e48497c90Mike Lockwood
973674019065bceb4150190bfb1aa63cda9de0a8560Nick Kralevich    public void setUsbDataUnlocked(boolean unlocked) {
974674019065bceb4150190bfb1aa63cda9de0a8560Nick Kralevich        if (DEBUG) Slog.d(TAG, "setUsbDataUnlocked(" + unlocked + ")");
975674019065bceb4150190bfb1aa63cda9de0a8560Nick Kralevich        mHandler.sendMessage(MSG_SET_USB_DATA_UNLOCKED, unlocked);
976674019065bceb4150190bfb1aa63cda9de0a8560Nick Kralevich    }
977674019065bceb4150190bfb1aa63cda9de0a8560Nick Kralevich
978afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo    private void readOemUsbOverrideConfig() {
979afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo        String[] configList = mContext.getResources().getStringArray(
980afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo            com.android.internal.R.array.config_oemUsbModeOverride);
981afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo
982afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo        if (configList != null) {
983afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo            for (String config: configList) {
984afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo                String[] items = config.split(":");
985afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo                if (items.length == 3) {
986afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo                    if (mOemModeMap == null) {
987afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo                        mOemModeMap = new HashMap<String, List<Pair<String, String>>>();
988afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo                    }
9892cb6c60c0d2de3bc743c043aca963db6fe52662fAdam Lesinski                    List<Pair<String, String>> overrideList = mOemModeMap.get(items[0]);
990afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo                    if (overrideList == null) {
991afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo                        overrideList = new LinkedList<Pair<String, String>>();
992afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo                        mOemModeMap.put(items[0], overrideList);
993afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo                    }
994afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo                    overrideList.add(new Pair<String, String>(items[1], items[2]));
995afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo                }
996afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo            }
997afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo        }
998afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo    }
999afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo
10002fedc4df5127d1a2eaf178e835d9f5398ce8f879Nick Kralevich    private String applyOemOverrideFunction(String usbFunctions) {
10012fedc4df5127d1a2eaf178e835d9f5398ce8f879Nick Kralevich        if ((usbFunctions == null) || (mOemModeMap == null)) return usbFunctions;
10022fedc4df5127d1a2eaf178e835d9f5398ce8f879Nick Kralevich
10032fedc4df5127d1a2eaf178e835d9f5398ce8f879Nick Kralevich        String bootMode = SystemProperties.get(BOOT_MODE_PROPERTY, "unknown");
10042fedc4df5127d1a2eaf178e835d9f5398ce8f879Nick Kralevich
10052fedc4df5127d1a2eaf178e835d9f5398ce8f879Nick Kralevich        List<Pair<String, String>> overrides = mOemModeMap.get(bootMode);
10062fedc4df5127d1a2eaf178e835d9f5398ce8f879Nick Kralevich        if (overrides != null) {
10072fedc4df5127d1a2eaf178e835d9f5398ce8f879Nick Kralevich            for (Pair<String, String> pair: overrides) {
10082fedc4df5127d1a2eaf178e835d9f5398ce8f879Nick Kralevich                if (pair.first.equals(usbFunctions)) {
10092fedc4df5127d1a2eaf178e835d9f5398ce8f879Nick Kralevich                    Slog.d(TAG, "OEM USB override: " + pair.first + " ==> " + pair.second);
10102fedc4df5127d1a2eaf178e835d9f5398ce8f879Nick Kralevich                    return pair.second;
10112fedc4df5127d1a2eaf178e835d9f5398ce8f879Nick Kralevich                }
10122fedc4df5127d1a2eaf178e835d9f5398ce8f879Nick Kralevich            }
10132fedc4df5127d1a2eaf178e835d9f5398ce8f879Nick Kralevich        }
10142fedc4df5127d1a2eaf178e835d9f5398ce8f879Nick Kralevich        // return passed in functions as is.
10152fedc4df5127d1a2eaf178e835d9f5398ce8f879Nick Kralevich        return usbFunctions;
10162fedc4df5127d1a2eaf178e835d9f5398ce8f879Nick Kralevich    }
10172fedc4df5127d1a2eaf178e835d9f5398ce8f879Nick Kralevich
10184e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby    public void allowUsbDebugging(boolean alwaysAllow, String publicKey) {
10194e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby        if (mDebuggingManager != null) {
10204e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby            mDebuggingManager.allowUsbDebugging(alwaysAllow, publicKey);
10214e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby        }
10224e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby    }
10234e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby
10244e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby    public void denyUsbDebugging() {
10254e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby        if (mDebuggingManager != null) {
10264e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby            mDebuggingManager.denyUsbDebugging();
10274e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby        }
10284e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby    }
10294e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby
1030cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby    public void clearUsbDebuggingKeys() {
1031cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby        if (mDebuggingManager != null) {
1032cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby            mDebuggingManager.clearUsbDebuggingKeys();
1033cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby        } else {
1034cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby            throw new RuntimeException("Cannot clear Usb Debugging keys, "
1035cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby                        + "UsbDebuggingManager not enabled");
1036cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby        }
1037cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby    }
1038cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby
10392dbccc1926ea2d3e27c5cfd2d61d2b3d5ed787c0Jeff Brown    public void dump(IndentingPrintWriter pw) {
104002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood        if (mHandler != null) {
10412dbccc1926ea2d3e27c5cfd2d61d2b3d5ed787c0Jeff Brown            mHandler.dump(pw);
104246d0adf8256a42416584765625852b6e48497c90Mike Lockwood        }
10434e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby        if (mDebuggingManager != null) {
10442dbccc1926ea2d3e27c5cfd2d61d2b3d5ed787c0Jeff Brown            mDebuggingManager.dump(pw);
10454e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby        }
104646d0adf8256a42416584765625852b6e48497c90Mike Lockwood    }
104746d0adf8256a42416584765625852b6e48497c90Mike Lockwood
104846d0adf8256a42416584765625852b6e48497c90Mike Lockwood    private native String[] nativeGetAccessoryStrings();
104946d0adf8256a42416584765625852b6e48497c90Mike Lockwood    private native ParcelFileDescriptor nativeOpenAccessory();
1050d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood    private native boolean nativeIsStartRequested();
1051166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood    private native int nativeGetAudioMode();
105246d0adf8256a42416584765625852b6e48497c90Mike Lockwood}
1053