Skip to content

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.

License

Notifications You must be signed in to change notification settings

infinum/android-sentinel

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Download Validate Gradle Wrapper Code analysis CodeFactor

Sentinel

UI

Description

Sentinel is a simple one screen UI that provides standardised entry point for tools used in development and QA alongside device, application and permissions data.
It's designed to be easily configured and expanded depending on needs and requirements of developers and QA testers.

The project is organized in the following modules:

  • sentinel - contains a single screen UI that provides visual information about device, application, permissions and tools
  • sentinel-no-op - contains stubs for easy release implementation of UI package and any Tools included
  • tool-chucker - contains a class wrapper for Chucker
  • tool-collar - contains a class wrapper for Collar
  • tool-dbinspector - contains a class wrapper for DbInspector
  • tool-leakcanary - contains a class wrapper for LeakCanary
  • tool-appgallery - contains a class wrapper for Huawei AppGallery
  • tool-googleplay - contains a class wrapper for Google Play
  • tool-thimble - contains a class wrapper for Thimble
  • tool-timber - contains a class wrapper for Timber
  • sample - a sample app for testing and developing

Table of contents

Requirements

This plugin has been written in Kotlin but works both inside Kotlin and Java projects. Minimum required API level to use Sentinel is 21 known as Android 5.0, Lollipop. Sentinel is built with and for AndroidX projects.

Usage

To include Sentinel in your project, you have to add buildscript dependencies in your project level build.gradle or build.gradle.kts:

Groovy

buildscript {
    repositories {
        mavenCentral()
    }
}

KotlinDSL

buildscript {
    repositories {
        mavenCentral()
    }
}

Then add the following dependencies in your app build.gradle or build.gradle.kts :

Groovy

def sentinelVersion = "1.4.1"
debugImplementation "com.infinum.sentinel:sentinel:$sentinelVersion"
releaseImplementation "com.infinum.sentinel:sentinel-no-op:$sentinelVersion"

KotlinDSL

val sentinelVersion = "1.4.1"
debugImplementation("com.infinum.sentinel:sentinel:$sentinelVersion")
releaseImplementation("com.infinum.sentinel:sentinel-no-op:$sentinelVersion")

Basic tools are provided inside the main package but depending on requirements you might want to add specific tools:

Groovy

debugImplementation "com.infinum.sentinel:tool-chucker:$sentinelVersion"
debugImplementation "com.infinum.sentinel:tool-collar:$sentinelVersion"
debugImplementation "com.infinum.sentinel:tool-dbinspector:$sentinelVersion"
debugImplementation "com.infinum.sentinel:tool-leakcanary:$sentinelVersion"
debugImplementation "com.infinum.sentinel:tool-appgallery:$sentinelVersion"
debugImplementation "com.infinum.sentinel:tool-googleplay:$sentinelVersion"
debugImplementation "com.infinum.sentinel:tool-thimble:$sentinelVersion"
debugImplementation "com.infinum.sentinel:tool-timber:$sentinelVersion"

KotlinDSL

debugImplementation("com.infinum.sentinel:tool-chucker:$sentinelVersion")
debugImplementation("com.infinum.sentinel:tool-collar:$sentinelVersion")
debugImplementation("com.infinum.sentinel:tool-dbinspector:$sentinelVersion")
debugImplementation("com.infinum.sentinel:tool-leakcanary:$sentinelVersion")
debugImplementation("com.infinum.sentinel:tool-appgallery:$sentinelVersion")
debugImplementation("com.infinum.sentinel:tool-googleplay:$sentinelVersion")
debugImplementation("com.infinum.sentinel:tool-thimble:$sentinelVersion")
debugImplementation("com.infinum.sentinel:tool-timber:$sentinelVersion")

Now you can sync your project.

Getting started

Create or inject an instance of Sentinel in your Application class and start watching for triggers:

Sentinel.watch(
    setOf(
        ChuckerTool(),
        CollarTool(),
        DbInspectorTool(),
        LeakCanaryTool(),
        AppGalleryTool(appId = "123456789"),
        GooglePlayTool(),
        ThimbleTool(),
        TimberTool(allowedTags = listOf("EXAMPLE")),
        CertificateTool(userCertificates = listOf())
    )
)

A set of tools should be provided as a watch parameter. This set of tools can be empty.

Tools

Sentinel provides several different levels of tools for a developer to implement.

Built in

  • AppInfoTool - opens Android OS Settings page of the application in which Sentinel was implemented
  • CrashMonitorTool - monitors exceptions and ANR crashes of the application in which Sentinel was implemented
  • BundleMonitorTool - monitors Bundle objects passed around the application mostly for size avoiding TransactionTooLarge exceptions
  • Preference Editor - by tapping any preference Sentinel opens a screen where you can edit current value
  • CertificateTool - opens a list of system and user provided X.509 certificates with details

Dependency wrappers

