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