• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
20 
21 import android.content.ActivityNotFoundException;
22 import android.content.ComponentName;
23 import android.content.Intent;
24 import android.content.pm.ResolveInfo;
25 import android.hardware.usb.IUsbManager;
26 import android.hardware.usb.UsbAccessory;
27 import android.hardware.usb.UsbDevice;
28 import android.hardware.usb.UsbManager;
29 import android.os.Bundle;
30 import android.os.IBinder;
31 import android.os.Parcelable;
32 import android.os.RemoteException;
33 import android.os.ServiceManager;
34 import android.os.UserHandle;
35 import android.util.Log;
36 import android.view.WindowManager;
37 import android.widget.CheckBox;
38 
39 import com.android.internal.app.ResolverActivity;
40 import com.android.internal.app.chooser.TargetInfo;
41 import com.android.systemui.res.R;
42 
43 import java.util.ArrayList;
44 import java.util.Iterator;
45 
46 /* Activity for choosing an application for a USB device or accessory */
47 public class UsbResolverActivity extends ResolverActivity {
48     public static final String TAG = "UsbResolverActivity";
49     public static final String EXTRA_RESOLVE_INFOS = "rlist";
50     public static final String EXTRA_RESOLVE_INFO = "rinfo";
51 
52     private UsbDevice mDevice;
53     private UsbAccessory mAccessory;
54     private UsbDisconnectedReceiver mDisconnectedReceiver;
55 
56     /** Resolve info that switches user profiles */
57     private ResolveInfo mForwardResolveInfo;
58 
59     /** The intent that should be started when the profile is switched */
60     private Intent mOtherProfileIntent;
61 
62     @Override
onCreate(Bundle savedInstanceState)63     protected void onCreate(Bundle savedInstanceState) {
64         getWindow().addSystemFlags(
65                 WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
66         Intent intent = getIntent();
67         Parcelable targetParcelable = intent.getParcelableExtra(Intent.EXTRA_INTENT);
68         if (!(targetParcelable instanceof Intent)) {
69             super_onCreate(savedInstanceState);
70             Log.w("UsbResolverActivity", "Target is not an intent: " + targetParcelable);
71             finish();
72             return;
73         }
74         Intent target = (Intent)targetParcelable;
75         ArrayList<ResolveInfo> rList = new ArrayList<>(
76                 intent.getParcelableArrayListExtra(EXTRA_RESOLVE_INFOS));
77 
78         // The rList contains the apps for all profiles of this users. Separate those. We currently
79         // only support two profiles, i.e. one forward resolve info.
80         ArrayList<ResolveInfo> rListOtherProfile = new ArrayList<>();
81         mForwardResolveInfo = null;
82         for (Iterator<ResolveInfo> iterator = rList.iterator(); iterator.hasNext();) {
83             ResolveInfo ri = iterator.next();
84 
85             if (ri.getComponentInfo().name.equals(FORWARD_INTENT_TO_MANAGED_PROFILE)) {
86                 mForwardResolveInfo = ri;
87             } else if (UserHandle.getUserId(ri.activityInfo.applicationInfo.uid)
88                     != UserHandle.myUserId()) {
89                 iterator.remove();
90                 rListOtherProfile.add(ri);
91             }
92         }
93 
94         mDevice = (UsbDevice)target.getParcelableExtra(UsbManager.EXTRA_DEVICE);
95         boolean hasAudioCapture = false;
96         if (mDevice != null) {
97             mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mDevice);
98             hasAudioCapture = mDevice.getHasAudioCapture();
99         } else {
100             mAccessory = (UsbAccessory)target.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
101             if (mAccessory == null) {
102                 super_onCreate(savedInstanceState);
103                 Log.e(TAG, "no device or accessory");
104                 finish();
105                 return;
106             }
107             mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mAccessory);
108         }
109 
110         // Create intent that will be used when switching to other profile. Emulate the behavior of
111         // UsbProfileGroupSettingsManager#resolveActivity
112         if (mForwardResolveInfo != null) {
113             if (rListOtherProfile.size() > 1) {
114                 mOtherProfileIntent = new Intent(intent);
115                 mOtherProfileIntent.putParcelableArrayListExtra(EXTRA_RESOLVE_INFOS,
116                         rListOtherProfile);
117             } else {
118                 mOtherProfileIntent = new Intent();
119                 mOtherProfileIntent.setComponent(ComponentName.unflattenFromString(
120                         this.getResources().getString(
121                                 com.android.internal.R.string.config_usbConfirmActivity)));
122                 mOtherProfileIntent.putExtra(EXTRA_RESOLVE_INFO, rListOtherProfile.get(0));
123 
124                 if (mDevice != null) {
125                     mOtherProfileIntent.putExtra(UsbManager.EXTRA_DEVICE, mDevice);
126                 }
127 
128                 if (mAccessory != null) {
129                     mOtherProfileIntent.putExtra(UsbManager.EXTRA_ACCESSORY, mAccessory);
130                 }
131             }
132         }
133         getIntent().putExtra(
134                 ResolverActivity.EXTRA_IS_AUDIO_CAPTURE_DEVICE, hasAudioCapture);
135 
136         CharSequence title = getResources().getText(com.android.internal.R.string.chooseUsbActivity);
137         super.onCreate(savedInstanceState, target, title, null, rList, true);
138 
139         CheckBox alwaysUse = (CheckBox)findViewById(com.android.internal.R.id.alwaysUse);
140         if (alwaysUse != null) {
141             if (mDevice == null) {
142                 alwaysUse.setText(R.string.always_use_accessory);
143             } else {
144                 alwaysUse.setText(R.string.always_use_device);
145             }
146         }
147     }
148 
149     @Override
onDestroy()150     protected void onDestroy() {
151         if (mDisconnectedReceiver != null) {
152             unregisterReceiver(mDisconnectedReceiver);
153         }
154         super.onDestroy();
155     }
156 
157     @Override
onTargetSelected(TargetInfo target, boolean alwaysCheck)158     protected boolean onTargetSelected(TargetInfo target, boolean alwaysCheck) {
159         final ResolveInfo ri = target.getResolveInfo();
160         if (ri == mForwardResolveInfo) {
161             startActivityAsUser(mOtherProfileIntent, null,
162                     UserHandle.of(mForwardResolveInfo.targetUserId));
163             return true;
164         }
165 
166         try {
167             IBinder b = ServiceManager.getService(USB_SERVICE);
168             IUsbManager service = IUsbManager.Stub.asInterface(b);
169             final int uid = ri.activityInfo.applicationInfo.uid;
170             final int userId = UserHandle.myUserId();
171 
172             if (mDevice != null) {
173                 // grant permission for the device
174                 service.grantDevicePermission(mDevice, uid);
175                 // set or clear default setting
176                 if (alwaysCheck) {
177                     service.setDevicePackage(mDevice, ri.activityInfo.packageName, userId);
178                 } else {
179                     service.setDevicePackage(mDevice, null, userId);
180                 }
181             } else if (mAccessory != null) {
182                 // grant permission for the accessory
183                 service.grantAccessoryPermission(mAccessory, uid);
184                 // set or clear default setting
185                 if (alwaysCheck) {
186                     service.setAccessoryPackage(mAccessory, ri.activityInfo.packageName, userId);
187                 } else {
188                     service.setAccessoryPackage(mAccessory, null, userId);
189                 }
190             }
191 
192             try {
193                 target.startAsUser(this, null, UserHandle.of(userId));
194             } catch (ActivityNotFoundException e) {
195                 Log.e(TAG, "startActivity failed", e);
196             }
197         } catch (RemoteException e) {
198             Log.e(TAG, "onIntentSelected failed", e);
199         }
200         return true;
201     }
202 
203     @Override
shouldShowTabs()204     protected boolean shouldShowTabs() {
205         return false;
206     }
207 }
208