1 package leakcanary.internal.activity
2
3 import android.annotation.SuppressLint
4 import android.content.ActivityNotFoundException
5 import android.content.ClipData
6 import android.content.ClipboardManager
7 import android.content.Context
8 import android.content.Intent
9 import android.net.Uri
10 import android.os.AsyncTask
11 import android.os.Build
12 import android.view.View
13 import android.widget.Toast
14 import com.squareup.leakcanary.core.BuildConfig
15 import com.squareup.leakcanary.core.R
16 import leakcanary.internal.LeakCanaryFileProvider
17 import leakcanary.internal.navigation.activity
18 import shark.HeapAnalysisFailure
19 import java.io.File
20
sharenull21 internal fun View.share(content: String) {
22 val intent = Intent(Intent.ACTION_SEND)
23 intent.type = "text/plain"
24 intent.putExtra(Intent.EXTRA_TEXT, content)
25 activity.startActivity(
26 Intent.createChooser(intent, resources.getString(R.string.leak_canary_share_with))
27 )
28 }
29
30 @SuppressLint("SetWorldReadable")
shareHeapDumpnull31 internal fun View.shareHeapDump(heapDumpFile: File) {
32 AsyncTask.SERIAL_EXECUTOR.execute {
33 heapDumpFile.setReadable(true, false)
34 val heapDumpUri = LeakCanaryFileProvider.getUriForFile(
35 activity,
36 "com.squareup.leakcanary.fileprovider." + activity.packageName,
37 heapDumpFile
38 )
39 activity.runOnUiThread { startShareIntentChooser(heapDumpUri) }
40 }
41 }
42
startShareIntentChoosernull43 private fun View.startShareIntentChooser(uri: Uri) {
44 val intent = Intent(Intent.ACTION_SEND)
45 intent.type = "application/octet-stream"
46 intent.putExtra(Intent.EXTRA_STREAM, uri)
47 activity.startActivity(
48 Intent.createChooser(intent, resources.getString(R.string.leak_canary_share_with))
49 )
50 }
51
shareToStackOverflownull52 internal fun View.shareToStackOverflow(content: String) {
53 val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
54 // AsyncTask was needed here due to setPrimaryClip making a disk write which
55 // violated StrictMode if on the main thread
56 AsyncTask.execute {
57 clipboard.setPrimaryClip(
58 ClipData.newPlainText(
59 context.getString(R.string.leak_canary_leak_clipdata_label),
60 "```\n$content```"
61 )
62 )
63 }
64 Toast.makeText(context, R.string.leak_canary_leak_copied, Toast.LENGTH_LONG)
65 .show()
66 val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(STACKOVERFLOW_QUESTION_URL))
67 try {
68 activity.startActivity(browserIntent)
69 } catch (e: ActivityNotFoundException) {
70 Toast.makeText(context, R.string.leak_canary_leak_missing_browser_error, Toast.LENGTH_LONG)
71 .show()
72 }
73 }
74
shareToGitHubIssuenull75 internal fun View.shareToGitHubIssue(failure: HeapAnalysisFailure) {
76 val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
77 // AsyncTask was needed here due to setPrimaryClip making a disk write which
78 // violated StrictMode if on the main thread
79 AsyncTask.execute {
80 clipboard.setPrimaryClip(
81 ClipData.newPlainText(
82 context.getString(R.string.leak_canary_failure_clipdata_label),
83 """```
84 |${failure.exception}
85 |Build.VERSION.SDK_INT: ${Build.VERSION.SDK_INT}
86 |Build.MANUFACTURER: ${Build.MANUFACTURER}
87 |LeakCanary version: ${BuildConfig.LIBRARY_VERSION}
88 |Analysis duration: ${failure.analysisDurationMillis} ms
89 |Heap dump file path: ${failure.heapDumpFile.absolutePath}
90 |Heap dump timestamp: ${failure.createdAtTimeMillis}
91 |```
92 """.trimMargin()
93 )
94 )
95 }
96 Toast.makeText(context, R.string.leak_canary_failure_copied, Toast.LENGTH_LONG)
97 .show()
98 val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(NEW_ISSUE_URL))
99 try {
100 activity.startActivity(browserIntent)
101 } catch (e: ActivityNotFoundException) {
102 Toast.makeText(context, R.string.leak_canary_leak_missing_browser_error, Toast.LENGTH_LONG)
103 .show()
104 }
105 }
106
107 private const val STACKOVERFLOW_QUESTION_URL =
108 "http://stackoverflow.com/questions/ask?guided=false&tags=leakcanary"
109
110 private const val NEW_ISSUE_URL =
111 "https://github.com/square/leakcanary/issues/new?labels=type%3A+bug&template=2-bug.md"
112