UsbModeChooserActivity.java revision 9e9e63b7b3b31fcae7242eb07f528487e0913402
1/*
2 * Copyright (C) 2015 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.settings.deviceinfo;
18
19import android.annotation.Nullable;
20import android.app.Activity;
21import android.app.ActivityManager;
22import android.app.AlertDialog;
23import android.content.BroadcastReceiver;
24import android.content.Context;
25import android.content.DialogInterface;
26import android.content.Intent;
27import android.content.IntentFilter;
28import android.graphics.drawable.Drawable;
29import android.graphics.PorterDuff;
30import android.hardware.usb.UsbManager;
31import android.os.Bundle;
32import android.os.UserHandle;
33import android.os.UserManager;
34import android.view.LayoutInflater;
35import android.view.View;
36import android.view.View.OnClickListener;
37import android.widget.Checkable;
38import android.widget.LinearLayout;
39import android.widget.TextView;
40
41import com.android.settings.R;
42import com.android.settingslib.RestrictedLockUtils;
43
44import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
45
46/**
47 * UI for the USB chooser dialog.
48 *
49 */
50public class UsbModeChooserActivity extends Activity {
51
52    public static final int[] DEFAULT_MODES = {
53        UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_NONE,
54        UsbBackend.MODE_POWER_SOURCE | UsbBackend.MODE_DATA_NONE,
55        UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_MTP,
56        UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_PTP,
57        UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_MIDI
58    };
59
60    private UsbBackend mBackend;
61    private AlertDialog mDialog;
62    private LayoutInflater mLayoutInflater;
63    private EnforcedAdmin mEnforcedAdmin;
64
65    private BroadcastReceiver mDisconnectedReceiver = new BroadcastReceiver() {
66        @Override
67        public void onReceive(Context context, Intent intent) {
68            String action = intent.getAction();
69            if (UsbManager.ACTION_USB_STATE.equals(action)) {
70                boolean connected = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false);
71                if (!connected) {
72                    mDialog.dismiss();
73                }
74            }
75        }
76    };
77
78    @Override
79    protected void onCreate(@Nullable Bundle savedInstanceState) {
80
81        super.onCreate(savedInstanceState);
82
83        mLayoutInflater = LayoutInflater.from(this);
84
85        mDialog = new AlertDialog.Builder(this)
86                .setTitle(R.string.usb_use)
87                .setView(R.layout.usb_dialog_container)
88                .setOnDismissListener(new DialogInterface.OnDismissListener() {
89                    @Override
90                    public void onDismiss(DialogInterface dialog) {
91                        finish();
92                    }
93                })
94                .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
95                    @Override
96                    public void onClick(DialogInterface dialog, int which) {
97                        finish();
98                    }
99                }).create();
100        mDialog.show();
101
102        LinearLayout container = (LinearLayout) mDialog.findViewById(R.id.container);
103
104        mEnforcedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(this,
105                UserManager.DISALLOW_USB_FILE_TRANSFER, UserHandle.myUserId());
106        mBackend = new UsbBackend(this);
107        int current = mBackend.getCurrentMode();
108        for (int i = 0; i < DEFAULT_MODES.length; i++) {
109            if (mBackend.isModeSupported(DEFAULT_MODES[i])
110                    && !mBackend.isModeDisallowedBySystem(DEFAULT_MODES[i])) {
111                inflateOption(DEFAULT_MODES[i], current == DEFAULT_MODES[i], container,
112                        mBackend.isModeDisallowed(DEFAULT_MODES[i]));
113            }
114        }
115    }
116
117    @Override
118    public void onStart() {
119        super.onStart();
120
121        IntentFilter filter = new IntentFilter(UsbManager.ACTION_USB_STATE);
122        registerReceiver(mDisconnectedReceiver, filter);
123    }
124
125    @Override
126    protected void onStop() {
127        unregisterReceiver(mDisconnectedReceiver);
128        super.onStop();
129    }
130
131    private void inflateOption(final int mode, boolean selected, LinearLayout container,
132            final boolean disallowedByAdmin) {
133        View v = mLayoutInflater.inflate(R.layout.radio_with_summary, container, false);
134
135        TextView titleView = (TextView) v.findViewById(android.R.id.title);
136        titleView.setText(getTitle(mode));
137        TextView summaryView = (TextView) v.findViewById(android.R.id.summary);
138        summaryView.setText(getSummary(mode));
139
140        if (disallowedByAdmin) {
141            if (mEnforcedAdmin != null) {
142                setDisabledByAdmin(titleView, summaryView);
143            } else {
144                return;
145            }
146        }
147
148        v.setOnClickListener(new OnClickListener() {
149            @Override
150            public void onClick(View v) {
151                if (disallowedByAdmin && mEnforcedAdmin != null) {
152                    RestrictedLockUtils.sendShowAdminSupportDetailsIntent(
153                            UsbModeChooserActivity.this, mEnforcedAdmin);
154                    return;
155                }
156                if (!ActivityManager.isUserAMonkey()) {
157                    mBackend.setMode(mode);
158                }
159                mDialog.dismiss();
160                finish();
161            }
162        });
163        ((Checkable) v).setChecked(selected);
164        container.addView(v);
165    }
166
167    private void setDisabledByAdmin(TextView titleView, TextView summaryView) {
168        if (mEnforcedAdmin != null) {
169            titleView.setEnabled(false);
170            summaryView.setEnabled(false);
171            RestrictedLockUtils.setTextViewPadlock(this,
172                    titleView, true /* showPadlock */);
173            Drawable[] compoundDrawables = titleView.getCompoundDrawablesRelative();
174            compoundDrawables[0 /* start */].mutate().setColorFilter(
175                    getColor(R.color.disabled_text_color), PorterDuff.Mode.MULTIPLY);
176        }
177    }
178
179    private static int getSummary(int mode) {
180        switch (mode) {
181            case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_NONE:
182                return R.string.usb_use_charging_only_desc;
183            case UsbBackend.MODE_POWER_SOURCE | UsbBackend.MODE_DATA_NONE:
184                return R.string.usb_use_power_only_desc;
185            case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_MTP:
186                return R.string.usb_use_file_transfers_desc;
187            case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_PTP:
188                return R.string.usb_use_photo_transfers_desc;
189            case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_MIDI:
190                return R.string.usb_use_MIDI_desc;
191        }
192        return 0;
193    }
194
195    private static int getTitle(int mode) {
196        switch (mode) {
197            case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_NONE:
198                return R.string.usb_use_charging_only;
199            case UsbBackend.MODE_POWER_SOURCE | UsbBackend.MODE_DATA_NONE:
200                return R.string.usb_use_power_only;
201            case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_MTP:
202                return R.string.usb_use_file_transfers;
203            case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_PTP:
204                return R.string.usb_use_photo_transfers;
205            case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_MIDI:
206                return R.string.usb_use_MIDI;
207        }
208        return 0;
209    }
210}
211