1/*
2 * Copyright (C) 2011 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.systemui.usb;
18
19import android.app.Activity;
20import android.app.AlertDialog;
21import android.app.PendingIntent;
22import android.content.Context;
23import android.content.DialogInterface;
24import android.content.Intent;
25import android.content.pm.ApplicationInfo;
26import android.content.pm.PackageManager;
27import android.hardware.usb.IUsbManager;
28import android.hardware.usb.UsbDevice;
29import android.hardware.usb.UsbAccessory;
30import android.hardware.usb.UsbManager;
31import android.os.Bundle;
32import android.os.IBinder;
33import android.os.RemoteException;
34import android.os.ServiceManager;
35import android.os.UserHandle;
36import android.util.Log;
37import android.view.LayoutInflater;
38import android.view.View;
39import android.widget.CheckBox;
40import android.widget.CompoundButton;
41import android.widget.TextView;
42
43import com.android.internal.app.AlertActivity;
44import com.android.internal.app.AlertController;
45
46import com.android.systemui.R;
47
48public class UsbPermissionActivity extends AlertActivity
49        implements DialogInterface.OnClickListener, CheckBox.OnCheckedChangeListener {
50
51    private static final String TAG = "UsbPermissionActivity";
52
53    private CheckBox mAlwaysUse;
54    private TextView mClearDefaultHint;
55    private UsbDevice mDevice;
56    private UsbAccessory mAccessory;
57    private PendingIntent mPendingIntent;
58    private String mPackageName;
59    private int mUid;
60    private boolean mPermissionGranted;
61    private UsbDisconnectedReceiver mDisconnectedReceiver;
62
63    @Override
64    public void onCreate(Bundle icicle) {
65        super.onCreate(icicle);
66
67       Intent intent = getIntent();
68        mDevice = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
69        mAccessory = (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
70        mPendingIntent = (PendingIntent)intent.getParcelableExtra(Intent.EXTRA_INTENT);
71        mUid = intent.getIntExtra(Intent.EXTRA_UID, -1);
72        mPackageName = intent.getStringExtra("package");
73
74        PackageManager packageManager = getPackageManager();
75        ApplicationInfo aInfo;
76        try {
77            aInfo = packageManager.getApplicationInfo(mPackageName, 0);
78        } catch (PackageManager.NameNotFoundException e) {
79            Log.e(TAG, "unable to look up package name", e);
80            finish();
81            return;
82        }
83        String appName = aInfo.loadLabel(packageManager).toString();
84
85        final AlertController.AlertParams ap = mAlertParams;
86        ap.mIcon = aInfo.loadIcon(packageManager);
87        ap.mTitle = appName;
88        if (mDevice == null) {
89            ap.mMessage = getString(R.string.usb_accessory_permission_prompt, appName);
90            mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mAccessory);
91        } else {
92            ap.mMessage = getString(R.string.usb_device_permission_prompt, appName);
93            mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mDevice);
94        }
95        ap.mPositiveButtonText = getString(android.R.string.ok);
96        ap.mNegativeButtonText = getString(android.R.string.cancel);
97        ap.mPositiveButtonListener = this;
98        ap.mNegativeButtonListener = this;
99
100        // add "always use" checkbox
101        LayoutInflater inflater = (LayoutInflater)getSystemService(
102                Context.LAYOUT_INFLATER_SERVICE);
103        ap.mView = inflater.inflate(com.android.internal.R.layout.always_use_checkbox, null);
104        mAlwaysUse = (CheckBox)ap.mView.findViewById(com.android.internal.R.id.alwaysUse);
105        if (mDevice == null) {
106            mAlwaysUse.setText(R.string.always_use_accessory);
107        } else {
108            mAlwaysUse.setText(R.string.always_use_device);
109        }
110        mAlwaysUse.setOnCheckedChangeListener(this);
111        mClearDefaultHint = (TextView)ap.mView.findViewById(
112                                                    com.android.internal.R.id.clearDefaultHint);
113        mClearDefaultHint.setVisibility(View.GONE);
114
115        setupAlert();
116
117    }
118
119    @Override
120    public void onDestroy() {
121        IBinder b = ServiceManager.getService(USB_SERVICE);
122        IUsbManager service = IUsbManager.Stub.asInterface(b);
123
124        // send response via pending intent
125        Intent intent = new Intent();
126        try {
127            if (mDevice != null) {
128                intent.putExtra(UsbManager.EXTRA_DEVICE, mDevice);
129                if (mPermissionGranted) {
130                    service.grantDevicePermission(mDevice, mUid);
131                    if (mAlwaysUse.isChecked()) {
132                        final int userId = UserHandle.getUserId(mUid);
133                        service.setDevicePackage(mDevice, mPackageName, userId);
134                    }
135                }
136            }
137            if (mAccessory != null) {
138                intent.putExtra(UsbManager.EXTRA_ACCESSORY, mAccessory);
139                if (mPermissionGranted) {
140                    service.grantAccessoryPermission(mAccessory, mUid);
141                    if (mAlwaysUse.isChecked()) {
142                        final int userId = UserHandle.getUserId(mUid);
143                        service.setAccessoryPackage(mAccessory, mPackageName, userId);
144                    }
145                }
146            }
147            intent.putExtra(UsbManager.EXTRA_PERMISSION_GRANTED, mPermissionGranted);
148            mPendingIntent.send(this, 0, intent);
149        } catch (PendingIntent.CanceledException e) {
150            Log.w(TAG, "PendingIntent was cancelled");
151        } catch (RemoteException e) {
152            Log.e(TAG, "IUsbService connection failed", e);
153        }
154
155        if (mDisconnectedReceiver != null) {
156            unregisterReceiver(mDisconnectedReceiver);
157        }
158        super.onDestroy();
159    }
160
161    public void onClick(DialogInterface dialog, int which) {
162        if (which == AlertDialog.BUTTON_POSITIVE) {
163            mPermissionGranted = true;
164        }
165        finish();
166    }
167
168    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
169        if (mClearDefaultHint == null) return;
170
171        if(isChecked) {
172            mClearDefaultHint.setVisibility(View.VISIBLE);
173        } else {
174            mClearDefaultHint.setVisibility(View.GONE);
175        }
176    }
177}
178