android.tsx 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. import {Fragment} from 'react';
  2. import ExternalLink from 'sentry/components/links/externalLink';
  3. import List from 'sentry/components/list/';
  4. import ListItem from 'sentry/components/list/listItem';
  5. import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/step';
  6. import type {
  7. BasePlatformOptions,
  8. Docs,
  9. DocsParams,
  10. OnboardingConfig,
  11. } from 'sentry/components/onboarding/gettingStartedDoc/types';
  12. import {feedbackOnboardingCrashApiJava} from 'sentry/gettingStartedDocs/java/java';
  13. import {t, tct} from 'sentry/locale';
  14. import {getPackageVersion} from 'sentry/utils/gettingStartedDocs/getPackageVersion';
  15. export enum InstallationMode {
  16. AUTO = 'auto',
  17. MANUAL = 'manual',
  18. }
  19. const platformOptions = {
  20. installationMode: {
  21. label: t('Installation Mode'),
  22. items: [
  23. {
  24. label: t('Auto'),
  25. value: InstallationMode.AUTO,
  26. },
  27. {
  28. label: t('Manual'),
  29. value: InstallationMode.MANUAL,
  30. },
  31. ],
  32. defaultValue:
  33. navigator.userAgent.indexOf('Win') !== -1
  34. ? InstallationMode.MANUAL
  35. : InstallationMode.AUTO,
  36. },
  37. } satisfies BasePlatformOptions;
  38. type PlatformOptions = typeof platformOptions;
  39. type Params = DocsParams<PlatformOptions>;
  40. const isAutoInstall = (params: Params) =>
  41. params.platformOptions.installationMode === InstallationMode.AUTO;
  42. const getManualInstallSnippet = (params: Params) => `
  43. plugins {
  44. id "com.android.application" // should be in the same module
  45. id "io.sentry.android.gradle" version "${getPackageVersion(
  46. params,
  47. 'sentry.java.android.gradle-plugin',
  48. '3.12.0'
  49. )}"
  50. }`;
  51. const getConfigurationSnippet = (params: Params) => `
  52. <application>
  53. <!-- Required: set your sentry.io project identifier (DSN) -->
  54. <meta-data android:name="io.sentry.dsn" android:value="${params.dsn}" />
  55. <!-- enable automatic breadcrumbs for user interactions (clicks, swipes, scrolls) -->
  56. <meta-data android:name="io.sentry.traces.user-interaction.enable" android:value="true" />
  57. <!-- enable screenshot for crashes -->
  58. <meta-data android:name="io.sentry.attach-screenshot" android:value="true" />
  59. <!-- enable view hierarchy for crashes -->
  60. <meta-data android:name="io.sentry.attach-view-hierarchy" android:value="true" />${
  61. params.isPerformanceSelected
  62. ? `
  63. <!-- enable the performance API by setting a sample-rate, adjust in production env -->
  64. <meta-data android:name="io.sentry.traces.sample-rate" android:value="1.0" />`
  65. : ''
  66. }${
  67. params.isProfilingSelected
  68. ? `
  69. <!-- enable profiling when starting transactions, adjust in production env -->
  70. <meta-data android:name="io.sentry.traces.profiling.sample-rate" android:value="1.0" />`
  71. : ''
  72. }
  73. </application>`;
  74. const getVerifySnippet = () => `
  75. val breakWorld = Button(this).apply {
  76. text = "Break the world"
  77. setOnClickListener {
  78. Sentry.captureException(RuntimeException("This app uses Sentry! :)"))
  79. }
  80. }
  81. addContentView(breakWorld, ViewGroup.LayoutParams(
  82. ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT))`;
  83. const onboarding: OnboardingConfig<PlatformOptions> = {
  84. install: params =>
  85. isAutoInstall(params)
  86. ? [
  87. {
  88. type: StepType.INSTALL,
  89. description: tct(
  90. 'Add Sentry automatically to your app with the [wizardLink:Sentry wizard] (call this inside your project directory).',
  91. {
  92. wizardLink: (
  93. <ExternalLink href="https://docs.sentry.io/platforms/android/#install" />
  94. ),
  95. }
  96. ),
  97. configurations: [
  98. {
  99. language: 'bash',
  100. code: `brew install getsentry/tools/sentry-wizard && sentry-wizard -i android`,
  101. },
  102. {
  103. description: (
  104. <Fragment>
  105. {t('The Sentry wizard will automatically patch your application:')}
  106. <List symbol="bullet">
  107. <ListItem>
  108. {tct(
  109. "Update your app's [buildGradle:build.gradle] file with the Sentry Gradle plugin and configure it.",
  110. {
  111. buildGradle: <code />,
  112. }
  113. )}
  114. </ListItem>
  115. <ListItem>
  116. {tct(
  117. 'Update your [manifest: AndroidManifest.xml] with the default Sentry configuration',
  118. {
  119. manifest: <code />,
  120. }
  121. )}
  122. </ListItem>
  123. <ListItem>
  124. {tct(
  125. 'Create [sentryProperties: sentry.properties] with an auth token to upload proguard mappings (this file is automatically added to [gitignore: .gitignore])',
  126. {
  127. sentryProperties: <code />,
  128. gitignore: <code />,
  129. }
  130. )}
  131. </ListItem>
  132. <ListItem>
  133. {t(
  134. "Add an example error to your app's Main Activity to verify your Sentry setup"
  135. )}
  136. </ListItem>
  137. </List>
  138. <p>
  139. {tct(
  140. 'Alternatively, you can also [manualSetupLink:set up the SDK manually].',
  141. {
  142. manualSetupLink: (
  143. <ExternalLink href="https://docs.sentry.io/platforms/android/manual-setup/" />
  144. ),
  145. }
  146. )}
  147. </p>
  148. </Fragment>
  149. ),
  150. },
  151. ],
  152. },
  153. ]
  154. : [
  155. {
  156. type: StepType.INSTALL,
  157. description: tct(
  158. 'Add the [sagpLink:Sentry Android Gradle plugin] to your [app:app] module:',
  159. {
  160. sagpLink: (
  161. <ExternalLink href="https://docs.sentry.io/platforms/android/configuration/gradle/" />
  162. ),
  163. app: <code />,
  164. }
  165. ),
  166. configurations: [
  167. {
  168. language: 'groovy',
  169. partialLoading: params.sourcePackageRegistries?.isLoading,
  170. code: getManualInstallSnippet(params),
  171. },
  172. ],
  173. },
  174. ],
  175. configure: params =>
  176. isAutoInstall(params)
  177. ? []
  178. : [
  179. {
  180. type: StepType.CONFIGURE,
  181. description: (
  182. <Fragment>
  183. <p>
  184. {tct(
  185. 'Configuration is done via the application [manifest: AndroidManifest.xml]. Under the hood Sentry uses a [provider:ContentProvider] to initialize the SDK based on the values provided below. This way the SDK can capture important crashes and metrics right from the app start.',
  186. {
  187. manifest: <code />,
  188. provider: <code />,
  189. }
  190. )}
  191. </p>
  192. <p>{t("Here's an example config which should get you started:")}</p>
  193. </Fragment>
  194. ),
  195. configurations: [
  196. {
  197. language: 'xml',
  198. code: getConfigurationSnippet(params),
  199. },
  200. ],
  201. },
  202. ],
  203. verify: params =>
  204. isAutoInstall(params)
  205. ? []
  206. : [
  207. {
  208. type: StepType.VERIFY,
  209. description: tct(
  210. "This snippet contains an intentional error and can be used as a test to make sure that everything's working as expected. You can add it to your app's [mainActivity: MainActivity].",
  211. {
  212. mainActivity: <code />,
  213. }
  214. ),
  215. configurations: [
  216. {
  217. language: 'kotlin',
  218. code: getVerifySnippet(),
  219. },
  220. ],
  221. },
  222. ],
  223. nextSteps: params =>
  224. isAutoInstall(params)
  225. ? [
  226. {
  227. id: 'advanced-configuration',
  228. name: t('Advanced Configuration'),
  229. description: t('Customize the SDK initialization behavior.'),
  230. link: 'https://docs.sentry.io/platforms/android/configuration/manual-init/#manual-initialization',
  231. },
  232. {
  233. id: 'jetpack-compose',
  234. name: t('Jetpack Compose'),
  235. description: t(
  236. 'Learn about our first class integration with Jetpack Compose.'
  237. ),
  238. link: 'https://docs.sentry.io/platforms/android/configuration/integrations/jetpack-compose/',
  239. },
  240. ]
  241. : [
  242. {
  243. id: 'advanced-configuration',
  244. name: t('Advanced Configuration'),
  245. description: t('Customize the SDK initialization behavior.'),
  246. link: 'https://docs.sentry.io/platforms/android/configuration/manual-init/#manual-initialization',
  247. },
  248. {
  249. id: 'proguard-r8',
  250. name: t('ProGuard/R8'),
  251. description: t(
  252. 'Deobfuscate and get readable stacktraces in your Sentry errors.'
  253. ),
  254. link: 'https://docs.sentry.io/platforms/android/configuration/gradle/#proguardr8--dexguard',
  255. },
  256. {
  257. id: 'jetpack-compose',
  258. name: t('Jetpack Compose'),
  259. description: t(
  260. 'Learn about our first class integration with Jetpack Compose.'
  261. ),
  262. link: 'https://docs.sentry.io/platforms/android/configuration/integrations/jetpack-compose/',
  263. },
  264. {
  265. id: 'source-context',
  266. name: t('Source Context'),
  267. description: t('See your source code as part of your stacktraces in Sentry.'),
  268. link: 'https://docs.sentry.io/platforms/android/enhance-errors/source-context/',
  269. },
  270. ],
  271. };
  272. const docs: Docs<PlatformOptions> = {
  273. onboarding,
  274. feedbackOnboardingCrashApi: feedbackOnboardingCrashApiJava,
  275. crashReportOnboarding: feedbackOnboardingCrashApiJava,
  276. platformOptions,
  277. };
  278. export default docs;