SendBug.java revision 8beb39758fe046fc19ebee7317949b9ba7ee97dd
18c658e058446ad69fb056b2160340d708582b9eeGuang Zhu/* 28c658e058446ad69fb056b2160340d708582b9eeGuang Zhu * Copyright (C) 2011 The Android Open Source Project 38c658e058446ad69fb056b2160340d708582b9eeGuang Zhu * 48c658e058446ad69fb056b2160340d708582b9eeGuang Zhu * Licensed under the Apache License, Version 2.0 (the "License"); 58c658e058446ad69fb056b2160340d708582b9eeGuang Zhu * you may not use this file except in compliance with the License. 68c658e058446ad69fb056b2160340d708582b9eeGuang Zhu * You may obtain a copy of the License at 78c658e058446ad69fb056b2160340d708582b9eeGuang Zhu * 88c658e058446ad69fb056b2160340d708582b9eeGuang Zhu * http://www.apache.org/licenses/LICENSE-2.0 98c658e058446ad69fb056b2160340d708582b9eeGuang Zhu * 108c658e058446ad69fb056b2160340d708582b9eeGuang Zhu * Unless required by applicable law or agreed to in writing, software 118c658e058446ad69fb056b2160340d708582b9eeGuang Zhu * distributed under the License is distributed on an "AS IS" BASIS, 128c658e058446ad69fb056b2160340d708582b9eeGuang Zhu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138c658e058446ad69fb056b2160340d708582b9eeGuang Zhu * See the License for the specific language governing permissions and 148c658e058446ad69fb056b2160340d708582b9eeGuang Zhu * limitations under the License. 158c658e058446ad69fb056b2160340d708582b9eeGuang Zhu */ 168c658e058446ad69fb056b2160340d708582b9eeGuang Zhupackage com.android.commands.sendbug; 178c658e058446ad69fb056b2160340d708582b9eeGuang Zhu 188c658e058446ad69fb056b2160340d708582b9eeGuang Zhuimport android.accounts.Account; 198c658e058446ad69fb056b2160340d708582b9eeGuang Zhuimport android.accounts.IAccountManager; 208c658e058446ad69fb056b2160340d708582b9eeGuang Zhuimport android.app.ActivityManagerNative; 218c658e058446ad69fb056b2160340d708582b9eeGuang Zhuimport android.app.IActivityManager; 228c658e058446ad69fb056b2160340d708582b9eeGuang Zhuimport android.content.Context; 238c658e058446ad69fb056b2160340d708582b9eeGuang Zhuimport android.content.Intent; 24d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhuimport android.content.pm.IPackageManager; 25d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhuimport android.content.pm.ResolveInfo; 268c658e058446ad69fb056b2160340d708582b9eeGuang Zhuimport android.net.Uri; 278c658e058446ad69fb056b2160340d708582b9eeGuang Zhuimport android.os.RemoteException; 288c658e058446ad69fb056b2160340d708582b9eeGuang Zhuimport android.os.ServiceManager; 298c658e058446ad69fb056b2160340d708582b9eeGuang Zhuimport android.os.SystemProperties; 308c658e058446ad69fb056b2160340d708582b9eeGuang Zhu 318c658e058446ad69fb056b2160340d708582b9eeGuang Zhuimport java.io.File; 3201cef7d875c77ad5efed9e73d0e3d60a258f79deAlon Albertimport java.util.ArrayList; 33d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhuimport java.util.List; 348c658e058446ad69fb056b2160340d708582b9eeGuang Zhu 358c658e058446ad69fb056b2160340d708582b9eeGuang Zhupublic class SendBug { 368c658e058446ad69fb056b2160340d708582b9eeGuang Zhu 378c658e058446ad69fb056b2160340d708582b9eeGuang Zhu private static final String GOOGLE_ACCOUNT_TYPE = "com.google"; 388c658e058446ad69fb056b2160340d708582b9eeGuang Zhu private static final String EMAIL_ACCOUNT_TYPE = "com.android.email"; 39d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu private static final String SEND_BUG_INTENT_ACTION = "android.testing.SEND_BUG"; 408c658e058446ad69fb056b2160340d708582b9eeGuang Zhu 418c658e058446ad69fb056b2160340d708582b9eeGuang Zhu public static void main(String[] args) { 428beb39758fe046fc19ebee7317949b9ba7ee97ddGuang Zhu if (args.length == 1) { 438c658e058446ad69fb056b2160340d708582b9eeGuang Zhu new SendBug().run(args[0]); 448beb39758fe046fc19ebee7317949b9ba7ee97ddGuang Zhu } else if (args.length == 2) { 458beb39758fe046fc19ebee7317949b9ba7ee97ddGuang Zhu new SendBug().run(args[0], args[1]); 468c658e058446ad69fb056b2160340d708582b9eeGuang Zhu } 478c658e058446ad69fb056b2160340d708582b9eeGuang Zhu } 488c658e058446ad69fb056b2160340d708582b9eeGuang Zhu 498c658e058446ad69fb056b2160340d708582b9eeGuang Zhu private void run(String bugreportPath) { 508beb39758fe046fc19ebee7317949b9ba7ee97ddGuang Zhu run(bugreportPath, null); 518beb39758fe046fc19ebee7317949b9ba7ee97ddGuang Zhu } 528beb39758fe046fc19ebee7317949b9ba7ee97ddGuang Zhu 538beb39758fe046fc19ebee7317949b9ba7ee97ddGuang Zhu private void run(String bugreportPath, String screenShotPath) { 5401cef7d875c77ad5efed9e73d0e3d60a258f79deAlon Albert final File bugreport = new File(bugreportPath); 558beb39758fe046fc19ebee7317949b9ba7ee97ddGuang Zhu File screenShot = null; 568beb39758fe046fc19ebee7317949b9ba7ee97ddGuang Zhu if (screenShotPath != null) { 578beb39758fe046fc19ebee7317949b9ba7ee97ddGuang Zhu screenShot = new File(screenShotPath); 588beb39758fe046fc19ebee7317949b9ba7ee97ddGuang Zhu if (!screenShot.exists()) { 598beb39758fe046fc19ebee7317949b9ba7ee97ddGuang Zhu // screen shot probably failed 608beb39758fe046fc19ebee7317949b9ba7ee97ddGuang Zhu screenShot = null; 618beb39758fe046fc19ebee7317949b9ba7ee97ddGuang Zhu } 628beb39758fe046fc19ebee7317949b9ba7ee97ddGuang Zhu } 638c658e058446ad69fb056b2160340d708582b9eeGuang Zhu if (bugreport.exists()) { 6401cef7d875c77ad5efed9e73d0e3d60a258f79deAlon Albert final Uri bugreportUri = Uri.fromFile(bugreport); 6501cef7d875c77ad5efed9e73d0e3d60a258f79deAlon Albert // todo (aalbert): investigate adding a screenshot to BugReporter 66d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu Intent intent = tryBugReporter(bugreportUri); 67d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu if (intent == null) { 688beb39758fe046fc19ebee7317949b9ba7ee97ddGuang Zhu final Uri screenshotUri = screenShot != null 698beb39758fe046fc19ebee7317949b9ba7ee97ddGuang Zhu ? Uri.fromFile(screenShot) : null; 7001cef7d875c77ad5efed9e73d0e3d60a258f79deAlon Albert intent = getSendMailIntent(bugreportUri, screenshotUri); 718c658e058446ad69fb056b2160340d708582b9eeGuang Zhu } 7201cef7d875c77ad5efed9e73d0e3d60a258f79deAlon Albert final IActivityManager mAm = ActivityManagerNative.getDefault(); 738c658e058446ad69fb056b2160340d708582b9eeGuang Zhu try { 748c658e058446ad69fb056b2160340d708582b9eeGuang Zhu mAm.startActivity(null, intent, intent.getType(), null, 0, null, null, 0, false, 7543350373779c519e0fda89f9c5c899af1a42e8d1Dianne Hackborn false, null, null, false); 768c658e058446ad69fb056b2160340d708582b9eeGuang Zhu } catch (RemoteException e) { 7701cef7d875c77ad5efed9e73d0e3d60a258f79deAlon Albert // ignore 788c658e058446ad69fb056b2160340d708582b9eeGuang Zhu } 798c658e058446ad69fb056b2160340d708582b9eeGuang Zhu } 808c658e058446ad69fb056b2160340d708582b9eeGuang Zhu } 818c658e058446ad69fb056b2160340d708582b9eeGuang Zhu 82d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu private Intent tryBugReporter(Uri bugreportUri) { 8301cef7d875c77ad5efed9e73d0e3d60a258f79deAlon Albert final Intent intent = new Intent(SEND_BUG_INTENT_ACTION); 84d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu intent.setData(bugreportUri); 8501cef7d875c77ad5efed9e73d0e3d60a258f79deAlon Albert final IPackageManager mPm = IPackageManager.Stub.asInterface( 86d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu ServiceManager.getService("package")); 87d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu if (mPm != null) { 8801cef7d875c77ad5efed9e73d0e3d60a258f79deAlon Albert final List<ResolveInfo> results; 89d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu try { 90d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu results = mPm.queryIntentActivities(intent, null, 0); 91d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu } catch (RemoteException e) { 92d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu return null; 93d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu } 94d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu if (results != null && results.size() > 0) { 9501cef7d875c77ad5efed9e73d0e3d60a258f79deAlon Albert final ResolveInfo info = results.get(0); 96d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 97d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu intent.setClassName(info.activityInfo.applicationInfo.packageName, 98d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu info.activityInfo.name); 99d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu return intent; 100d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu } else { 101d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu return null; 102d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu } 103d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu } 104d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu return null; 105d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu } 106d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu 10701cef7d875c77ad5efed9e73d0e3d60a258f79deAlon Albert private Intent getSendMailIntent(Uri bugreportUri, Uri screenshotUri) { 10801cef7d875c77ad5efed9e73d0e3d60a258f79deAlon Albert final Account sendToAccount = findSendToAccount(); 10901cef7d875c77ad5efed9e73d0e3d60a258f79deAlon Albert final Intent intent = new Intent(Intent.ACTION_SEND); 110d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 111d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu intent.setType("application/octet-stream"); 112d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu intent.putExtra("subject", bugreportUri.getLastPathSegment()); 11301cef7d875c77ad5efed9e73d0e3d60a258f79deAlon Albert final StringBuilder sb = new StringBuilder(); 114d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu sb.append(SystemProperties.get("ro.build.description")); 115d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu sb.append("\n(Sent from BugMailer)"); 116d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu intent.putExtra("body", sb.toString()); 11701cef7d875c77ad5efed9e73d0e3d60a258f79deAlon Albert if (screenshotUri != null) { 11801cef7d875c77ad5efed9e73d0e3d60a258f79deAlon Albert final ArrayList<Uri> attachments = new ArrayList<Uri>(); 11901cef7d875c77ad5efed9e73d0e3d60a258f79deAlon Albert attachments.add(bugreportUri); 12001cef7d875c77ad5efed9e73d0e3d60a258f79deAlon Albert attachments.add(screenshotUri); 12101cef7d875c77ad5efed9e73d0e3d60a258f79deAlon Albert intent.setAction(Intent.ACTION_SEND_MULTIPLE); 12201cef7d875c77ad5efed9e73d0e3d60a258f79deAlon Albert intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, attachments); 12301cef7d875c77ad5efed9e73d0e3d60a258f79deAlon Albert } else { 12401cef7d875c77ad5efed9e73d0e3d60a258f79deAlon Albert intent.putExtra(Intent.EXTRA_STREAM, bugreportUri); 12501cef7d875c77ad5efed9e73d0e3d60a258f79deAlon Albert } 126d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu if (sendToAccount != null) { 127d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu intent.putExtra("to", sendToAccount.name); 128d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu } 129d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu return intent; 130d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu } 131d4cd3249e37e5689fc4a8c2858351ec9bebb467cGuang Zhu 1328c658e058446ad69fb056b2160340d708582b9eeGuang Zhu private Account findSendToAccount() { 13301cef7d875c77ad5efed9e73d0e3d60a258f79deAlon Albert final IAccountManager accountManager = IAccountManager.Stub.asInterface(ServiceManager 1348c658e058446ad69fb056b2160340d708582b9eeGuang Zhu .getService(Context.ACCOUNT_SERVICE)); 1358c658e058446ad69fb056b2160340d708582b9eeGuang Zhu Account[] accounts = null; 1368c658e058446ad69fb056b2160340d708582b9eeGuang Zhu Account foundAccount = null; 1378c658e058446ad69fb056b2160340d708582b9eeGuang Zhu try { 1388c658e058446ad69fb056b2160340d708582b9eeGuang Zhu accounts = accountManager.getAccounts(null); 1398c658e058446ad69fb056b2160340d708582b9eeGuang Zhu } catch (RemoteException e) { 14001cef7d875c77ad5efed9e73d0e3d60a258f79deAlon Albert // ignore 1418c658e058446ad69fb056b2160340d708582b9eeGuang Zhu } 1428c658e058446ad69fb056b2160340d708582b9eeGuang Zhu if (accounts != null) { 1438c658e058446ad69fb056b2160340d708582b9eeGuang Zhu for (Account account : accounts) { 1448c658e058446ad69fb056b2160340d708582b9eeGuang Zhu if (GOOGLE_ACCOUNT_TYPE.equals(account.type)) { 1458c658e058446ad69fb056b2160340d708582b9eeGuang Zhu // return first gmail account found 1468c658e058446ad69fb056b2160340d708582b9eeGuang Zhu return account; 1478c658e058446ad69fb056b2160340d708582b9eeGuang Zhu } else if (EMAIL_ACCOUNT_TYPE.equals(account.type)) { 1488c658e058446ad69fb056b2160340d708582b9eeGuang Zhu // keep regular email account for now in case there are gmail accounts 1498c658e058446ad69fb056b2160340d708582b9eeGuang Zhu // found later 1508c658e058446ad69fb056b2160340d708582b9eeGuang Zhu foundAccount = account; 1518c658e058446ad69fb056b2160340d708582b9eeGuang Zhu } 1528c658e058446ad69fb056b2160340d708582b9eeGuang Zhu } 1538c658e058446ad69fb056b2160340d708582b9eeGuang Zhu } 1548c658e058446ad69fb056b2160340d708582b9eeGuang Zhu return foundAccount; 1558c658e058446ad69fb056b2160340d708582b9eeGuang Zhu } 15601cef7d875c77ad5efed9e73d0e3d60a258f79deAlon Albert 1578c658e058446ad69fb056b2160340d708582b9eeGuang Zhu} 158