/* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.commands.sendbug; import android.accounts.Account; import android.accounts.IAccountManager; import android.app.ActivityManagerNative; import android.app.IActivityManager; import android.content.Context; import android.content.Intent; import android.content.pm.IPackageManager; import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; import android.os.UserHandle; import android.util.Log; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; public class SendBug { private static final String LOG_TAG = SendBug.class.getSimpleName(); private static final Pattern EMAIL_REGEX = Pattern.compile( "^[\\w.%+-]+@[\\w.-]+\\.[a-zA-Z]{2,}$"); private static final String SEND_BUG_INTENT_ACTION = "android.testing.SEND_BUG"; public static void main(String[] args) { if (args.length == 1) { new SendBug().run(args[0]); } else if (args.length == 2) { new SendBug().run(args[0], args[1]); } } private void run(String bugreportPath) { run(bugreportPath, null); } private void run(String bugreportPath, String screenShotPath) { final File bugreport = new File(bugreportPath); File screenShot = null; if (screenShotPath != null) { screenShot = new File(screenShotPath); } final Uri bugreportUri = Uri.fromFile(bugreport); // todo (aalbert): investigate adding a screenshot to BugReporter Intent intent = tryBugReporter(bugreportUri); if (intent == null) { final Uri screenshotUri = screenShot != null ? Uri.fromFile(screenShot) : null; intent = getSendMailIntent(bugreportUri, screenshotUri); } if (intent != null) { final IActivityManager am = ActivityManagerNative.getDefault(); if (am == null) { Log.e(LOG_TAG, "Cannot get ActivityManager, is the system running?"); return; } try { am.startActivityAsUser(null, intent, intent.getType(), null, null, 0, 0, null, null, null, UserHandle.USER_CURRENT); } catch (RemoteException e) { // ignore } } else { Log.w(LOG_TAG, "Cannot find account to send bugreport, local path: " + bugreportPath); } } private Intent tryBugReporter(Uri bugreportUri) { final Intent intent = new Intent(SEND_BUG_INTENT_ACTION); intent.setData(bugreportUri); final IPackageManager pm = IPackageManager.Stub.asInterface( ServiceManager.getService("package")); if (pm == null) { Log.e(LOG_TAG, "Cannot get PackageManager, is the system running?"); return null; } final List results; try { results = pm.queryIntentActivities(intent, null, 0, 0); } catch (RemoteException e) { return null; } if (results != null && results.size() > 0) { final ResolveInfo info = results.get(0); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setClassName(info.activityInfo.applicationInfo.packageName, info.activityInfo.name); return intent; } else { return null; } } private Intent getSendMailIntent(Uri bugreportUri, Uri screenshotUri) { final Account sendToAccount = findSendToAccount(); final Intent intent = new Intent(Intent.ACTION_SEND); intent.addCategory(Intent.CATEGORY_DEFAULT); intent.setType("application/octet-stream"); intent.putExtra(Intent.EXTRA_SUBJECT, bugreportUri.getLastPathSegment()); final StringBuilder sb = new StringBuilder(); sb.append(SystemProperties.get("ro.build.description")); sb.append("\n(Sent from BugMailer)"); intent.putExtra(Intent.EXTRA_TEXT, (CharSequence)sb); if (screenshotUri != null) { final ArrayList attachments = new ArrayList(); attachments.add(bugreportUri); attachments.add(screenshotUri); intent.setAction(Intent.ACTION_SEND_MULTIPLE); intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, attachments); } else { intent.putExtra(Intent.EXTRA_STREAM, bugreportUri); } if (sendToAccount != null) { intent.putExtra(Intent.EXTRA_EMAIL, new String[]{sendToAccount.name}); return intent; } return null; } private Account findSendToAccount() { final IAccountManager accountManager = IAccountManager.Stub.asInterface(ServiceManager .getService(Context.ACCOUNT_SERVICE)); if (accountManager == null) { Log.e(LOG_TAG, "Cannot get AccountManager, is the system running?"); return null; } Account[] accounts = null; Account foundAccount = null; String preferredDomain = SystemProperties.get("sendbug.preferred.domain"); if (!preferredDomain.startsWith("@")) { preferredDomain = "@" + preferredDomain; } try { accounts = accountManager.getAccounts(null); } catch (RemoteException e) { // ignore } if (accounts != null) { for (Account account : accounts) { if (EMAIL_REGEX.matcher(account.name).matches()) { if (!preferredDomain.isEmpty()) { // if we have a preferred domain and it matches, return; otherwise keep // looking if (account.name.endsWith(preferredDomain)) { return account; } else { foundAccount = account; } // if we don't have a preferred domain, just return since it looks like // an email address } else { return account; } } } } return foundAccount; } }