SendBug.java revision 46899d1b5d606e9349a40079b60034e3cf6eaafb
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 */ 16package com.android.commands.sendbug; 17 18import android.accounts.Account; 19import android.accounts.IAccountManager; 20import android.app.ActivityManagerNative; 21import android.app.IActivityManager; 22import android.content.Context; 23import android.content.Intent; 24import android.content.pm.IPackageManager; 25import android.content.pm.ResolveInfo; 26import android.net.Uri; 27import android.os.RemoteException; 28import android.os.ServiceManager; 29import android.os.SystemProperties; 30import android.util.Log; 31 32import java.io.File; 33import java.util.ArrayList; 34import java.util.List; 35import java.util.regex.Pattern; 36 37public class SendBug { 38 39 private static final String LOG_TAG = SendBug.class.getSimpleName(); 40 private static final Pattern EMAIL_REGEX = Pattern.compile( 41 "^[\\w.%+-]+@[\\w.-]+\\.[a-zA-Z]{2,}$"); 42 private static final String SEND_BUG_INTENT_ACTION = "android.testing.SEND_BUG"; 43 44 public static void main(String[] args) { 45 if (args.length == 1) { 46 new SendBug().run(args[0]); 47 } else if (args.length == 2) { 48 new SendBug().run(args[0], args[1]); 49 } 50 } 51 52 private void run(String bugreportPath) { 53 run(bugreportPath, null); 54 } 55 56 private void run(String bugreportPath, String screenShotPath) { 57 final File bugreport = new File(bugreportPath); 58 File screenShot = null; 59 if (screenShotPath != null) { 60 screenShot = new File(screenShotPath); 61 } 62 final Uri bugreportUri = Uri.fromFile(bugreport); 63 // todo (aalbert): investigate adding a screenshot to BugReporter 64 Intent intent = tryBugReporter(bugreportUri); 65 if (intent == null) { 66 final Uri screenshotUri = screenShot != null 67 ? Uri.fromFile(screenShot) : null; 68 intent = getSendMailIntent(bugreportUri, screenshotUri); 69 } 70 if (intent != null) { 71 final IActivityManager mAm = ActivityManagerNative.getDefault(); 72 try { 73 mAm.startActivity(null, intent, intent.getType(), null, null, 0, 0, 74 null, null, null); 75 } catch (RemoteException e) { 76 // ignore 77 } 78 } else { 79 Log.w(LOG_TAG, "Cannot find account to send bugreport, local path: " 80 + bugreportPath); 81 } 82 } 83 84 private Intent tryBugReporter(Uri bugreportUri) { 85 final Intent intent = new Intent(SEND_BUG_INTENT_ACTION); 86 intent.setData(bugreportUri); 87 final IPackageManager mPm = IPackageManager.Stub.asInterface( 88 ServiceManager.getService("package")); 89 if (mPm != null) { 90 final List<ResolveInfo> results; 91 try { 92 results = mPm.queryIntentActivities(intent, null, 0, 0); 93 } catch (RemoteException e) { 94 return null; 95 } 96 if (results != null && results.size() > 0) { 97 final ResolveInfo info = results.get(0); 98 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 99 intent.setClassName(info.activityInfo.applicationInfo.packageName, 100 info.activityInfo.name); 101 return intent; 102 } else { 103 return null; 104 } 105 } 106 return null; 107 } 108 109 private Intent getSendMailIntent(Uri bugreportUri, Uri screenshotUri) { 110 final Account sendToAccount = findSendToAccount(); 111 final Intent intent = new Intent(Intent.ACTION_SEND); 112 intent.addCategory(Intent.CATEGORY_DEFAULT); 113 intent.setType("application/octet-stream"); 114 intent.putExtra(Intent.EXTRA_SUBJECT, bugreportUri.getLastPathSegment()); 115 final StringBuilder sb = new StringBuilder(); 116 sb.append(SystemProperties.get("ro.build.description")); 117 sb.append("\n(Sent from BugMailer)"); 118 intent.putExtra(Intent.EXTRA_TEXT, (CharSequence)sb); 119 if (screenshotUri != null) { 120 final ArrayList<Uri> attachments = new ArrayList<Uri>(); 121 attachments.add(bugreportUri); 122 attachments.add(screenshotUri); 123 intent.setAction(Intent.ACTION_SEND_MULTIPLE); 124 intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, attachments); 125 } else { 126 intent.putExtra(Intent.EXTRA_STREAM, bugreportUri); 127 } 128 if (sendToAccount != null) { 129 intent.putExtra(Intent.EXTRA_EMAIL, new String[]{sendToAccount.name}); 130 return intent; 131 } 132 return null; 133 } 134 135 private Account findSendToAccount() { 136 final IAccountManager accountManager = IAccountManager.Stub.asInterface(ServiceManager 137 .getService(Context.ACCOUNT_SERVICE)); 138 Account[] accounts = null; 139 Account foundAccount = null; 140 String preferredDomain = SystemProperties.get("sendbug.preferred.domain"); 141 if (!preferredDomain.startsWith("@")) { 142 preferredDomain = "@" + preferredDomain; 143 } 144 try { 145 accounts = accountManager.getAccounts(null); 146 } catch (RemoteException e) { 147 // ignore 148 } 149 if (accounts != null) { 150 for (Account account : accounts) { 151 if (EMAIL_REGEX.matcher(account.name).matches()) { 152 if (!preferredDomain.isEmpty()) { 153 // if we have a preferred domain and it matches, return; otherwise keep 154 // looking 155 if (account.name.endsWith(preferredDomain)) { 156 return account; 157 } else { 158 foundAccount = account; 159 } 160 // if we don't have a preferred domain, just return since it looks like 161 // an email address 162 } else { 163 return account; 164 } 165 } 166 } 167 } 168 return foundAccount; 169 } 170 171} 172