/* * Copyright 2010 Emmanuel Astier & Kevin Gaudin * * 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 org.acra.annotation; import android.support.annotation.DrawableRes; import android.support.annotation.NonNull; import android.support.annotation.RawRes; import android.support.annotation.StringRes; import android.support.annotation.StyleRes; import org.acra.ACRA; import org.acra.ACRAConstants; import org.acra.ReportField; import org.acra.ReportingInteractionMode; import org.acra.attachment.AttachmentUriProvider; import org.acra.attachment.DefaultAttachmentProvider; import org.acra.builder.NoOpReportPrimer; import org.acra.builder.ReportPrimer; import org.acra.config.DefaultRetryPolicy; import org.acra.config.RetryPolicy; import org.acra.dialog.BaseCrashReportDialog; import org.acra.dialog.CrashReportDialog; import org.acra.file.Directory; import org.acra.security.KeyStoreFactory; import org.acra.security.NoKeyStoreFactory; import org.acra.sender.DefaultReportSenderFactory; import org.acra.sender.HttpSender; import org.acra.sender.ReportSenderFactory; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Provide configuration elements to the * {@link ACRA#init(android.app.Application)} method. * * @author Kevin Gaudin */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Inherited @Configuration public @interface ReportsCrashes { /** * The Uri of your own server-side script that will receive reports. * * @return URI of a custom server to which to post reports. */ @NonNull String formUri() default ACRAConstants.DEFAULT_STRING_VALUE; /** * <p> * The interaction mode you want to implement. Default is * {@link ReportingInteractionMode#SILENT} which does not require any * resources configuration. * </p> * <p> * Other modes have resources requirements: * </p> * <ul> * <li>{@link ReportingInteractionMode#TOAST} requires * {@link #resToastText()} to be provided to define the text that you want * to be displayed to the user when a report is being sent.</li> * <li>{@link ReportingInteractionMode#NOTIFICATION} requires * {@link #resNotifTickerText()}, {@link #resNotifTitle()}, * {@link #resNotifText()}, {@link #resDialogText()}.</li> * <li>{@link ReportingInteractionMode#DIALOG} requires * {@link #resDialogText()}.</li> * </ul> * <p> * Default is {@link ReportingInteractionMode#SILENT} * </p> * * @return the interaction mode that you want ACRA to implement. */ @Name("reportingInteractionMode") @NonNull ReportingInteractionMode mode() default ReportingInteractionMode.SILENT; /** * @return Resource id for the label of positive button in the crash dialog. * If not provided, defaults to 'OK'. */ @StringRes int resDialogPositiveButtonText() default ACRAConstants.DEFAULT_DIALOG_POSITIVE_BUTTON_TEXT; /** * @return Resource id for the label of negative button in the crash dialog. * If not provided, defaults to 'cancel'. */ @StringRes int resDialogNegativeButtonText() default ACRAConstants.DEFAULT_DIALOG_NEGATIVE_BUTTON_TEXT; /** * @return Resource id for the user comment input label in the crash dialog. * If not provided, disables the input field. */ @StringRes int resDialogCommentPrompt() default ACRAConstants.DEFAULT_RES_VALUE; /** * @return Resource id for the user email address input label in the crash * dialog. If not provided, disables the input field. */ @StringRes int resDialogEmailPrompt() default ACRAConstants.DEFAULT_RES_VALUE; /** * @return Resource id for the icon in the crash dialog. Default value is * the system alert icon. */ @DrawableRes int resDialogIcon() default ACRAConstants.DEFAULT_DIALOG_ICON; /** * @return Resource id for the Toast text triggered when the user accepts to * send a report in the crash dialog. */ @StringRes int resDialogOkToast() default ACRAConstants.DEFAULT_RES_VALUE; /** * @return Resource id for the text in the crash dialog. */ @StringRes int resDialogText() default ACRAConstants.DEFAULT_RES_VALUE; /** * @return Resource id for the title in the crash dialog. */ @StringRes int resDialogTitle() default ACRAConstants.DEFAULT_RES_VALUE; /** * @return resource id for the crash dialog theme */ @StyleRes int resDialogTheme() default ACRAConstants.DEFAULT_RES_VALUE; /** * @return Resource id for the icon in the status bar notification. Default * is the system error notification icon. */ @DrawableRes int resNotifIcon() default ACRAConstants.DEFAULT_NOTIFICATION_ICON; /** * @return Resource id for the text in the status bar notification. */ @StringRes int resNotifText() default ACRAConstants.DEFAULT_RES_VALUE; /** * @return Resource id for the ticker text in the status bar notification. */ @StringRes int resNotifTickerText() default ACRAConstants.DEFAULT_RES_VALUE; /** * @return Resource id for the title in the status bar notification. */ @StringRes int resNotifTitle() default ACRAConstants.DEFAULT_RES_VALUE; /** * Resource id for the Toast text triggered when the application crashes if * the {@link ReportingInteractionMode#TOAST} mode is used. Can also be used * in {@link ReportingInteractionMode#NOTIFICATION} and * {@link ReportingInteractionMode#DIALOG} modes to display a Toast message * while the report is being created, before the dialog/notification * appears. This allows the user to know what is happening just before the * application is terminated. * * @return Resource id for the Toast text triggered when the application * crashes. */ @StringRes int resToastText() default ACRAConstants.DEFAULT_RES_VALUE; /** * @return Name of the SharedPreferences that will host ACRA settings you * can make accessible to your users through a preferences screen: * <ul> * <li> * {@link org.acra.ACRA#PREF_DISABLE_ACRA} or {@link org.acra.ACRA#PREF_ENABLE_ACRA}</li> * <li> * {@link org.acra.ACRA#PREF_ALWAYS_ACCEPT}</li> * <li> * {@link org.acra.ACRA#PREF_ENABLE_DEVICE_ID}</li> * <li> * {@link org.acra.ACRA#PREF_ENABLE_SYSTEM_LOGS}</li> * </ul> * preference. Default is to use the application default * SharedPreferences, as retrieved with * {@link android.preference.PreferenceManager#getDefaultSharedPreferences(android.content.Context)}. */ @NonNull String sharedPreferencesName() default ACRAConstants.DEFAULT_STRING_VALUE; /** * If using a custom {@link ReportsCrashes#sharedPreferencesName()}, pass * here the mode that you need for the SharedPreference file creation: * {@link android.content.Context#MODE_PRIVATE}, {@link android.content.Context#MODE_WORLD_READABLE} or * {@link android.content.Context#MODE_WORLD_WRITEABLE}. Default is * {@link android.content.Context#MODE_PRIVATE}. * * @return Mode to use with the SharedPreference creation. * @see android.content.Context#getSharedPreferences(String, int) */ int sharedPreferencesMode() default ACRAConstants.DEFAULT_SHARED_PREFERENCES_MODE; /** * If enabled, DropBox events collection will include system tags: * <ul> * <li>system_app_anr</li> * <li>system_app_wtf</li> * <li>system_app_crash</li> * <li>system_server_anr</li> * <li>system_server_wtf</li> * <li>system_server_crash</li> * <li>BATTERY_DISCHARGE_INFO</li> * <li>SYSTEM_RECOVERY_LOG</li> * <li>SYSTEM_BOOT</li> * <li>SYSTEM_LAST_KMSG</li> * <li>APANIC_CONSOLE</li> * <li>APANIC_THREADS</li> * <li>SYSTEM_RESTART</li> * <li>SYSTEM_TOMBSTONE</li> * <li>data_app_strictmode</li> * </ul> * * @return True if system tags are to be included as part of DropBox events. */ boolean includeDropBoxSystemTags() default ACRAConstants.DEFAULT_INCLUDE_DROPBOX_SYSTEM_TAGS; /** * @return Array of tags that you want to be fetched when collecting DropBox * entries. */ @NonNull String[] additionalDropBoxTags() default {}; /** * @return Number of minutes to look back when collecting events from * DropBoxManager. */ int dropboxCollectionMinutes() default ACRAConstants.DEFAULT_DROPBOX_COLLECTION_MINUTES; /** * <p> * Arguments to be passed to the logcat command line. Default is { "-t", * "100", "-v", "time" } for: * </p> * <pre> * logcat -t 100 -v time * </pre> * <p> * Do not include -b arguments for buffer selection, include * {@link ReportField#EVENTSLOG} and {@link ReportField#RADIOLOG} in * {@link ReportsCrashes#customReportContent()} to activate alternative * logcat buffers reporting. They will use the same other arguments as those * provided here. * </p> * <p> * See <a href= * "http://developer.android.com/intl/fr/guide/developing/tools/adb.html#logcatoptions" * >Listing of logcat Command Options</a>. * </p> * * @return Array of arguments to supply if retrieving the log as part of the * report. */ @NonNull String[] logcatArguments() default {"-t", "" + ACRAConstants.DEFAULT_LOGCAT_LINES, "-v", "time"}; /** * When using the {@link #formUri()} parameter to send reports to a custom * server-side script, you can set here and in * {@link #formUriBasicAuthPassword()} the credentials for a BASIC HTTP * authentication. * * @return Login to use when posting reports to a custom server. */ @NonNull String formUriBasicAuthLogin() default ACRAConstants.NULL_VALUE; /** * When using the {@link #formUri()} parameter to send reports to a custom * server-side script, you can set here and in * {@link #formUriBasicAuthLogin()} the credentials for a BASIC HTTP * authentication. * * @return Password to use when posting reports to a custom server. */ @NonNull String formUriBasicAuthPassword() default ACRAConstants.NULL_VALUE; /** * <p> * Redefines the list of {@link ReportField}s collected and sent in your * reports. * </p> * <p> * The fields order is significant. You can also use this property to modify * fields order in your reports. * </p> * <p> * The default list is the following, except if you send reports by mail * using {@link #mailTo()}. * </p> * <ul> * <li> * {@link ReportField#REPORT_ID}</li> * <li> * {@link ReportField#APP_VERSION_CODE}</li> * <li> * {@link ReportField#APP_VERSION_NAME}</li> * <li> * {@link ReportField#PACKAGE_NAME}</li> * <li> * {@link ReportField#FILE_PATH}</li> * <li> * {@link ReportField#PHONE_MODEL}</li> * <li> * {@link ReportField#BRAND}</li> * <li> * {@link ReportField#PRODUCT}</li> * <li> * {@link ReportField#ANDROID_VERSION}</li> * <li> * {@link ReportField#BUILD}</li> * <li> * {@link ReportField#TOTAL_MEM_SIZE}</li> * <li> * {@link ReportField#AVAILABLE_MEM_SIZE}</li> * <li> * {@link ReportField#CUSTOM_DATA}</li> * <li> * {@link ReportField#IS_SILENT}</li> * <li> * {@link ReportField#STACK_TRACE}</li> * <li> * {@link ReportField#INITIAL_CONFIGURATION}</li> * <li> * {@link ReportField#CRASH_CONFIGURATION}</li> * <li> * {@link ReportField#DISPLAY}</li> * <li> * {@link ReportField#USER_COMMENT}</li> * <li> * {@link ReportField#USER_EMAIL}</li> * <li> * {@link ReportField#USER_APP_START_DATE}</li> * <li> * {@link ReportField#USER_CRASH_DATE}</li> * <li> * {@link ReportField#DUMPSYS_MEMINFO}</li> * <li> * {@link ReportField#LOGCAT}</li> * <li> * {@link ReportField#INSTALLATION_ID}</li> * <li> * {@link ReportField#DEVICE_FEATURES}</li> * <li> * {@link ReportField#ENVIRONMENT}</li> * <li> * {@link ReportField#SHARED_PREFERENCES}</li> * <li> * {@link ReportField#SETTINGS_SYSTEM}</li> * <li> * {@link ReportField#SETTINGS_SECURE}</li> * <li> * {@link ReportField#SETTINGS_GLOBAL}</li> * </ul> * * @return ReportField Array listing the fields to be included in the * report. */ @NonNull ReportField[] customReportContent() default {}; /** * <p> * Add your crash reports mailbox here if you want to send reports via * email. This allows to get rid of the INTERNET permission. Reports content * can be customized with {@link #customReportContent()} . Default fields * are: * </p> * <ul> * <li> * {@link ReportField#USER_COMMENT}</li> * <li> * {@link ReportField#ANDROID_VERSION}</li> * <li> * {@link ReportField#APP_VERSION_NAME}</li> * <li> * {@link ReportField#BRAND}</li> * <li> * {@link ReportField#PHONE_MODEL}</li> * <li> * {@link ReportField#CUSTOM_DATA}</li> * <li> * {@link ReportField#STACK_TRACE}</li> * </ul> * * @return email address to which to send reports. */ @NonNull String mailTo() default ACRAConstants.DEFAULT_STRING_VALUE; /** * Controls whether unapproved reports are deleted on application start or not. * Default is true. * <p> * Silent and Toast reports are automatically approved. * Dialog and Notification reports required explicit approval by the user before they are sent. * </p> * <p> * On application restart the user is prompted with approval for any unsent reports. * So you generally don't want to accumulate unapproved reports, otherwise you will prompt them multiple times. * </p> * <p> * If this is set to true then all unapproved reports bar one will be deleted on application start. * The last report is always retained because that is the report that probably just happened. * </p> * <p> * If set to false then on restart the user will be prompted with approval for each unapproved report. * </p> * * @return true if ACRA should delete unapproved reports on application start. */ boolean deleteUnapprovedReportsOnApplicationStart() default ACRAConstants.DEFAULT_DELETE_UNAPPROVED_REPORTS_ON_APPLICATION_START; /** * This property can be used to determine whether old (out of date) reports * should be sent or not. By default they are discarded. * * @return true if ACRA should delete any unsent reports on startup if the * application has been updated since the last time the application * was started. */ boolean deleteOldUnsentReportsOnApplicationStart() default ACRAConstants.DEFAULT_DELETE_OLD_UNSENT_REPORTS_ON_APPLICATION_START; /** * @return Value in milliseconds for timeout attempting to connect to a network (default 5000ms). */ int connectionTimeout() default ACRAConstants.DEFAULT_CONNECTION_TIMEOUT; /** * If the request is retried due to timeout, the socketTimeout will double * before retrying the request. * * @return Value in milliseconds for timeout receiving a response to a network request (default 8000ms). */ int socketTimeout() default ACRAConstants.DEFAULT_SOCKET_TIMEOUT; /** * Set this to true if you prefer displaying the native force close dialog after the ACRA is done. * Recommended: Keep this set to false if using {@link ReportingInteractionMode#DIALOG} for notification. * * @return true if the native force close dialog should be displayed. */ boolean alsoReportToAndroidFramework() default ACRAConstants.DEFAULT_REPORT_TO_ANDROID_FRAMEWORK; /** * Add here your {@link android.content.SharedPreferences} identifier Strings if you use * others than your application's default. They will be added to the * {@link ReportField#SHARED_PREFERENCES} field. * * @return String Array containing the names of the additional preferences. */ @NonNull String[] additionalSharedPreferences() default {}; /** * Set this to true if you want to include only logcat lines related to your * Application process. * * @return true if you want to filter logcat with your process id. */ boolean logcatFilterByPid() default ACRAConstants.DEFAULT_LOGCAT_FILTER_BY_PID; /** * Set this to true if you want to read logcat lines in a non blocking way for your * thread. It has a default timeout of 3 seconds. * * @return true if you want that reading of logcat lines to not block current thread. */ boolean nonBlockingReadForLogcat() default ACRAConstants.DEFAULT_NON_BLOCKING_READ_FOR_LOGCAT; /** * Set this to false if you want to disable sending reports in development * mode. Only signed application packages will send reports. Default value * is true. * * @return false if reports should not be sent. */ boolean sendReportsInDevMode() default ACRAConstants.DEFAULT_SEND_REPORTS_IN_DEV_MODE; /** * @return true. * @deprecated since 4.8.3 no replacement. Now that we are using the SenderService in a separate process we always send at shutdown. */ @Deprecated boolean sendReportsAtShutdown() default true; /** * Provide here regex patterns to be evaluated on each SharedPreference key * to exclude KV pairs from the collected SharedPreferences. This allows you * to exclude sensitive user data like passwords to be collected. * * @return an array of regex patterns, every matching key is not collected. */ @NonNull String[] excludeMatchingSharedPreferencesKeys() default {}; /** * Provide here regex patterns to be evaluated on each Settings.System, * Settings.Secure and Settings.Global key to exclude KV pairs from the * collected SharedPreferences. This allows you to exclude sensitive data to * be collected. * * @return an array of regex patterns, every matching key is not collected. */ @NonNull String[] excludeMatchingSettingsKeys() default {}; /** * The default value will be a BuildConfig class residing in the same package as the Application class. * * @return BuildConfig class from which to read any BuildConfig attributes. */ @NonNull Class buildConfigClass() default Object.class; /** * The default {@link org.acra.sender.ReportSenderFactory} creates an {@link org.acra.sender.EmailIntentSender} * if the 'mailTo' parameter is defined or an {@link org.acra.sender.HttpSender} if the 'formUri' parameter * is defined (and internet permission has been granted. * * @return List of the {@link org.acra.sender.ReportSenderFactory} with which to construct the * {@link org.acra.sender.ReportSender}s that will send the crash reports. */ @NonNull Class<? extends ReportSenderFactory>[] reportSenderFactoryClasses() default {DefaultReportSenderFactory.class}; /** * To use in combination with {@link ReportField#APPLICATION_LOG} to set the * path/name of your application log file. If the string does not contain * any path separator, the file is assumed as being in * {@link android.content.Context#getFilesDir()}. * * @return a String containing the path/name of your application log file. * If the string does not contain any path separator, the file is * assumed as being in {@link android.content.Context#getFilesDir()}. */ @NonNull String applicationLogFile() default ACRAConstants.DEFAULT_APPLICATION_LOGFILE; /** * To use in combination with {@link ReportField#APPLICATION_LOG} to set the * number of latest lines of your application log file to be collected. * Default value is 100. * * @return number of lines to collect. */ int applicationLogFileLines() default ACRAConstants.DEFAULT_APPLICATION_LOGFILE_LINES; /** * To use in combination with {@link ReportField#APPLICATION_LOG} to set the root * for the path provided in {@link #applicationLogFile()} * * @return the directory of the application log file */ @NonNull Directory applicationLogFileDir() default Directory.FILES_LEGACY; /** * @return Class for the CrashReportDialog used when prompting the user for crash details. * If not provided, defaults to CrashReportDialog.class */ @NonNull Class<? extends BaseCrashReportDialog> reportDialogClass() default CrashReportDialog.class; /** * @return Class that is ued to provide any extra details for a crash. */ @NonNull Class<? extends ReportPrimer> reportPrimerClass() default NoOpReportPrimer.class; /** * <p> * The {@link HttpSender.Method} to be used when posting with {@link #formUri()}. * </p> * * @return HTTP method used when posting reports. */ @NonNull HttpSender.Method httpMethod() default HttpSender.Method.POST; /** * <p> * The {@link HttpSender.Type} to be used when posting with {@link #formUri()}. * </p> * * @return the report type used when posting reports */ @NonNull HttpSender.Type reportType() default HttpSender.Type.FORM; /** * @return Class which creates a keystore that can contain trusted certificates */ @NonNull Class<? extends KeyStoreFactory> keyStoreFactoryClass() default NoKeyStoreFactory.class; /** * @return path to a custom trusted certificate. Must start with "asset://" if the file is in the assets folder */ @NonNull String certificatePath() default ACRAConstants.DEFAULT_STRING_VALUE; /** * @return resource id of a custom trusted certificate. */ @RawRes int resCertificate() default ACRAConstants.DEFAULT_RES_VALUE; /** * @return specify the type of the certificate set in either {@link #certificatePath()} or {@link #resCertificate()} */ @NonNull String certificateType() default ACRAConstants.DEFAULT_CERTIFICATE_TYPE; /** * @return a Class that decides if a report should be resent (usually if one or more senders failed). * @since 4.9.1 */ @NonNull Class<? extends RetryPolicy> retryPolicyClass() default DefaultRetryPolicy.class; /** * @return true if all services running in a process should be stopped before it is killed. * @since 4.9.2 */ boolean stopServicesOnCrash() default false; /** * Allows to attach files to crash reports. * <p> * ACRA contains a file provider under the following Uri: * content://[applicationId].acra/[Directory]/[Path] * where [applicationId] is your application package name, * [Directory] is one of the enum constants in {@link Directory} in lower case * and [Path] is the relative path to the file in that directory * e.g. content://org.acra.provider/files/thisIsATest.txt * </p> * Side effects: * <ul> * <li>POST mode: requests will be sent with content-type multipart/mixed</li> * <li>PUT mode: There will be additional requests with the attachments. Naming scheme: [report-id]-[filename] </li> * <li>EMAIL mode: Some email clients do not support attachments, so some email may lack these attachments. * Note that attachments will be readable to email clients when they are sent.</li> * </ul> * * @return uris to be attached to crash reports. * @since 4.9.3 */ @NonNull String[] attachmentUris() default {}; /** * Allows attachmentUri configuration at runtime instead of compile time. * * @return a class that decides which uris should be attached to reports * @since 4.9.3 */ @NonNull Class<? extends AttachmentUriProvider> attachmentUriProvider() default DefaultAttachmentProvider.class; /** * @return if the report should be an attachment instead of plain text. Supported for email mode. */ boolean reportAsFile() default false; }