Depending of what you include as module dependencies, very specific tools are provided.

  • ChuckerTool - a wrapper class that opens Chucker
  • CollarTool - a wrapper class that opens Collar
  • DbInspectorTool - a wrapper class that opens DbInspector
  • LeakCanaryTool - a wrapper class that opens LeakCanary
  • ThimbleTool - a wrapper class that opens Thimble
  • TimberTool - a wrapper class that opens Timber . Takes in an optional list of allowed tags for filtering logged messages per tag.
  • AppGalleryTool - a wrapper class that opens Huawei AppGallery of a published application or a web page of the application if Huawei AppGallery is not found
  • GooglePlayTool - a wrapper class that opens Google Play of a published application or a web page of the application if Google Play is not found

Source abstractions

If you want to implement a different tool other than already packaged with a predefined type and name, several are available.

  • NetworkTool - a wrapper interface with a name Network for any network interceptors
  • MemoryTool - a wrapper interface with a name Memory for any memory management tools
  • AnalyticsTool - a wrapper interface with a name Analytics for any analytics collectors
  • DatabaseTool - a wrapper interface with a name Database for any database viewers
  • ReportTool - a wrapper interface with a name Report for any crash reporting tools
  • BluetoothTool - a wrapper interface with a name Bluetooth for any Bluetooth loggers
  • DistributionTool - a wrapper interface with a name Distribution for any release distribution channels
  • DesignTool - a wrapper interface with a name Design for any design utilities

Independent implementations

An interface is provided named Sentinel.Tool that requires implementation of a String resource for a name and a View.OnClickListener. An optional icon Drawable resource can be supplied. Implementing this interface enables any class to be provided as a tool in Sentinel.

interface Tool {

    @DrawableRes
    fun icon(): Int? = null

    @StringRes
    fun name(): Int

    fun listener(): View.OnClickListener
}

Triggers

Sentinel observes several different trigger events, determining when to show up. Manual trigger cannot be turned off but rest are configurable through Sentinel settings except Foreground trigger when running on emulators. Trigger states will be persisted between sessions. Upon first run, all triggers are enabled.
Only way to override default trigger behaviour is to explicitly set them in you application manifest.
If declared, these will override any changes that user does on each application launch.
Accepted values are 0 and 1 to disable or enable a trigger.
Anything else will result in the same way like the metadata key isn't declared at all.

<application
    android:name=".SampleApplication"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
  
    ...
  
    <meta-data
        android:name="com.infinum.sentinel.trigger.shake"
        android:value="1" />

    <meta-data
        android:name="com.infinum.sentinel.trigger.proximity"
        android:value="0" />

    <meta-data
        android:name="com.infinum.sentinel.trigger.foreground"
        android:value="0" />

    <meta-data
        android:name="com.infinum.sentinel.trigger.usb_connected"
        android:value="0" />

    <meta-data
        android:name="com.infinum.sentinel.trigger.airplane_mode_on"
        android:value="0" />

    ...
  
</application>
  • Manual - used for manually triggering UI with show()
  • Shake - default trigger to show UI, shake device to invoke
  • Proximity - shows UI every time sensor detects near state
  • Foreground - shows UI every time application goes into foreground
  • USB connected - shows UI every time an USB cable is plugged in
  • Airplane mode on - shows UI every time Airplane mode is turned on

Formatters

Data gathered and presented by Sentinel can be shared to any text compliant recipient applications. Sentinel provides a few simple text formatters for easy integrations into other systems. Plain formatter is selected by default, but selecting any other is persisted between sessions.

  • Plain
  • Markdown
  • JSON
  • XML
  • HTML

Crash monitor

Sentinel has a built in default uncaught exception handler and ANR observer. If switched on in settings, it will notify both in a form of a notification. Note that from Android 13 you need to give permission to the app to show notifications. Once tapped on this notification, a screen with details is shown. A complete list of crashes is persisted between sessions and available on demand.
Methods to react on these crashes in a graceful way are provided in Sentinel.

Sentinel.setExceptionHandler { _, exception ->
    println("Exception happened: ${exception.message}")
    exitProcess(exception.hashCode())
}

Sentinel.setAnrListener { exception ->
    println("ANR happened: ${exception.message}")
    exitProcess(exception.hashCode())
}

Bundle monitor

Sentinel monitors Bundle objects passed around the application mostly for size limit of 500kB, thus avoiding TransactionTooLarge exceptions.
In settings there are options to notify inside a running session, toggle specific variants or set the limit of Bundle size.
This monitor feature runs automatically for every Activity but if you wish to disable monitoring for a specific screen, you can do so in the AndroidManifest.xml by adding a meta-data node.

<activity
    android:name="com.example.ui.main.MainActivity"
    android:exported="false">
    <meta-data
      android:name="@string/sentinel_infinum_monitored"
      android:value="false" />
</activity>

Contributing

We believe that the community can help us improve and build better a product. Please refer to our contributing guide to learn about the types of contributions we accept and the process for submitting them.

To ensure that our community remains respectful and professional, we defined a code of conduct that we expect all contributors to follow.

For easier developing a sample application with proper implementations is provided. If you wish to add a new specific dependency wrapper tool, create a new module and set it up like the ones already provided. Then create a pull request.

We appreciate your interest and look forward to your contributions.

License

Copyright 2020 Infinum

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.

Credits

Maintained and sponsored by Infinum.