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