1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.providers.media;
18
19import android.app.ActivityManager;
20import android.content.BroadcastReceiver;
21import android.content.Context;
22import android.content.Intent;
23import android.content.IntentFilter;
24import android.hardware.usb.UsbManager;
25import android.net.Uri;
26import android.os.Bundle;
27import android.os.UserHandle;
28import android.util.Log;
29import android.mtp.MtpServer;
30
31public class MtpReceiver extends BroadcastReceiver {
32    private static final String TAG = MtpReceiver.class.getSimpleName();
33    private static final boolean DEBUG = false;
34
35    @Override
36    public void onReceive(Context context, Intent intent) {
37        final String action = intent.getAction();
38        if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
39            // If we somehow fail to configure after boot, it becomes difficult to
40            // recover usb state. Thus we always configure once on boot, but it
41            // has no effect if Mtp is disabled or already configured.
42            MtpServer.configure(false);
43            final Intent usbState = context.registerReceiver(
44                    null, new IntentFilter(UsbManager.ACTION_USB_STATE));
45            if (usbState != null) {
46                handleUsbState(context, usbState);
47            }
48        } else if (UsbManager.ACTION_USB_STATE.equals(action)) {
49            handleUsbState(context, intent);
50        }
51    }
52
53    private void handleUsbState(Context context, Intent intent) {
54        Bundle extras = intent.getExtras();
55        boolean configured = extras.getBoolean(UsbManager.USB_CONFIGURED);
56        boolean connected = extras.getBoolean(UsbManager.USB_CONNECTED);
57        boolean mtpEnabled = extras.getBoolean(UsbManager.USB_FUNCTION_MTP);
58        boolean ptpEnabled = extras.getBoolean(UsbManager.USB_FUNCTION_PTP);
59        boolean unlocked = extras.getBoolean(UsbManager.USB_DATA_UNLOCKED);
60        boolean configChanged = extras.getBoolean(UsbManager.USB_CONFIG_CHANGED);
61
62        if ((configChanged || (connected && !configured)) && (mtpEnabled || ptpEnabled)) {
63            MtpServer.configure(ptpEnabled);
64            // tell MediaProvider MTP is configured so it can bind to the service
65            context.getContentResolver().insert(Uri.parse(
66                    "content://media/none/mtp_connected"), null);
67        } else if (configured && (mtpEnabled || ptpEnabled)) {
68            intent = new Intent(context, MtpService.class);
69            intent.putExtra(UsbManager.USB_DATA_UNLOCKED, unlocked);
70            if (ptpEnabled) {
71                intent.putExtra(UsbManager.USB_FUNCTION_PTP, true);
72            }
73            if (DEBUG) { Log.d(TAG, "handleUsbState startService"); }
74            context.startService(intent);
75        } else if (!connected || !(mtpEnabled || ptpEnabled)) {
76            // Only unbind if disconnected or disabled.
77            boolean status = context.stopService(new Intent(context, MtpService.class));
78            if (DEBUG) { Log.d(TAG, "handleUsbState stopService status=" + status); }
79            // tell MediaProvider MTP is disconnected so it can unbind from the service
80            context.getContentResolver().delete(Uri.parse(
81                    "content://media/none/mtp_connected"), null, null);
82        }
83    }
84}
85