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 package com.android.commands.sendbug; 17 18 import android.accounts.Account; 19 import android.accounts.IAccountManager; 20 import android.app.ActivityManagerNative; 21 import android.app.IActivityManager; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.content.pm.IPackageManager; 25 import android.content.pm.ResolveInfo; 26 import android.net.Uri; 27 import android.os.RemoteException; 28 import android.os.ServiceManager; 29 import android.os.SystemProperties; 30 31 import java.io.File; 32 import java.util.ArrayList; 33 import java.util.List; 34 35 public class SendBug { 36 37 private static final String GOOGLE_ACCOUNT_TYPE = "com.google"; 38 private static final String EMAIL_ACCOUNT_TYPE = "com.android.email"; 39 private static final String SEND_BUG_INTENT_ACTION = "android.testing.SEND_BUG"; 40 41 public static void main(String[] args) { 42 if (args.length == 1) { 43 new SendBug().run(args[0]); 44 } else if (args.length == 2) { 45 new SendBug().run(args[0], args[1]); 46 } 47 } 48 49 private void run(String bugreportPath) { 50 run(bugreportPath, null); 51 } 52 53 private void run(String bugreportPath, String screenShotPath) { 54 final File bugreport = new File(bugreportPath); 55 File screenShot = null; 56 if (screenShotPath != null) { 57 screenShot = new File(screenShotPath); 58 if (!screenShot.exists()) { 59 // screen shot probably failed 60 screenShot = null; 61 } 62 } 63 if (bugreport.exists()) { 64 final Uri bugreportUri = Uri.fromFile(bugreport); 65 // todo (aalbert): investigate adding a screenshot to BugReporter 66 Intent intent = tryBugReporter(bugreportUri); 67 if (intent == null) { 68 final Uri screenshotUri = screenShot != null 69 ? Uri.fromFile(screenShot) : null; 70 intent = getSendMailIntent(bugreportUri, screenshotUri); 71 } 72 final IActivityManager mAm = ActivityManagerNative.getDefault(); 73 try { 74 mAm.startActivity(null, intent, intent.getType(), null, 0, null, null, 0, false, 75 false, null, null, false); 76 } catch (RemoteException e) { 77 // ignore 78 } 79 } 80 } 81 82 private Intent tryBugReporter(Uri bugreportUri) { 83 final Intent intent = new Intent(SEND_BUG_INTENT_ACTION); 84 intent.setData(bugreportUri); 85 final IPackageManager mPm = IPackageManager.Stub.asInterface( 86 ServiceManager.getService("package")); 87 if (mPm != null) { 88 final List<ResolveInfo> results; 89 try { 90 results = mPm.queryIntentActivities(intent, null, 0); 91 } catch (RemoteException e) { 92 return null; 93 } 94 if (results != null && results.size() > 0) { 95 final ResolveInfo info = results.get(0); 96 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 97 intent.setClassName(info.activityInfo.applicationInfo.packageName, 98 info.activityInfo.name); 99 return intent; 100 } else { 101 return null; 102 } 103 } 104 return null; 105 } 106 107 private Intent getSendMailIntent(Uri bugreportUri, Uri screenshotUri) { 108 final Account sendToAccount = findSendToAccount(); 109 final Intent intent = new Intent(Intent.ACTION_SEND); 110 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 111 intent.setType("application/octet-stream"); 112 intent.putExtra("subject", bugreportUri.getLastPathSegment()); 113 final StringBuilder sb = new StringBuilder(); 114 sb.append(SystemProperties.get("ro.build.description")); 115 sb.append("\n(Sent from BugMailer)"); 116 intent.putExtra("body", sb.toString()); 117 if (screenshotUri != null) { 118 final ArrayList<Uri> attachments = new ArrayList<Uri>(); 119 attachments.add(bugreportUri); 120 attachments.add(screenshotUri); 121 intent.setAction(Intent.ACTION_SEND_MULTIPLE); 122 intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, attachments); 123 } else { 124 intent.putExtra(Intent.EXTRA_STREAM, bugreportUri); 125 } 126 if (sendToAccount != null) { 127 intent.putExtra("to", sendToAccount.name); 128 } 129 return intent; 130 } 131 132 private Account findSendToAccount() { 133 final IAccountManager accountManager = IAccountManager.Stub.asInterface(ServiceManager 134 .getService(Context.ACCOUNT_SERVICE)); 135 Account[] accounts = null; 136 Account foundAccount = null; 137 try { 138 accounts = accountManager.getAccounts(null); 139 } catch (RemoteException e) { 140 // ignore 141 } 142 if (accounts != null) { 143 for (Account account : accounts) { 144 if (GOOGLE_ACCOUNT_TYPE.equals(account.type)) { 145 // return first gmail account found 146 return account; 147 } else if (EMAIL_ACCOUNT_TYPE.equals(account.type)) { 148 // keep regular email account for now in case there are gmail accounts 149 // found later 150 foundAccount = account; 151 } 152 } 153 } 154 return foundAccount; 155 } 156 157 } 158