{"id":13610091,"url":"https://github.com/infinum/android-sentinel","last_synced_at":"2025-08-20T02:32:35.974Z","repository":{"id":43087526,"uuid":"257115400","full_name":"infinum/android-sentinel","owner":"infinum","description":"Sentinel is a simple one screen UI which provides a standardised entry point for tools used in development and QA alongside device, application and permissions data.","archived":false,"fork":false,"pushed_at":"2025-04-06T13:44:33.000Z","size":2278,"stargazers_count":40,"open_issues_count":2,"forks_count":2,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-08-17T23:44:24.720Z","etag":null,"topics":["android","android-development","android-library","developer-tools","kotlin","kotlin-android","kotlin-library","open-source","qa","testing","testing-tools"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/infinum.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-04-19T22:29:37.000Z","updated_at":"2025-08-17T20:06:41.000Z","dependencies_parsed_at":"2024-03-12T12:25:36.714Z","dependency_job_id":"bd73a417-d018-4538-97cc-a0a3423082bd","html_url":"https://github.com/infinum/android-sentinel","commit_stats":{"total_commits":417,"total_committers":12,"mean_commits":34.75,"dds":0.2853717026378897,"last_synced_commit":"605b5849d4d00ffb212859fba7797c8b33384925"},"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"purl":"pkg:github/infinum/android-sentinel","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infinum%2Fandroid-sentinel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infinum%2Fandroid-sentinel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infinum%2Fandroid-sentinel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infinum%2Fandroid-sentinel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/infinum","download_url":"https://codeload.github.com/infinum/android-sentinel/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infinum%2Fandroid-sentinel/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270923562,"owners_count":24668578,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-17T02:00:09.016Z","response_time":129,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","android-development","android-library","developer-tools","kotlin","kotlin-android","kotlin-library","open-source","qa","testing","testing-tools"],"created_at":"2024-08-01T19:01:41.109Z","updated_at":"2025-08-20T02:32:35.966Z","avatar_url":"https://github.com/infinum.png","language":"Kotlin","funding_links":[],"categories":["Kotlin"],"sub_categories":[],"readme":"![Download](https://img.shields.io/maven-central/v/com.infinum.sentinel/sentinel) ![Validate Gradle Wrapper](https://github.com/infinum/android-sentinel/actions/workflows/gradle-wrapper-validation.yml/badge.svg) ![Code analysis](https://github.com/infinum/android-sentinel/actions/workflows/code-analysis.yml/badge.svg) [![CodeFactor](https://www.codefactor.io/repository/github/infinum/android-sentinel/badge/master)](https://www.codefactor.io/repository/github/infinum/android-sentinel/overview/master)\n\n### \u003cimg align=\"left\" src=\"logo.svg\" width=\"48\"\u003e\n\n# Sentinel\n\n![UI](ui.png)\n\n## Description\n\n_Sentinel_ is a simple one screen UI that provides standardised entry point for tools used in\ndevelopment and QA alongside device, application and permissions data.  \nIt's designed to be easily configured and expanded depending on needs and requirements of developers\nand QA testers.\n\nThe project is organized in the following modules:\n\n- `sentinel` - contains a single screen UI that provides visual information about device,\n  application, permissions and tools\n- `sentinel-no-op` - contains stubs for easy release implementation of UI package and any Tools\n  included\n- `tool-chucker` - contains a class wrapper for Chucker\n- `tool-collar` - contains a class wrapper for Collar\n- `tool-dbinspector` - contains a class wrapper for DbInspector\n- `tool-leakcanary` - contains a class wrapper for LeakCanary\n- `tool-appgallery` - contains a class wrapper for Huawei AppGallery\n- `tool-googleplay` - contains a class wrapper for Google Play\n- `tool-thimble` - contains a class wrapper for Thimble\n- `tool-timber` - contains a class wrapper for Timber\n- `sample` - a sample app for testing and developing\n\n\n## Table of contents\n\n* [Requirements](#requirements)\n* [Usage](#usage)\n* [Getting started](#getting-started)\n* [Contributing](#contributing)\n* [License](#license)\n* [Credits](#credits)\n\n## Requirements\n\nThis plugin has been written in Kotlin but works both inside Kotlin and Java projects. Minimum\nrequired API level to use _Sentinel_ is *21* known\nas [Android 5.0, Lollipop](https://www.android.com/versions/lollipop-5-0/).\n_Sentinel_ is built with and for AndroidX projects.\n\n## Usage\n\nTo include _Sentinel_ in your project, you have to add buildscript dependencies in your project\nlevel `build.gradle` or `build.gradle.kts`:\n\n**Groovy**\n\n```groovy\nbuildscript {\n    repositories {\n        mavenCentral()\n    }\n}\n```\n\n**KotlinDSL**\n\n```kotlin\nbuildscript {\n    repositories {\n        mavenCentral()\n    }\n}\n```\n\nThen add the following dependencies in your app `build.gradle` or `build.gradle.kts` :\n\n**Groovy**\n\n\u003c!-- \n    If format of version definition is changed, make sure to update `generateReadme` task\n--\u003e\n```groovy\ndef sentinelVersion = \"1.5.1\"\ndebugImplementation \"com.infinum.sentinel:sentinel:$sentinelVersion\"\nreleaseImplementation \"com.infinum.sentinel:sentinel-no-op:$sentinelVersion\"\n```\n\n**KotlinDSL**\n\n```kotlin\nval sentinelVersion = \"1.5.1\"\ndebugImplementation(\"com.infinum.sentinel:sentinel:$sentinelVersion\")\nreleaseImplementation(\"com.infinum.sentinel:sentinel-no-op:$sentinelVersion\")\n```\n\nBasic tools are provided inside the main package but depending on requirements you might want to add\nspecific tools:\n\n**Groovy**\n\n```groovy\ndebugImplementation \"com.infinum.sentinel:tool-chucker:$sentinelVersion\"\ndebugImplementation \"com.infinum.sentinel:tool-collar:$sentinelVersion\"\ndebugImplementation \"com.infinum.sentinel:tool-dbinspector:$sentinelVersion\"\ndebugImplementation \"com.infinum.sentinel:tool-leakcanary:$sentinelVersion\"\ndebugImplementation \"com.infinum.sentinel:tool-appgallery:$sentinelVersion\"\ndebugImplementation \"com.infinum.sentinel:tool-googleplay:$sentinelVersion\"\ndebugImplementation \"com.infinum.sentinel:tool-thimble:$sentinelVersion\"\ndebugImplementation \"com.infinum.sentinel:tool-timber:$sentinelVersion\"\n```\n\n**KotlinDSL**\n\n```kotlin\ndebugImplementation(\"com.infinum.sentinel:tool-chucker:$sentinelVersion\")\ndebugImplementation(\"com.infinum.sentinel:tool-collar:$sentinelVersion\")\ndebugImplementation(\"com.infinum.sentinel:tool-dbinspector:$sentinelVersion\")\ndebugImplementation(\"com.infinum.sentinel:tool-leakcanary:$sentinelVersion\")\ndebugImplementation(\"com.infinum.sentinel:tool-appgallery:$sentinelVersion\")\ndebugImplementation(\"com.infinum.sentinel:tool-googleplay:$sentinelVersion\")\ndebugImplementation(\"com.infinum.sentinel:tool-thimble:$sentinelVersion\")\ndebugImplementation(\"com.infinum.sentinel:tool-timber:$sentinelVersion\")\n```\n\nNow you can sync your project.\n\n## Getting started\n\nCreate or inject an instance of _Sentinel_ in your Application class and start watching for\ntriggers:\n\n```kotlin\nSentinel.watch(\n    setOf(\n        ChuckerTool(),\n        CollarTool(),\n        DbInspectorTool(),\n        LeakCanaryTool(),\n        AppGalleryTool(appId = \"123456789\"),\n        GooglePlayTool(),\n        ThimbleTool(),\n        TimberTool(allowedTags = listOf(\"EXAMPLE\")),\n        CertificateTool(userCertificates = listOf())\n    )\n)\n```\n\nA set of tools should be provided as a _watch_ parameter. This set of tools can be empty.\n\n### App Startup\n\nUnder the hood Sentinel is using [App Startup library](https://developer.android.com/topic/libraries/app-startup) to initialize itself. \nIf you are using [App Startup library](https://developer.android.com/topic/libraries/app-startup) in your project, you might encounter errors related to Sentinel's initialization.\n\nTo avoid errors simply add dependency to Sentinel's initializer in your initializer:\n\n```kotlin\nclass SentinelInitializer : Initializer\u003cUnit\u003e {\n\n    override fun create(context: Context) {\n        Sentinel.watch(\n            setOf(\n                ChuckerTool(),\n                DbInspectorTool(),\n                GooglePlayTool(),\n                TimberTool(),\n            ),\n        )\n    }\n\n    override fun dependencies(): List\u003cClass\u003cout Initializer\u003c*\u003e?\u003e?\u003e = listOf(\n        com.infinum.sentinel.SentinelInitializer::class.java,\n    )\n}\n```\n\n### Tools\n\n_Sentinel_ provides several different levels of tools for a developer to implement.\n\n#### Built in\n\n- `AppInfoTool` - opens Android OS Settings page of the application in which _Sentinel_ was\n  implemented\n- `CrashMonitorTool` - monitors exceptions and ANR crashes of the application in which _Sentinel_\n  was implemented\n- `BundleMonitorTool` - monitors Bundle objects passed around the application mostly for size\n  avoiding _TransactionTooLarge_ exceptions\n- `Preference Editor` - by tapping any preference _Sentinel_ opens a screen where you can edit\n  current value\n- `CertificateTool` - opens a list of system and user provided X.509 certificates with details    \n\n#### Dependency wrappers\n\nDepending of what you include as module dependencies, very specific tools are provided.\n\n- `ChuckerTool` - a wrapper class that opens [Chucker](https://github.com/ChuckerTeam/chucker)\n- `CollarTool` - a wrapper class that opens [Collar](https://github.com/infinum/android-collar)\n- `DbInspectorTool` - a wrapper class that\n  opens [DbInspector](https://github.com/infinum/android_dbinspector)\n- `LeakCanaryTool` - a wrapper class that opens [LeakCanary](https://github.com/square/leakcanary)\n- `ThimbleTool` - a wrapper class that opens [Thimble](https://github.com/infinum/android-thimble)\n- `TimberTool` - a wrapper class that opens [Timber](https://github.com/JakeWharton/timber) . Takes in an optional list of allowed tags for filtering logged messages per tag.\n- `AppGalleryTool` - a wrapper class that opens Huawei AppGallery of a published application or a\n  web page of the application if Huawei AppGallery is not found\n- `GooglePlayTool` - a wrapper class that opens Google Play of a published application or a web page\n  of the application if Google Play is not found\n\n#### Source abstractions\n\nIf you want to implement a different tool other than already packaged with a predefined type and\nname, several are available.\n\n- `NetworkTool` - a wrapper interface with a name *Network* for any network interceptors\n- `MemoryTool` - a wrapper interface with a name *Memory* for any memory management tools\n- `AnalyticsTool` - a wrapper interface with a name *Analytics* for any analytics collectors\n- `DatabaseTool` - a wrapper interface with a name *Database* for any database viewers\n- `ReportTool` - a wrapper interface with a name *Report* for any crash reporting tools\n- `BluetoothTool` - a wrapper interface with a name *Bluetooth* for any Bluetooth loggers\n- `DistributionTool` - a wrapper interface with a name *Distribution* for any release distribution\n  channels\n- `DesignTool` - a wrapper interface with a name *Design* for any design utilities\n\n#### Independent implementations\n\nAn interface is provided named _Sentinel.Tool_ that requires implementation of a *String resource*\nfor a name and a _View.OnClickListener_. An optional icon *Drawable resource* can be supplied.\nImplementing this interface enables any class to be provided as a tool in _Sentinel_.\n\n```kotlin\ninterface Tool {\n\n    @DrawableRes\n    fun icon(): Int? = null\n\n    @StringRes\n    fun name(): Int\n\n    fun listener(): View.OnClickListener\n}\n```\n\n### Triggers\n\n_Sentinel_ observes several different trigger events, determining when to show up.\n*Manual* trigger cannot be turned off but rest are configurable through _Sentinel_\nsettings except *Foreground* trigger when running on emulators. Trigger states will be persisted\nbetween sessions.\n*Upon first run, all triggers are enabled.*  \nOnly way to override default trigger behaviour is to explicitly set them in you application manifest.  \nIf declared, these will override any changes that user does on each application launch.  \nAccepted values are *0* and *1* to disable or enable a trigger.  \nAnything else will result in the same way like the metadata key isn't declared at all.\n```xml\n\u003capplication\n    android:name=\".SampleApplication\"\n    android:icon=\"@mipmap/ic_launcher\"\n    android:label=\"@string/app_name\"\n    android:roundIcon=\"@mipmap/ic_launcher_round\"\n    android:supportsRtl=\"true\"\n    android:theme=\"@style/AppTheme\"\u003e\n  \n    ...\n  \n    \u003cmeta-data\n        android:name=\"com.infinum.sentinel.trigger.shake\"\n        android:value=\"1\" /\u003e\n\n    \u003cmeta-data\n        android:name=\"com.infinum.sentinel.trigger.proximity\"\n        android:value=\"0\" /\u003e\n\n    \u003cmeta-data\n        android:name=\"com.infinum.sentinel.trigger.foreground\"\n        android:value=\"0\" /\u003e\n\n    \u003cmeta-data\n        android:name=\"com.infinum.sentinel.trigger.usb_connected\"\n        android:value=\"0\" /\u003e\n\n    \u003cmeta-data\n        android:name=\"com.infinum.sentinel.trigger.airplane_mode_on\"\n        android:value=\"0\" /\u003e\n\n    ...\n  \n\u003c/application\u003e\n```\n\n- `Manual` - used for manually triggering UI with _show()_\n- `Shake` - default trigger to show UI, shake device to invoke\n- `Proximity` - shows UI every time sensor detects _near_ state  \n- `Foreground` - shows UI every time application goes into foreground\n- `USB connected` - shows UI every time an USB cable is plugged in\n- `Airplane mode on` - shows UI every time Airplane mode is turned on\n\n### Formatters\n\nData gathered and presented by _Sentinel_ can be shared to any text compliant recipient\napplications.\n_Sentinel_ provides a few simple text formatters for easy integrations into other systems.\n_Plain_ formatter is selected by default, but selecting any other is persisted between sessions.\n\n- `Plain`\n- `Markdown`\n- `JSON`\n- `XML`\n- `HTML`\n\n### Crash monitor\n\n_Sentinel_ has a built in default uncaught exception handler and ANR observer. If switched on in\nsettings, it will notify both in a form of a notification. Note that from Android 13 you need to give permission \nto the app to show notifications.\nOnce tapped on this notification, a screen with details is shown. A complete list of crashes is\npersisted between sessions and available on demand.    \nMethods to react on these crashes in a graceful way are provided in _Sentinel_.\n\n```kotlin\nSentinel.setExceptionHandler { _, exception -\u003e\n    println(\"Exception happened: ${exception.message}\")\n    exitProcess(exception.hashCode())\n}\n\nSentinel.setAnrListener { exception -\u003e\n    println(\"ANR happened: ${exception.message}\")\n    exitProcess(exception.hashCode())\n}\n```\n\n### Bundle monitor\n\n_Sentinel_ monitors Bundle objects passed around the application mostly for size limit of 500kB,\nthus avoiding _TransactionTooLarge_ exceptions.  \nIn settings there are options to notify inside a running session, toggle specific variants or set\nthe limit of Bundle size.  \nThis monitor feature runs automatically for every _Activity_ but if you wish to disable monitoring\nfor a specific screen, you can do so in the _AndroidManifest.xml_ by adding a _meta-data_ node.\n```xml\n\u003cactivity\n    android:name=\"com.example.ui.main.MainActivity\"\n    android:exported=\"false\"\u003e\n    \u003cmeta-data\n      android:name=\"@string/sentinel_infinum_monitored\"\n      android:value=\"false\" /\u003e\n\u003c/activity\u003e\n```\n\n## Contributing\n\nWe believe that the community can help us improve and build better a product.\nPlease refer to our [contributing guide](CONTRIBUTING.md) to learn about the types of contributions we accept and the process for submitting them.\n\nTo ensure that our community remains respectful and professional, we defined a [code of conduct](CODE_OF_CONDUCT.md) that we expect all contributors to follow.\n\nFor easier developing a `sample` application with\nproper implementations is provided. If you wish to add a new specific dependency wrapper tool,\ncreate a new module and set it up like the ones already provided. Then create a pull request.\n\nWe appreciate your interest and look forward to your contributions.\n\n## License\n\n```\nCopyright 2020 Infinum\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n\n## Credits\nMaintained and sponsored by [Infinum](http://www.infinum.com).\n\n\u003cp align=\"center\"\u003e\n  \u003ca href='https://infinum.com'\u003e\n    \u003cpicture\u003e\n        \u003csource srcset=\"https://assets.infinum.com/brand/logo/static/white.svg\" media=\"(prefers-color-scheme: dark)\"\u003e\n        \u003cimg src=\"https://assets.infinum.com/brand/logo/static/default.svg\"\u003e\n    \u003c/picture\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finfinum%2Fandroid-sentinel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finfinum%2Fandroid-sentinel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finfinum%2Fandroid-sentinel/lists"}