[
  {
    "path": ".gitignore",
    "content": "# Built application files\n*.apk\n*.ap_\n\n# Files for the ART/Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated files\nbin/\ngen/\nout/\n\n# Gradle files\n.gradle/\nbuild/\n\n# Local configuration file (sdk path, etc)\nlocal.properties\n\n# Proguard folder generated by Eclipse\nproguard/\n\n# Log Files\n*.log\n\n# Android Studio Navigation editor temp files\n.navigation/\n\n# Android Studio captures folder\ncaptures/\n\n# Intellij\n*.iml\n.idea\n\n# Keystore files\n*.jks\n\n# External native build folder generated in Android Studio 2.2 and later\n.externalNativeBuild\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2016-2019 PSPDFKit Labs\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# QuickDemo\n\n_QuickDemo_ is a Nougat 7.0 [quick settings tile](https://developer.android.com/about/versions/nougat/android-7.0.html#tile_api) for fast access to the Marshmallow 6.0 [System UI demo mode](https://android.googlesource.com/platform/frameworks/base/+/android-6.0.0_r1/packages/SystemUI/docs/demo_mode.md). The app also provides a configuration activity for customizing available demo mode settings.\n\nRelease blog post: https://pspdfkit.com/blog/2016/clean-statusbar-with-systemui-and-quickdemo/\n\n![QuickDemo in action](showcase.gif)\n\n## Requirements\n\n* Android SDK (API 25)\n* Android Studio 2.2+\n* `adb` (for installing the app and granting the required permissions)\n* Android emulator or devices running Marshmallow (API 23+)\n\n## Building\n\nTo build and run the app, you can open the project with Android Studio and press `Run`. Alternatively you can install the app from the command line.\n\n```bash\ngit clone git@github.com:PSPDFKit-labs/QuickDemo.git\ncd QuickDemo/\n./gradlew installDebug\n```\n\nYou can also run the [`setup.sh`](https://github.com/PSPDFKit-labs/QuickDemo/blob/master/setup.sh) script, wich will check for ANDROID_HOME, clone the project, and use Gradle to install and setup the tool. The script will also remove files of the project after installation.\n\n## Setup\n\n### With Gradle\n\nIf you cloned the project, you can run `setupDemoMode` gradle task to do the setup.\n\nThis can be done either by finding and selecting `setupDemoMode` in `Gradle` window in Android Studio, or by running the following:\n\n  ```bash\n  ./gradlew setupDemoMode\n  ```\n\n### Manually via adb\n\n1. When launching the app for the first time you need to grant the `android.permission.DUMP` permission, which is required to control the System UI demo mode. You need to do this using `adb`.\n\n  ```bash\n  adb shell pm grant com.pspdfkit.labs.quickdemo android.permission.DUMP\n  ```\n\n2. Since the System UI tuner (and its demo mode) is an experimental Android feature, you need to activate it globally.\n\n  ```bash\n  adb shell settings put global sysui_demo_allowed 1\n  ```\n  \n## Usage\n\n1. The app comes with a quick settings tile which you can use to quickly toggle the demo mode.  \n    1. Completely open the status bar drawer, expanding all quick setting tiles.\n    2. Press the edit button on top of the drawer, to show the quick setting tiles picker.\n    3. Drag the QuickDemo tile to your desired position.\n    4. Exit edit mode, and tap the tile.\n\n2. You can launch QuickDemo activity to configure all displayed icons of the demo mode.\n    1. You can find the activity in your app launcher.\n\n## Feedback and contribution\n\nSince this project is open source, feel free to use it, give feedback, or contribute in any way you find suitable.\n\n## About\n\n<a href=\"https://pspdfkit.com/\">\n  <img src=\"https://avatars2.githubusercontent.com/u/1527679?v=3&s=200\" height=\"80\" />\n</a>\n\nThis project is maintained and funded by [PSPDFKit](https://pspdfkit.com/).\n\nSee [our other open source projects](https://github.com/PSPDFKit-labs), read [our blog](https://pspdfkit.com/blog/) or say hello on Twitter ([@PSPDFKit](https://twitter.com/pspdfkit)).\n"
  },
  {
    "path": "app/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "app/build.gradle",
    "content": "/*\n *   Copyright (c) 2016-2019 PSPDFKit GmbH. All rights reserved.\n *\n *   THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW\n *   AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.\n *   UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.\n *   This notice may not be removed from this file\n */\n\napply plugin: 'com.android.application'\napply plugin: 'kotlin-android'\napply plugin: 'android-command'\n\nandroid {\n    compileSdkVersion 28\n    defaultConfig {\n        applicationId \"com.pspdfkit.labs.quickdemo\"\n        minSdkVersion 23\n        targetSdkVersion 28\n        versionCode 1\n        versionName \"1.0\"\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n    sourceSets {\n        main.java.srcDirs += 'src/main/kotlin'\n    }\n}\n\ndependencies {\n    androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', {\n        exclude group: 'com.android.support', module: 'support-annotations'\n    })\n    implementation \"org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version\"\n    implementation 'androidx.appcompat:appcompat:1.0.2'\n    implementation 'androidx.legacy:legacy-support-v4:1.0.0'\n\n    implementation 'io.reactivex.rxjava2:rxjava:2.2.4'\n    implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'\n\n    testImplementation 'junit:junit:4.12'\n}\n\ntask setupDemoMode(type: com.novoda.gradle.command.AdbTask) {\n    description 'Demo Mode initial setup'\n    doLast {\n        runCommand(['shell', 'settings', 'put', 'global', 'sysui_demo_allowed', '1'])\n        runCommand(['shell', 'pm', 'grant', 'com.pspdfkit.labs.quickdemo', 'android.permission.DUMP'])\n    }\n}\n"
  },
  {
    "path": "app/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/david/Library/Android/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n"
  },
  {
    "path": "app/src/androidTest/java/com/pspdfkit/labs/quickdemo/ExampleInstrumentedTest.kt",
    "content": "/*\n *   Copyright (c) 2016-2019 PSPDFKit GmbH. All rights reserved.\n *\n *   THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW\n *   AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.\n *   UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.\n *   This notice may not be removed from this file\n */\n\npackage com.pspdfkit.labs.quickdemo\n\nimport androidx.test.InstrumentationRegistry\nimport androidx.test.runner.AndroidJUnit4\nimport org.junit.Assert.assertEquals\nimport org.junit.Test\nimport org.junit.runner.RunWith\n\n/**\n * Instrumentation test, which will execute on an Android device.\n\n * @see [Testing documentation](http://d.android.com/tools/testing)\n */\n@RunWith(AndroidJUnit4::class)\nclass ExampleInstrumentedTest {\n    @Test\n    @Throws(Exception::class)\n    fun useAppContext() {\n        // Context of the app under test.\n        val appContext = InstrumentationRegistry.getTargetContext()\n\n        assertEquals(\"com.pspdfkit.demoqstile\", appContext.packageName)\n    }\n}\n"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~   Copyright (c) 2016-2019 PSPDFKit GmbH. All rights reserved.\n  ~\n  ~   THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW\n  ~   AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.\n  ~   UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.\n  ~   This notice may not be removed from this file\n  -->\n\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    package=\"com.pspdfkit.labs.quickdemo\">\n\n    <!-- Required to access the demo mode service. This permission can't be granted by the user at runtime. -->\n    <uses-permission\n        android:name=\"android.permission.DUMP\"\n        tools:ignore=\"ProtectedPermissions\" />\n\n    <!-- Allow collapsing of the notification tray after toggling the quick-settings tile. -->\n    <uses-permission android:name=\"android.permission.EXPAND_STATUS_BAR\" />\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@drawable/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\">\n        <service\n            android:name=\".service.DemoModeTileService\"\n            android:icon=\"@drawable/ic_demo_mode\"\n            android:label=\"@string/demo_mode_tile_title\"\n            android:permission=\"android.permission.BIND_QUICK_SETTINGS_TILE\">\n            <intent-filter>\n                <action android:name=\"android.service.quicksettings.action.QS_TILE\" />\n            </intent-filter>\n        </service>\n\n        <activity\n            android:name=\".activity.ConfigurationActivity\"\n            android:label=\"@string/title_activity_configuration\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n        <activity android:name=\".activity.SetupGuideActivity\" />\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "app/src/main/assets/setup-guide.html",
    "content": "<!DOCTYPE html>\n<!--\n  ~   Copyright (c) 2016-2019 PSPDFKit GmbH. All rights reserved.\n  ~\n  ~   THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW\n  ~   AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.\n  ~   UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.\n  ~   This notice may not be removed from this file\n  -->\n\n<html>\n\n<head>\n\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=yes\">\n<title>setup-guide</title>\n\n\n<style type=\"text/css\">\nbody {\n\tcolor: #333;\n\tfont: 16px/1.6 \"Helvetica Neue\", Helvetica, \"Segoe UI\", Arial, freesans, sans-serif;\n\tpadding: 30px;\n\tmargin: 0;\n\tword-wrap: break-word;\n}\n\nbody > *:first-child {\n\tmargin-top: 0 !important;\n}\n\nbody > *:last-child {\n\tmargin-bottom: 0 !important;\n}\n\na {\n\tbackground: transparent;\n\tcolor: #4183c4;\n\ttext-decoration: none;\n}\n\na:active,\na:hover {\n\toutline: 0 none;\n\ttext-decoration: underline;\n}\n\nabbr[title] {\n\tborder-bottom: 1px dotted;\n}\n\nb,\nstrong {\n\tfont-weight: bold;\n}\n\ndfn {\n\tfont-style: italic;\n}\nh1 {\n\tfont-size: 2em;\n\tmargin: 0.67em 0;\n}\nmark {\n\tbackground: #ff0;\n\tcolor: #000;\n}\nsmall {\n\tfont-size: 80%;\n}\nsub, sup {\n\tfont-size: 75%;\n\tline-height: 0;\n\tposition: relative;\n\tvertical-align: baseline;\n}\nsup {\n\ttop: -0.5em;\n}\nsub {\n\tbottom: -0.25em;\n}\nimg {\n\tborder: 0 none;\n}\nsvg:not(:root) {\n\toverflow: hidden;\n}\nfigure {\n\tmargin: 1em 40px;\n}\nhr {\n\tbox-sizing: content-box;\n\theight: 0;\n}\n\ncode,\nkbd,\npre,\nsamp {\n\tfont-family: monospace,monospace;\n\tfont-size: 1em;\n}\n\npre {\n\toverflow: auto;\n\tfont: 12px Consolas,\"Liberation Mono\",Menlo,Courier,monospace;\n\tmargin-bottom: 0;\n\tmargin-top: 0;\n}\n\n.absent {\n\tcolor: #c00;\n}\n\n.anchor {\n\tposition: absolute;\n\ttop: 0;\n\tbottom: 0;\n\tleft: 0;\n\tdisplay: block;\n\tpadding-right: 6px;\n\tpadding-left: 30px;\n\tmargin-left: -30px;\n}\n\n.anchor:focus {\n\toutline: none;\n}\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n\tposition: relative;\n\tmargin-top: 1em;\n\tmargin-bottom: 16px;\n\tfont-weight: bold;\n\tline-height: 1.4;\n}\n\nh1 .octicon-link,\nh2 .octicon-link,\nh3 .octicon-link,\nh4 .octicon-link,\nh5 .octicon-link,\nh6 .octicon-link {\n\tdisplay: none;\n\tcolor: #000;\n\tvertical-align: middle;\n}\n\nh1:hover .anchor,\nh2:hover .anchor,\nh3:hover .anchor,\nh4:hover .anchor,\nh5:hover .anchor,\nh6:hover .anchor {\n\tpadding-left: 8px;\n\tmargin-left: -30px;\n\tline-height: 1;\n\ttext-decoration: none;\n}\n\nh1:hover .anchor .octicon-link,\nh2:hover .anchor .octicon-link,\nh3:hover .anchor .octicon-link,\nh4:hover .anchor .octicon-link,\nh5:hover .anchor .octicon-link,\nh6:hover .anchor .octicon-link {\n\tdisplay: inline-block;\n}\n\nh1 tt,\nh1 code,\nh2 tt,\nh2 code,\nh3 tt,\nh3 code,\nh4 tt,\nh4 code,\nh5 tt,\nh5 code,\nh6 tt,\nh6 code {\n\tfont-size: inherit;\n}\n\nh1 {\n\tpadding-bottom: 0.3em;\n\tfont-size: 2.25em;\n\tline-height: 1.2;\n\tborder-bottom: 1px solid #eee;\n}\n\nh2 {\n\tpadding-bottom: 0.3em;\n\tfont-size: 1.75em;\n\tline-height: 1.225;\n\tborder-bottom: 1px solid #eee;\n}\n\nh3 {\n\tfont-size: 1.5em;\n\tline-height: 1.43;\n}\n\nh4 {\n\tfont-size: 1.25em;\n}\n\nh5 {\n\tfont-size: 1em;\n}\n\nh6 {\n\tfont-size: 1em;\n\tcolor: #777;\n}\n\np,blockquote,\nul,ol,\ndl,table,\npre {\n\tmargin-top: 0;\n\tmargin-bottom: 16px;\n}\n\nhr {\n\theight: 4px;\n\tpadding: 0;\n\tmargin: 16px 0;\n\tbackground-color: #e7e7e7;\n\tborder: 0 none;\n}\n\nul,\nol {\n\tpadding-left: 2em;\n}\n\nul.no-list,\nol.no-list {\n\tpadding: 0;\n\tlist-style-type: none;\n}\n\nul ul,\nul ol,\nol ol,\nol ul {\n\tmargin-top: 0;\n\tmargin-bottom: 0;\n}\n\nli>p {\n\tmargin-top: 16px;\n}\n\ndl {\n\tpadding: 0;\n}\n\ndl dt {\n\tpadding: 0;\n\tmargin-top: 16px;\n\tfont-size: 1em;\n\tfont-style: italic;\n\tfont-weight: bold;\n}\n\ndl dd {\n\tpadding: 0 16px;\n\tmargin-bottom: 16px;\n}\n\nblockquote {\n\tpadding: 0 15px;\n\tcolor: #777;\n\tborder-left: 4px solid #ddd;\n}\n\nblockquote>:first-child {\n\tmargin-top: 0;\n}\n\nblockquote>:last-child {\n\tmargin-bottom: 0;\n}\n\ntable {\n\tdisplay: block;\n\twidth: 100%;\n\toverflow: auto;\n\tword-break: keep-all;\n}\n\ntable th {\n\tfont-weight: bold;\n}\n\ntable th,\ntable td {\n\tpadding: 6px 13px;\n\tborder: 1px solid #ddd;\n}\n\ntable tr {\n\tbackground-color: #fff;\n\tborder-top: 1px solid #ccc;\n}\n\ntable tr:nth-child(2n) {\n\tbackground-color: #f8f8f8;\n}\n\nimg {\n\tmax-width: 100%;\n\t-moz-box-sizing: border-box;\n\tbox-sizing: border-box;\n}\n\nspan.frame {\n\tdisplay: block;\n\toverflow: hidden;\n}\n\nspan.frame>span {\n\tdisplay: block;\n\tfloat: left;\n\twidth: auto;\n\tpadding: 7px;\n\tmargin: 13px 0 0;\n\toverflow: hidden;\n\tborder: 1px solid #ddd;\n}\n\nspan.frame span img {\n\tdisplay: block;\n\tfloat: left;\n}\n\nspan.frame span span {\n\tdisplay: block;\n\tpadding: 5px 0 0;\n\tclear: both;\n\tcolor: #333;\n}\n\nspan.align-center {\n\tdisplay: block;\n\toverflow: hidden;\n\tclear: both;\n}\n\nspan.align-center>span {\n\tdisplay: block;\n\tmargin: 13px auto 0;\n\toverflow: hidden;\n\ttext-align: center;\n}\n\nspan.align-center span img {\n\tmargin: 0 auto;\n\ttext-align: center;\n}\n\nspan.align-right {\n\tdisplay: block;\n\toverflow: hidden;\n\tclear: both;\n}\n\nspan.align-right>span {\n\tdisplay: block;\n\tmargin: 13px 0 0;\n\toverflow: hidden;\n\ttext-align: right;\n}\n\nspan.align-right span img {\n\tmargin: 0;\n\ttext-align: right;\n}\n\nspan.float-left {\n\tdisplay: block;\n\tfloat: left;\n\tmargin-right: 13px;\n\toverflow: hidden;\n}\n\nspan.float-left span {\n\tmargin: 13px 0 0;\n}\n\nspan.float-right {\n\tdisplay: block;\n\tfloat: right;\n\tmargin-left: 13px;\n\toverflow: hidden;\n}\n\nspan.float-right>span {\n\tdisplay: block;\n\tmargin: 13px auto 0;\n\toverflow: hidden;\n\ttext-align: right;\n}\n\ncode,tt {\n\tpadding: 0.2em 0;\n\tmargin: 0;\n\tfont-size: 85%;\n\tbackground-color: rgba(0,0,0,0.04);\n\tborder-radius: 3px;\n}\n\ncode:before,\ncode:after,\ntt:before,\ntt:after {\n\tletter-spacing: -0.2em;\n\tcontent: \"\\00a0\";\n}\n\ncode br,\ntt br {\n\tdisplay: none;\n}\n\ndel code {\n\ttext-decoration: inherit;\n}\n\npre>code {\n\tpadding: 0;\n\tmargin: 0;\n\tfont-size: 100%;\n\tword-break: normal;\n\twhite-space: pre;\n\tbackground: transparent;\n\tborder: 0;\n}\n\n.highlight {\n\tmargin-bottom: 16px;\n}\n\n.highlight pre,\npre {\n\tpadding: 16px;\n\toverflow: auto;\n\tfont-size: 85%;\n\tline-height: 1.45;\n\tbackground-color: #f7f7f7;\n\tborder-radius: 3px;\n}\n\n.highlight pre {\n\tmargin-bottom: 0;\n\tword-break: normal;\n}\n\npre {\n\tword-wrap: normal;\n}\n\npre code,\npre tt {\n\tdisplay: inline;\n\tmax-width: initial;\n\tpadding: 0;\n\tmargin: 0;\n\toverflow: initial;\n\tline-height: inherit;\n\tword-wrap: normal;\n\tbackground-color: transparent;\n\tborder: 0;\n}\n\npre code:before,\npre code:after,\npre tt:before,\npre tt:after {\n\tcontent: normal;\n}\n\n.highlight .pl-coc,\n.highlight .pl-entl,\n.highlight .pl-entm,\n.highlight .pl-eoa,\n.highlight .pl-mai .pl-sf,\n.highlight .pl-mm,\n.highlight .pl-pdv,\n.highlight .pl-sc,\n.highlight .pl-som,\n.highlight .pl-sr,\n.highlight .pl-v,\n.highlight .pl-vpf {\n\tcolor: #0086b3;\n}\n.highlight .pl-eoac,\n.highlight .pl-mdht,\n.highlight .pl-mi1,\n.highlight .pl-mri,\n.highlight .pl-va,\n.highlight .pl-vpu {\n\tcolor: #008080;\n}\n.highlight .pl-c,\n.highlight .pl-pdc {\n\tcolor: #b4b7b4;\n\tfont-style: italic;\n}\n.highlight .pl-k,\n.highlight .pl-ko,\n.highlight .pl-kolp,\n.highlight .pl-mc,\n.highlight .pl-mr,\n.highlight .pl-ms,\n.highlight .pl-s,\n.highlight .pl-sok,\n.highlight .pl-st {\n\tcolor: #6e5494;\n}\n.highlight .pl-ef,\n.highlight .pl-enf,\n.highlight .pl-enm,\n.highlight .pl-entc,\n.highlight .pl-eoi,\n.highlight .pl-sf,\n.highlight .pl-smc {\n\tcolor: #d12089;\n}\n.highlight .pl-ens,\n.highlight .pl-eoai,\n.highlight .pl-kos,\n.highlight .pl-mh .pl-pdh,\n.highlight .pl-mp,\n.highlight .pl-pde,\n.highlight .pl-stp {\n\tcolor: #458;\n}\n.highlight .pl-enti {\n\tcolor: #d12089;\n\tfont-weight: bold;\n}\n.highlight .pl-cce,\n.highlight .pl-enc,\n.highlight .pl-kou,\n.highlight .pl-mq {\n\tcolor: #f93;\n}\n.highlight .pl-mp1 .pl-sf {\n\tcolor: #458;\n\tfont-weight: bold;\n}\n.highlight .pl-cos,\n.highlight .pl-ent,\n.highlight .pl-md,\n.highlight .pl-mdhf,\n.highlight .pl-ml,\n.highlight .pl-pdc1,\n.highlight .pl-pds,\n.highlight .pl-s1,\n.highlight .pl-scp,\n.highlight .pl-sol {\n\tcolor: #df5000;\n}\n.highlight .pl-c1,\n.highlight .pl-cn,\n.highlight .pl-pse,\n.highlight .pl-pse .pl-s2,\n.highlight .pl-vi {\n\tcolor: #a31515;\n}\n.highlight .pl-mb,\n.highlight .pl-pdb {\n\tcolor: #df5000;\n\tfont-weight: bold;\n}\n.highlight .pl-mi,\n.highlight .pl-pdi {\n\tcolor: #6e5494;\n\tfont-style: italic;\n}\n.highlight .pl-ms1 {\n\tbackground-color: #f5f5f5;\n}\n.highlight .pl-mdh,\n.highlight .pl-mdi {\n\tfont-weight: bold;\n}\n.highlight .pl-mdr {\n\tcolor: #0086b3;\n\tfont-weight: bold;\n}\n.highlight .pl-s2 {\n\tcolor: #333;\n}\n.highlight .pl-ii {\n\tbackground-color: #df5000;\n\tcolor: #fff;\n}\n.highlight .pl-ib {\n\tbackground-color: #f93;\n}\n.highlight .pl-id {\n\tbackground-color: #a31515;\n\tcolor: #fff;\n}\n.highlight .pl-iu {\n\tbackground-color: #b4b7b4;\n}\n.highlight .pl-mo {\n\tcolor: #969896;\n}\n</style>\n\n<style type=\"text/css\">\n/**\n * prism.js default theme for JavaScript, CSS and HTML\n * Based on dabblet (http://dabblet.com)\n * @author Lea Verou\n */\n\ncode[class*=\"language-\"],\npre[class*=\"language-\"] {\n\tcolor: black;\n\tbackground: none;\n\ttext-shadow: 0 1px white;\n\tfont-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;\n\ttext-align: left;\n\twhite-space: pre;\n\tword-spacing: normal;\n\tword-break: normal;\n\tword-wrap: normal;\n\tline-height: 1.5;\n\n\t-moz-tab-size: 4;\n\t-o-tab-size: 4;\n\ttab-size: 4;\n\n\t-webkit-hyphens: none;\n\t-moz-hyphens: none;\n\t-ms-hyphens: none;\n\thyphens: none;\n}\n\npre[class*=\"language-\"]::-moz-selection, pre[class*=\"language-\"] ::-moz-selection,\ncode[class*=\"language-\"]::-moz-selection, code[class*=\"language-\"] ::-moz-selection {\n\ttext-shadow: none;\n\tbackground: #b3d4fc;\n}\n\npre[class*=\"language-\"]::selection, pre[class*=\"language-\"] ::selection,\ncode[class*=\"language-\"]::selection, code[class*=\"language-\"] ::selection {\n\ttext-shadow: none;\n\tbackground: #b3d4fc;\n}\n\n@media print {\n\tcode[class*=\"language-\"],\n\tpre[class*=\"language-\"] {\n\t\ttext-shadow: none;\n\t}\n}\n\n/* Code blocks */\npre[class*=\"language-\"] {\n\tpadding: 1em;\n\tmargin: .5em 0;\n\toverflow: auto;\n}\n\n:not(pre) > code[class*=\"language-\"],\npre[class*=\"language-\"] {\n\tbackground: #f5f2f0;\n}\n\n/* Inline code */\n:not(pre) > code[class*=\"language-\"] {\n\tpadding: .1em;\n\tborder-radius: .3em;\n\twhite-space: normal;\n}\n\n.token.comment,\n.token.prolog,\n.token.doctype,\n.token.cdata {\n\tcolor: slategray;\n}\n\n.token.punctuation {\n\tcolor: #999;\n}\n\n.namespace {\n\topacity: .7;\n}\n\n.token.property,\n.token.tag,\n.token.boolean,\n.token.number,\n.token.constant,\n.token.symbol,\n.token.deleted {\n\tcolor: #905;\n}\n\n.token.selector,\n.token.attr-name,\n.token.string,\n.token.char,\n.token.builtin,\n.token.inserted {\n\tcolor: #690;\n}\n\n.token.operator,\n.token.entity,\n.token.url,\n.language-css .token.string,\n.style .token.string {\n\tcolor: #a67f59;\n\tbackground: hsla(0, 0%, 100%, .5);\n}\n\n.token.atrule,\n.token.attr-value,\n.token.keyword {\n\tcolor: #07a;\n}\n\n.token.function {\n\tcolor: #DD4A68;\n}\n\n.token.regex,\n.token.important,\n.token.variable {\n\tcolor: #e90;\n}\n\n.token.important,\n.token.bold {\n\tfont-weight: bold;\n}\n.token.italic {\n\tfont-style: italic;\n}\n\n.token.entity {\n\tcursor: help;\n}\n</style>\n\n\n</head>\n\n<body>\n\n<p><strong><em>QuickDemo is a tool for Android developers. If you don&#39;t know what this application is for, do not use it!</em></strong></p>\n\n<h2 id=\"toc_0\">Setup</h2>\n\n<p>To enable <em>QuickDemo</em> you need to do two things.</p>\n\n<ol>\n<li>Enable the System UI demo mode on your phone.</li>\n<li>Grant the <code>android.permission.DUMP</code> to the QuickDemo app. This permissions is protected and can&#39;t be requested at runtime.</li>\n</ol>\n\n<p>This can be achieved by running the following <code>gradle</code> task.</p>\n\n<div><pre><code class=\"language-none\">./gradlew setupDemoMode</code></pre></div>\n\n<p>If you don&#39;t have the project. Both steps can be performed manually from command line via <code>adb</code>.</p>\n\n<div><pre><code class=\"language-none\"># Ensure demo mode is activated.\nadb shell settings put global sysui_demo_allowed 1\n\n# Grant required permissions.\nadb shell pm grant com.pspdfkit.labs.quickdemo android.permission.DUMP</code></pre></div>\n\n<p><strong>Please note:</strong> The permissions is granted until you revoke it or uninstall the app.</p>\n\n<script type=\"text/javascript\">\nvar _self=\"undefined\"!=typeof window?window:\"undefined\"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(){var e=/\\blang(?:uage)?-(\\w+)\\b/i,t=0,n=_self.Prism={util:{encode:function(e){return e instanceof a?new a(e.type,n.util.encode(e.content),e.alias):\"Array\"===n.util.type(e)?e.map(n.util.encode):e.replace(/&/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/\\u00a0/g,\" \")},type:function(e){return Object.prototype.toString.call(e).match(/\\[object (\\w+)\\]/)[1]},objId:function(e){return e.__id||Object.defineProperty(e,\"__id\",{value:++t}),e.__id},clone:function(e){var t=n.util.type(e);switch(t){case\"Object\":var a={};for(var r in e)e.hasOwnProperty(r)&&(a[r]=n.util.clone(e[r]));return a;case\"Array\":return e.map&&e.map(function(e){return n.util.clone(e)})}return e}},languages:{extend:function(e,t){var a=n.util.clone(n.languages[e]);for(var r in t)a[r]=t[r];return a},insertBefore:function(e,t,a,r){r=r||n.languages;var l=r[e];if(2==arguments.length){a=arguments[1];for(var i in a)a.hasOwnProperty(i)&&(l[i]=a[i]);return l}var o={};for(var s in l)if(l.hasOwnProperty(s)){if(s==t)for(var i in a)a.hasOwnProperty(i)&&(o[i]=a[i]);o[s]=l[s]}return n.languages.DFS(n.languages,function(t,n){n===r[e]&&t!=e&&(this[t]=o)}),r[e]=o},DFS:function(e,t,a,r){r=r||{};for(var l in e)e.hasOwnProperty(l)&&(t.call(e,l,e[l],a||l),\"Object\"!==n.util.type(e[l])||r[n.util.objId(e[l])]?\"Array\"!==n.util.type(e[l])||r[n.util.objId(e[l])]||(r[n.util.objId(e[l])]=!0,n.languages.DFS(e[l],t,l,r)):(r[n.util.objId(e[l])]=!0,n.languages.DFS(e[l],t,null,r)))}},plugins:{},highlightAll:function(e,t){var a={callback:t,selector:'code[class*=\"language-\"], [class*=\"language-\"] code, code[class*=\"lang-\"], [class*=\"lang-\"] code'};n.hooks.run(\"before-highlightall\",a);for(var r,l=a.elements||document.querySelectorAll(a.selector),i=0;r=l[i++];)n.highlightElement(r,e===!0,a.callback)},highlightElement:function(t,a,r){for(var l,i,o=t;o&&!e.test(o.className);)o=o.parentNode;o&&(l=(o.className.match(e)||[,\"\"])[1],i=n.languages[l]),t.className=t.className.replace(e,\"\").replace(/\\s+/g,\" \")+\" language-\"+l,o=t.parentNode,/pre/i.test(o.nodeName)&&(o.className=o.className.replace(e,\"\").replace(/\\s+/g,\" \")+\" language-\"+l);var s=t.textContent,u={element:t,language:l,grammar:i,code:s};if(!s||!i)return n.hooks.run(\"complete\",u),void 0;if(n.hooks.run(\"before-highlight\",u),a&&_self.Worker){var c=new Worker(n.filename);c.onmessage=function(e){u.highlightedCode=e.data,n.hooks.run(\"before-insert\",u),u.element.innerHTML=u.highlightedCode,r&&r.call(u.element),n.hooks.run(\"after-highlight\",u),n.hooks.run(\"complete\",u)},c.postMessage(JSON.stringify({language:u.language,code:u.code,immediateClose:!0}))}else u.highlightedCode=n.highlight(u.code,u.grammar,u.language),n.hooks.run(\"before-insert\",u),u.element.innerHTML=u.highlightedCode,r&&r.call(t),n.hooks.run(\"after-highlight\",u),n.hooks.run(\"complete\",u)},highlight:function(e,t,r){var l=n.tokenize(e,t);return a.stringify(n.util.encode(l),r)},tokenize:function(e,t){var a=n.Token,r=[e],l=t.rest;if(l){for(var i in l)t[i]=l[i];delete t.rest}e:for(var i in t)if(t.hasOwnProperty(i)&&t[i]){var o=t[i];o=\"Array\"===n.util.type(o)?o:[o];for(var s=0;s<o.length;++s){var u=o[s],c=u.inside,g=!!u.lookbehind,h=!!u.greedy,f=0,d=u.alias;u=u.pattern||u;for(var p=0;p<r.length;p++){var m=r[p];if(r.length>e.length)break e;if(!(m instanceof a)){u.lastIndex=0;var y=u.exec(m),v=1;if(!y&&h&&p!=r.length-1){var b=r[p+1].matchedStr||r[p+1],k=m+b;if(p<r.length-2&&(k+=r[p+2].matchedStr||r[p+2]),u.lastIndex=0,y=u.exec(k),!y)continue;var w=y.index+(g?y[1].length:0);if(w>=m.length)continue;var _=y.index+y[0].length,P=m.length+b.length;if(v=3,P>=_){if(r[p+1].greedy)continue;v=2,k=k.slice(0,P)}m=k}if(y){g&&(f=y[1].length);var w=y.index+f,y=y[0].slice(f),_=w+y.length,S=m.slice(0,w),O=m.slice(_),j=[p,v];S&&j.push(S);var A=new a(i,c?n.tokenize(y,c):y,d,y,h);j.push(A),O&&j.push(O),Array.prototype.splice.apply(r,j)}}}}}return r},hooks:{all:{},add:function(e,t){var a=n.hooks.all;a[e]=a[e]||[],a[e].push(t)},run:function(e,t){var a=n.hooks.all[e];if(a&&a.length)for(var r,l=0;r=a[l++];)r(t)}}},a=n.Token=function(e,t,n,a,r){this.type=e,this.content=t,this.alias=n,this.matchedStr=a||null,this.greedy=!!r};if(a.stringify=function(e,t,r){if(\"string\"==typeof e)return e;if(\"Array\"===n.util.type(e))return e.map(function(n){return a.stringify(n,t,e)}).join(\"\");var l={type:e.type,content:a.stringify(e.content,t,r),tag:\"span\",classes:[\"token\",e.type],attributes:{},language:t,parent:r};if(\"comment\"==l.type&&(l.attributes.spellcheck=\"true\"),e.alias){var i=\"Array\"===n.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(l.classes,i)}n.hooks.run(\"wrap\",l);var o=\"\";for(var s in l.attributes)o+=(o?\" \":\"\")+s+'=\"'+(l.attributes[s]||\"\")+'\"';return\"<\"+l.tag+' class=\"'+l.classes.join(\" \")+'\" '+o+\">\"+l.content+\"</\"+l.tag+\">\"},!_self.document)return _self.addEventListener?(_self.addEventListener(\"message\",function(e){var t=JSON.parse(e.data),a=t.language,r=t.code,l=t.immediateClose;_self.postMessage(n.highlight(r,n.languages[a],a)),l&&_self.close()},!1),_self.Prism):_self.Prism;var r=document.currentScript||[].slice.call(document.getElementsByTagName(\"script\")).pop();return r&&(n.filename=r.src,document.addEventListener&&!r.hasAttribute(\"data-manual\")&&document.addEventListener(\"DOMContentLoaded\",n.highlightAll)),_self.Prism}();\"undefined\"!=typeof module&&module.exports&&(module.exports=Prism),\"undefined\"!=typeof global&&(global.Prism=Prism);\n</script>\n\n\n</body>\n\n</html>\n"
  },
  {
    "path": "app/src/main/kotlin/com/pspdfkit/labs/quickdemo/DemoMode.kt",
    "content": "/*\n *   Copyright (c) 2016-2019 PSPDFKit GmbH. All rights reserved.\n *\n *   THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW\n *   AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.\n *   UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.\n *   This notice may not be removed from this file\n */\n\npackage com.pspdfkit.labs.quickdemo\n\nimport android.content.Context\nimport android.content.Intent\nimport android.content.SharedPreferences\nimport android.content.pm.PackageManager\nimport android.preference.PreferenceManager\nimport android.provider.Settings\nimport androidx.core.content.ContextCompat\nimport kotlin.properties.ReadWriteProperty\nimport kotlin.reflect.KProperty\n\nclass DemoMode private constructor(context: Context) {\n    private val applicationContext: Context = context.applicationContext\n    private val sharedPreferences: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)\n    private val demoModeProperties = mutableSetOf<DemoModeProperty<out Any>>()\n\n    companion object {\n        private var singleton: DemoMode? = null\n\n        /** Returns the demo mode singleton */\n        fun get(context: Context): DemoMode {\n            var demoMode = singleton\n            if (demoMode == null) {\n                demoMode = DemoMode(context)\n                singleton = demoMode\n            }\n\n            return demoMode\n        }\n\n        const val DEFAULT_MOBILE_DATATYPE = \"hidden\"\n        const val DEFAULT_MOBILE_LEVEL = 4\n        const val DEFAULT_WIFI_LEVEL = 4\n        const val DEFAULT_NETWORK_NUM_OF_SIMS = 1\n        const val DEFAULT_STATUS_BAR_MODE = \"transparent\"\n        const val DEFAULT_BATTERY_LEVEL = 100\n        const val DEFAULT_STATUS_HIDDEN = \"hidden\"\n    }\n\n    /** Returns `true` if the required permissions to send out demo mode broadcasts are available, or `false` if they need to be requested first. */\n    val requiredPermissionsGranted: Boolean\n        get() = ContextCompat.checkSelfPermission(applicationContext, \"android.permission.DUMP\") == PackageManager.PERMISSION_GRANTED\n\n    /** Returns `true` if the demo mode has been activated in system UI. **/\n    val demoModeAllowed: Boolean\n        get() = Settings.Global.getInt(applicationContext.contentResolver, \"sysui_demo_allowed\", 0) == 1\n\n    /**\n     * Enables or disables the demo mode. If this is set to `false`, no other demo mode settings will have effect.\n     */\n    var enabled: Boolean\n        get() = sharedPreferences.getBoolean(\"demoEnabled\", false)\n        set(value) {\n            sharedPreferences.edit().putBoolean(\"demoEnabled\", value).commit()\n\n            if (value) {\n                sendDemoCommand(\"enter\")\n                for (property in demoModeProperties) {\n                    property.issueDemoModeCommand()\n                }\n            } else {\n                sendDemoCommand(\"exit\")\n            }\n\n        }\n\n    /**\n     * If set to `true`, all notifications get hidden.\n     */\n    var hideNotifications by booleanPreference(\"hideNotifications\", true) { value ->\n        if (enabled) sendDemoCommand(\"notifications\", \"visible\" to !value)\n    }\n\n    /**\n     * Sets the time in the format of `hhmm`.\n     */\n    var time by stringPreference(\"time\", \"0700\") { value ->\n        if (enabled) sendDemoCommand(\"clock\", \"hhmm\" to value)\n    }\n\n    /**\n     * Can be set to any of `opaque`, `translucent`, `semi-transparent`, `transparent`, or `warning`.\n     */\n    var statusBarMode by stringPreference(\"statusBarMode\", DEFAULT_STATUS_BAR_MODE) { value ->\n        if (enabled) sendDemoCommand(\"bars\", \"mode\" to value)\n    }\n\n    /**\n     * Configure the network display (Wi-Fi, mobile, airplane, etc.).\n     */\n    val network = Network()\n\n    inner class Network {\n        /**\n         * Enables or disables airplane mode. Disabled by default.\n         */\n        var showAirplane by booleanPreference(\"networkShowAirplane\", false) { value ->\n            if (enabled) sendDemoCommand(\"network\", \"airplane\" to if (value) \"show\" else \"hide\")\n        }\n\n        /**\n         * Enables or disables full network connectivity mode. Enabled by default.\n         */\n        var fullConnectivity by booleanPreference(\"networkFullConnectivity\", true) { value ->\n            if (enabled) sendDemoCommand(\"network\", \"fully\" to value)\n        }\n\n        /**\n         * Shows or hides the Wi-Fi icon. Hidden by default.\n         */\n        var showWifi by booleanPreference(\"networkShowWifi\", false) { value ->\n            if (enabled) sendDemoCommand(\"network\", \"wifi\" to if (value) \"show\" else \"hide\")\n        }\n\n        /**\n         * Sets the Wi-Fi connection level. Can be an integer from `0` (no reception) to `4` (full reception). Defaults to `4`.\n         */\n        var wifiLevel by intPreference(\"networkWifiLevel\", DEFAULT_WIFI_LEVEL) { value ->\n            if (enabled && showWifi) sendDemoCommand(\"network\", \"wifi\" to \"show\", \"level\" to value)\n        }\n\n        /**\n         * Shows or hides the mobile network icon. Shown by default.\n         */\n        var mobileShown by booleanPreference(\"networkMobileShown\", true) { value ->\n            if (enabled) sendDemoCommand(\"network\", \"mobile\" to if (value) \"show\" else \"hide\")\n        }\n\n        /**\n         * Sets the mobile network level. Can be an integer from `0` (no reception) to `4` (full reception). Defaults to `4`.\n         */\n        var mobileLevel by intPreference(\"networkMobileLevel\", DEFAULT_MOBILE_LEVEL) { value ->\n            if (enabled && mobileShown) sendDemoCommand(\"network\", \"mobile\" to \"show\", \"level\" to value)\n        }\n\n        /**\n         * Sets the mobile network connection type. Can be any of `1x`, `3g`, `4g`, `e`, `g`, `h`, `lte`, `roam`, or any other value to hide. Defaults to `lte`.\n         */\n        var mobileDatatype by stringPreference(\"networkMobileDatatype\", DEFAULT_MOBILE_DATATYPE) { value ->\n            if (enabled && mobileShown) sendDemoCommand(\"network\", \"mobile\" to \"show\", \"datatype\" to value)\n        }\n\n        /**\n         * Sets mobile signal icon to carrier network change UX when disconnected. Disabled by default.\n         */\n        var showCarrierNetworkChange by booleanPreference(\"networkCarrierNetworkChange\", false) { value ->\n            if (enabled) sendDemoCommand(\"network\", \"carriernetworkchange\" to if (value) \"show\" else \"hide\")\n        }\n\n        /**\n         * Sets the number of used SIMs. Can be an integer from `1` to `8`. Defaults to `1`.\n         */\n        var numberOfSims by intPreference(\"networkNumberOfSims\", DEFAULT_NETWORK_NUM_OF_SIMS) { value ->\n            if (enabled) sendDemoCommand(\"network\", \"sims\" to value)\n        }\n\n        /**\n         * Show or hide the \"no SIM\" icon. Hidden by default.\n         */\n        var showNoSim by booleanPreference(\"networkShowNoSim\", false) { value ->\n            if (enabled) sendDemoCommand(\"network\", \"nosim\" to if (value) \"show\" else \"hide\")\n        }\n    }\n\n    /**\n     * Configure the status icons (alarm, volume, bluetooth, etc.)\n     */\n    val status = Status()\n\n    inner class Status {\n        /**\n         * Sets the volume icon. Can be any of `silent`, `vibrate`, or any other value to hide the icon. Hidden by default.\n         */\n        var volume by stringPreference(\"statusVolume\", DEFAULT_STATUS_HIDDEN) { value ->\n            if (enabled) sendDemoCommand(\"status\", \"volume\" to value)\n        }\n\n        /**\n         * Sets the bluetooth icon. Can be any of `connected`, `disconnected`, `hidden`. Hidden by default.\n         */\n        var bluetooth by stringPreference(\"statusBluetooth\", DEFAULT_STATUS_HIDDEN, { value ->\n            if (enabled) sendDemoCommand(\"status\", \"bluetooth\" to value)\n        })\n\n        /**\n         * Shows or hides the icon in the location slot. Hidden by default.\n         */\n        var showLocation by booleanPreference(\"statusLocation\", false) { value ->\n            if (enabled) sendDemoCommand(\"status\", \"location\" to if (value) \"show\" else \"hide\")\n        }\n\n        /**\n         * Shows or hides the alarm clock icon. Hidden by default.\n         */\n        var showAlarm by booleanPreference(\"statusAlarm\", false) { value ->\n            if (enabled) sendDemoCommand(\"status\", \"alarm\" to if (value) \"show\" else \"hide\")\n        }\n\n        /**\n         * Shows or hides the sync icon. Hidden by default.\n         */\n        var showSync by booleanPreference(\"statusSync\", false) { value ->\n            if (enabled) sendDemoCommand(\"status\", \"sync\" to if (value) \"show\" else \"hide\")\n        }\n\n        /**\n         * Shows or hides the TTY icon. Hidden by default.\n         */\n        var showTty by booleanPreference(\"statusTty\", false) { value ->\n            if (enabled) sendDemoCommand(\"status\", \"tty\" to if (value) \"show\" else \"hide\")\n        }\n\n        /**\n         * Shows or hides the CDMA ERI icon. Hidden by default.\n         */\n        var showEri by booleanPreference(\"statusEri\", false) { value ->\n            if (enabled) sendDemoCommand(\"status\", \"eri\" to if (value) \"show\" else \"hide\")\n        }\n\n        /**\n         * Shows or hides the mute icon. Hidden by default.\n         */\n        var showMute by booleanPreference(\"statusMute\", false) { value ->\n            if (enabled) sendDemoCommand(\"status\", \"mute\" to if (value) \"show\" else \"hide\")\n        }\n\n        /**\n         * Shows or hides the speakerphone icon. Hidden by default.\n         */\n        var showSpeakerphone by booleanPreference(\"statusSpeakerphone\", false) { value ->\n            if (enabled) sendDemoCommand(\"status\", \"speakerphone\" to if (value) \"show\" else \"hide\")\n        }\n    }\n\n    /**\n     * Configure the battery display.\n     */\n    val battery = Battery()\n\n    inner class Battery() {\n        /**\n         * Sets the shown battery level. Can be an integer from `0` (depleted) to `100` (fully charged). Defaults to `100`.\n         */\n        var level by intPreference(\"batteryLevel\", DEFAULT_BATTERY_LEVEL) { value ->\n            if (enabled) sendDemoCommand(\"battery\", \"level\" to value)\n        }\n\n        /**\n         * Enables or disables the battery being shown as being plugged in and charging. Defaults to `false`.\n         */\n        var plugged by booleanPreference(\"batteryPlugged\", false) { value ->\n            if (enabled) sendDemoCommand(\"battery\", \"plugged\" to value)\n        }\n\n        /**\n         * Enables or disables the device's power save mode. Defaults to `false`.\n         */\n        var powersave by booleanPreference(\"batteryPowersave\", default = false) { value ->\n            if (enabled) sendDemoCommand(\"battery\", \"powersave\" to value)\n        }\n    }\n\n    private fun sendDemoCommand(command: String, vararg extras: Pair<String, Any>) {\n        val intent = Intent(\"com.android.systemui.demo\").apply {\n            putExtra(\"command\", command)\n            for ((key, value) in extras) {\n                putExtra(key, value.toString())\n            }\n        }\n\n        applicationContext.sendBroadcast(intent)\n    }\n\n    abstract class DemoModeProperty<T> : ReadWriteProperty<Any, T>, SharedPreferences.OnSharedPreferenceChangeListener {\n        abstract val key: String\n        abstract fun issueDemoModeCommand()\n        abstract fun getStoredValue(): T\n        override fun getValue(thisRef: Any, property: KProperty<*>) = getStoredValue()\n        override fun onSharedPreferenceChanged(p0: SharedPreferences?, changedKey: String?) {\n            if (key == changedKey) issueDemoModeCommand()\n        }\n    }\n\n    fun booleanPreference(key: String, default: Boolean, onSendCommand: (Boolean) -> Unit) = object : DemoModeProperty<Boolean>() {\n        override val key = key\n        override fun issueDemoModeCommand() = onSendCommand(getStoredValue())\n        override fun getStoredValue() = sharedPreferences.getBoolean(key, default)\n        override fun setValue(thisRef: Any, property: KProperty<*>, value: Boolean) {\n            sharedPreferences.edit().putBoolean(key, value).apply()\n        }\n    }.apply {\n        sharedPreferences.registerOnSharedPreferenceChangeListener(this)\n        demoModeProperties.add(this)\n    }\n\n    fun intPreference(key: String, default: Int, onSendCommand: (Int) -> Unit) = object : DemoModeProperty<Int>() {\n        override val key = key\n        override fun issueDemoModeCommand() = onSendCommand(getStoredValue())\n        override fun getStoredValue() = sharedPreferences.getString(key, default.toString()).toInt()\n        override fun setValue(thisRef: Any, property: KProperty<*>, value: Int) {\n            sharedPreferences.edit().putString(key, value.toString()).apply()\n        }\n    }.apply {\n        sharedPreferences.registerOnSharedPreferenceChangeListener(this)\n        demoModeProperties.add(this)\n    }\n\n    fun stringPreference(key: String, default: String, onSendCommand: (String) -> Unit) = object : DemoModeProperty<String>() {\n        override val key = key\n        override fun issueDemoModeCommand() = onSendCommand(getStoredValue())\n        override fun getStoredValue() = sharedPreferences.getString(key, default)\n        override fun setValue(thisRef: Any, property: KProperty<*>, value: String) {\n            sharedPreferences.edit().putString(key, value).apply()\n        }\n    }.apply {\n        sharedPreferences.registerOnSharedPreferenceChangeListener(this)\n        demoModeProperties.add(this)\n    }\n}\n"
  },
  {
    "path": "app/src/main/kotlin/com/pspdfkit/labs/quickdemo/Utils.kt",
    "content": "/*\n *   Copyright (c) 2016-2019 PSPDFKit GmbH. All rights reserved.\n *\n *   THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW\n *   AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.\n *   UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.\n *   This notice may not be removed from this file\n */\n\npackage com.pspdfkit.labs.quickdemo\n\nimport android.content.Context\nimport android.widget.Toast\n\n/** Shows a normal toast message. */\nfun Context.toast(message: CharSequence, length: Int = Toast.LENGTH_SHORT)\n    = Toast.makeText(this, message, length).show()"
  },
  {
    "path": "app/src/main/kotlin/com/pspdfkit/labs/quickdemo/activity/ConfigurationActivity.kt",
    "content": "/*\n *   Copyright (c) 2016-2019 PSPDFKit GmbH. All rights reserved.\n *\n *   THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW\n *   AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.\n *   UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.\n *   This notice may not be removed from this file\n */\n\npackage com.pspdfkit.labs.quickdemo.activity\n\n\nimport android.content.BroadcastReceiver\nimport android.content.Context\nimport android.content.Intent\nimport android.content.IntentFilter\nimport android.content.SharedPreferences\nimport android.os.Bundle\nimport android.preference.PreferenceFragment\nimport android.preference.SwitchPreference\nimport androidx.annotation.ArrayRes\nimport androidx.appcompat.app.AppCompatActivity\nimport com.pspdfkit.labs.quickdemo.DemoMode\nimport com.pspdfkit.labs.quickdemo.R\n\nclass ConfigurationActivity : AppCompatActivity() {\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        supportActionBar?.setIcon(R.drawable.ic_configuration_activity)\n        fragmentManager.beginTransaction().replace(android.R.id.content, DemoModePreferences()).commit()\n    }\n\n    override fun onStart() {\n        super.onStart()\n\n        // Whenever this activity comes to the foreground, we check if the required permissions have been granted.\n        // If the permissions are missing, launch the setup guide.\n        val demoMode = DemoMode.get(this)\n        if (!demoMode.requiredPermissionsGranted || !demoMode.demoModeAllowed) {\n            SetupGuideActivity.launch(this)\n            // We have to finish this activity, otherwise users that do not complete the setup guide would end up in a endless loop.\n            finish()\n        }\n    }\n\n    class DemoModePreferences : PreferenceFragment(), SharedPreferences.OnSharedPreferenceChangeListener {\n        private lateinit var demoMode: DemoMode\n        private var updateFromReceiver: Boolean = false\n\n        private val demoModeChangeReceiver = object : BroadcastReceiver() {\n            override fun onReceive(p0: Context?, p1: Intent?) {\n                updateFromReceiver = true\n                updateDemoModeSwitch()\n                updateFromReceiver = false\n            }\n        }\n\n        override fun onCreate(savedInstanceState: Bundle?) {\n            super.onCreate(savedInstanceState)\n            demoMode = DemoMode.get(context)\n            addPreferencesFromResource(R.xml.demo_mode_preferences)\n            preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(this)\n            updateSummaries()\n        }\n\n        fun updateSummaries() {\n            setSummaryFromArrayValue(\"batteryLevel\", R.array.batteryLevelEscaped, R.array.batteryLevelValues, DemoMode.DEFAULT_BATTERY_LEVEL.toString())\n            setSummaryFromArrayValue(\"statusBarMode\", R.array.statusBarModes, R.array.statusBarModeValues, DemoMode.DEFAULT_STATUS_BAR_MODE)\n            setSummaryFromArrayValue(\"networkMobileDatatype\", R.array.networkMobileDatatypes, R.array.networkMobileDatatypeValues, DemoMode.DEFAULT_MOBILE_DATATYPE)\n            setSummaryFromArrayValue(\"networkMobileLevel\", R.array.networkReceptionLevels, R.array.networkReceptionLevelValues, DemoMode.DEFAULT_MOBILE_LEVEL.toString())\n            setSummaryFromArrayValue(\"networkNumberOfSims\", R.array.networkNumOfSims, R.array.networkNumOfSims, DemoMode.DEFAULT_NETWORK_NUM_OF_SIMS.toString())\n            setSummaryFromArrayValue(\"networkWifiLevel\", R.array.networkReceptionLevels, R.array.networkReceptionLevelValues, DemoMode.DEFAULT_WIFI_LEVEL.toString())\n            setSummaryFromArrayValue(\"statusVolume\", R.array.statusVolume, R.array.statusVolumeValues, DemoMode.DEFAULT_STATUS_HIDDEN)\n            setSummaryFromArrayValue(\"statusBluetooth\", R.array.statusBluetooth, R.array.statusBluetoothValues, DemoMode.DEFAULT_STATUS_HIDDEN)\n        }\n\n        fun setSummaryFromArrayValue(key: String, @ArrayRes labelArrayRes: Int, @ArrayRes valueArrayRes: Int, default: String) {\n            val preference = findPreference(key)\n            val value = preferenceManager.sharedPreferences.getString(key, default)\n            val i = resources.getStringArray(valueArrayRes).indexOf(value)\n            if (i >= 0) preference.summary = resources.getStringArray(labelArrayRes)[i]\n        }\n\n        override fun onStart() {\n            super.onStart()\n            context.registerReceiver(demoModeChangeReceiver, IntentFilter(\"com.android.systemui.demo\"))\n            updateDemoModeSwitch()\n        }\n\n        override fun onStop() {\n            super.onStop()\n            context.unregisterReceiver(demoModeChangeReceiver)\n        }\n\n        private fun updateDemoModeSwitch() {\n            val enabled = findPreference(\"enable_demo\") as SwitchPreference\n            enabled.isChecked = demoMode.enabled\n        }\n\n        override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {\n            when (key) {\n                \"enable_demo\" -> {\n                    if (!updateFromReceiver) demoMode.enabled = sharedPreferences.getBoolean(key, false)\n                }\n                \"batteryLevel\", \"statusBarMode\", \"networkMobileDatatype\", \"networkMobileLevel\",\n                \"networkNumberOfSims\", \"networkWifiLevel\", \"statusVolume\", \"statusBluetooth\" -> {\n                    updateSummaries()\n                }\n            }\n        }\n    }\n\n    companion object {\n        fun launch(context: Context) {\n            val intent = Intent(context, ConfigurationActivity::class.java)\n            context.startActivity(intent)\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/kotlin/com/pspdfkit/labs/quickdemo/activity/SetupGuideActivity.kt",
    "content": "/*\n *   Copyright (c) 2016-2019 PSPDFKit GmbH. All rights reserved.\n *\n *   THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW\n *   AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.\n *   UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.\n *   This notice may not be removed from this file\n */\n\npackage com.pspdfkit.labs.quickdemo.activity\n\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Bundle\nimport androidx.appcompat.app.AppCompatActivity\nimport android.webkit.WebView\nimport android.widget.Toast\nimport com.pspdfkit.labs.quickdemo.DemoMode\nimport com.pspdfkit.labs.quickdemo.R\nimport com.pspdfkit.labs.quickdemo.toast\nimport io.reactivex.Observable\nimport io.reactivex.android.schedulers.AndroidSchedulers\nimport io.reactivex.disposables.Disposable\nimport java.util.concurrent.TimeUnit\n\n/**\n * An interactive introduction guide for first-time users.\n */\nclass SetupGuideActivity : AppCompatActivity() {\n\n    var permissionChecking: Disposable? = null\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        val demoMode = DemoMode.get(this)\n\n        // If the app has already been granted the required permissions, there's no need to setup.\n        if (demoMode.requiredPermissionsGranted && demoMode.demoModeAllowed) finish()\n\n        // Setup content is just informative. We're using a webview to show pre-formatted instructions.\n        setContentView(R.layout.activity_setup_guide)\n        val webView: WebView = findViewById(R.id.webview)\n        webView.loadUrl(\"file:///android_asset/setup-guide.html\")\n\n        // We periodically check if the permission has been granted. Once this happened, we notify the user and finish the activity.\n        permissionChecking = Observable.interval(1, TimeUnit.SECONDS)\n            .filter { demoMode.requiredPermissionsGranted && demoMode.demoModeAllowed }\n            .observeOn(AndroidSchedulers.mainThread())\n            .doOnNext {\n                toast(\"QuickDemo has been successfully set up! Ready for activating demo mode.\", Toast.LENGTH_LONG)\n                ConfigurationActivity.launch(this)\n                finish()\n            }\n            .subscribe()\n    }\n\n    override fun onDestroy() {\n        super.onDestroy()\n\n        // Stop permission checking when destroying the activity (preventing leaks).\n        permissionChecking?.dispose()\n        permissionChecking = null\n    }\n\n    companion object {\n        fun launch(context: Context) {\n            context.startActivity(intent(context))\n        }\n\n        fun intent(context: Context) = Intent(context, SetupGuideActivity::class.java)\n    }\n}\n"
  },
  {
    "path": "app/src/main/kotlin/com/pspdfkit/labs/quickdemo/service/DemoModeTileService.kt",
    "content": "/*\n *   Copyright (c) 2016-2019 PSPDFKit GmbH. All rights reserved.\n *\n *   THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW\n *   AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.\n *   UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.\n *   This notice may not be removed from this file\n */\n\npackage com.pspdfkit.labs.quickdemo.service\n\nimport android.content.Intent\nimport android.graphics.drawable.Icon\nimport android.service.quicksettings.Tile\nimport android.service.quicksettings.TileService\nimport com.pspdfkit.labs.quickdemo.DemoMode\nimport com.pspdfkit.labs.quickdemo.R\nimport com.pspdfkit.labs.quickdemo.activity.SetupGuideActivity\n\nclass DemoModeTileService : TileService() {\n\n    private lateinit var demoMode: DemoMode\n\n    override fun onCreate() {\n        super.onCreate()\n        demoMode = DemoMode.get(this)\n    }\n\n    override fun onStartListening() {\n        qsTile.icon = Icon.createWithResource(this, R.drawable.ic_demo_mode)\n        qsTile.label = \"Demo mode\"\n        updateIcon()\n    }\n\n    override fun onClick() {\n        if (!demoMode.requiredPermissionsGranted || !demoMode.demoModeAllowed) {\n            startActivityAndCollapse(SetupGuideActivity.intent(this))\n            return\n        }\n\n        demoMode.enabled = !demoMode.enabled\n        updateIcon()\n\n        val it = Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)\n        sendBroadcast(it)\n    }\n\n    private fun updateIcon() {\n        qsTile.state = if (demoMode.enabled) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE\n        qsTile.updateTile()\n    }\n}"
  },
  {
    "path": "app/src/main/res/drawable/ic_configuration_activity.xml",
    "content": "<!--\n  ~   Copyright (c) 2016-2019 PSPDFKit GmbH. All rights reserved.\n  ~\n  ~   THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW\n  ~   AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.\n  ~   UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.\n  ~   This notice may not be removed from this file\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"42dp\"\n    android:height=\"24dp\"\n    android:viewportHeight=\"24.0\"\n    android:viewportWidth=\"42.0\">\n    <path\n        android:fillColor=\"#FFFFFFFF\"\n        android:pathData=\"M19,12h-2v3h-3v2h5v-5zM7,9h3L10,7L5,7v5h2L7,9zM21,3L3,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2zM21,19.01L3,19.01L3,4.99h18v14.02z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_demo_mode.xml",
    "content": "<!--\n  ~   Copyright (c) 2016-2019 PSPDFKit GmbH. All rights reserved.\n  ~\n  ~   THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW\n  ~   AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.\n  ~   UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.\n  ~   This notice may not be removed from this file\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportHeight=\"24.0\"\n    android:viewportWidth=\"24.0\">\n    <path\n        android:fillColor=\"#FFFFFFFF\"\n        android:pathData=\"M19,12h-2v3h-3v2h5v-5zM7,9h3L10,7L5,7v5h2L7,9zM21,3L3,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2zM21,19.01L3,19.01L3,4.99h18v14.02z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_launcher.xml",
    "content": "<!--\n  ~   Copyright (c) 2016-2019 PSPDFKit GmbH. All rights reserved.\n  ~\n  ~   THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW\n  ~   AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.\n  ~   UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.\n  ~   This notice may not be removed from this file\n  -->\n\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportHeight=\"24.0\"\n    android:viewportWidth=\"24.0\">\n    <path\n        android:fillColor=\"#2599cf\"\n        android:pathData=\"M19,12h-2v3h-3v2h5v-5zM7,9h3L10,7L5,7v5h2L7,9zM21,3L3,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2zM21,19.01L3,19.01L3,4.99h18v14.02z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/layout/activity_setup_guide.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~   Copyright (c) 2016-2019 PSPDFKit GmbH. All rights reserved.\n  ~\n  ~   THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW\n  ~   AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.\n  ~   UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.\n  ~   This notice may not be removed from this file\n  -->\n\n<WebView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:id=\"@+id/webview\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:paddingBottom=\"@dimen/activity_vertical_margin\"\n    android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n    android:paddingRight=\"@dimen/activity_horizontal_margin\"\n    android:paddingTop=\"@dimen/activity_vertical_margin\"\n    tools:context=\"com.pspdfkit.labs.quickdemo.activity.SetupGuideActivity\"/>\n"
  },
  {
    "path": "app/src/main/res/values/array.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~   Copyright (c) 2016-2019 PSPDFKit GmbH. All rights reserved.\n  ~\n  ~   THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW\n  ~   AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.\n  ~   UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.\n  ~   This notice may not be removed from this file\n  -->\n\n<resources>\n    <string-array name=\"statusBarModes\">\n        <item>Transparent</item>\n        <item>Opaque</item>\n        <item>Translucent</item>\n        <item>Semi-Transparent</item>\n        <item>Warning</item>\n    </string-array>\n\n    <string-array name=\"statusBarModeValues\">\n        <item>transparent</item>\n        <item>opaque</item>\n        <item>translucent</item>\n        <item>semi-transparent</item>\n        <item>warning</item>\n    </string-array>\n\n    <string-array name=\"networkMobileDatatypes\">\n        <item>1x</item>\n        <item>3G</item>\n        <item>4G</item>\n        <item>Edge</item>\n        <item>GPRS</item>\n        <item>HSPA</item>\n        <item>LTE</item>\n        <item>Roaming</item>\n        <item>Hidden</item>\n    </string-array>\n\n    <string-array name=\"networkMobileDatatypeValues\">\n        <item>1x</item>\n        <item>3g</item>\n        <item>4g</item>\n        <item>e</item>\n        <item>g</item>\n        <item>h</item>\n        <item>lte</item>\n        <item>roam</item>\n        <item>hidden</item>\n    </string-array>\n\n    <string-array name=\"batteryLevel\">\n        <item>100% (fully charged)</item>\n        <item>85%</item>\n        <item>70%</item>\n        <item>50%</item>\n        <item>30%</item>\n        <item>15%</item>\n        <item>0% (depleted)</item>\n    </string-array>\n\n    <string-array name=\"batteryLevelEscaped\">\n        <item>100%% (fully charged)</item>\n        <item>85%%</item>\n        <item>70%%</item>\n        <item>50%%</item>\n        <item>30%%</item>\n        <item>15%%</item>\n        <item>0%% (depleted)</item>\n    </string-array>\n\n    <string-array name=\"batteryLevelValues\">\n        <item>100</item>\n        <item>85</item>\n        <item>70</item>\n        <item>50</item>\n        <item>30</item>\n        <item>15</item>\n        <item>0</item>\n    </string-array>\n\n    <string-array name=\"networkReceptionLevels\">\n        <item>4 (full reception)</item>\n        <item>3</item>\n        <item>2</item>\n        <item>1</item>\n        <item>0 (no reception)</item>\n    </string-array>\n\n    <string-array name=\"networkReceptionLevelValues\">\n        <item>4</item>\n        <item>3</item>\n        <item>2</item>\n        <item>1</item>\n        <item>0</item>\n    </string-array>\n\n    <string-array name=\"networkNumOfSims\">\n        <item>1</item>\n        <item>2</item>\n        <item>3</item>\n        <item>4</item>\n        <item>5</item>\n        <item>6</item>\n        <item>7</item>\n        <item>8</item>\n    </string-array>\n\n    <string-array name=\"statusVolume\">\n        <item>Hidden</item>\n        <item>Silent</item>\n        <item>Vibrate</item>\n    </string-array>\n\n    <string-array name=\"statusVolumeValues\">\n        <item>hidden</item>\n        <item>silent</item>\n        <item>vibrate</item>\n    </string-array>\n\n    <string-array name=\"statusBluetooth\">\n        <item>Hidden</item>\n        <item>Connected</item>\n        <item>Disconnected</item>\n    </string-array>\n\n    <string-array name=\"statusBluetoothValues\">\n        <item>hidden</item>\n        <item>connected</item>\n        <item>disconnected</item>\n    </string-array>\n\n\n</resources>"
  },
  {
    "path": "app/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~   Copyright (c) 2016-2019 PSPDFKit GmbH. All rights reserved.\n  ~\n  ~   THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW\n  ~   AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.\n  ~   UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.\n  ~   This notice may not be removed from this file\n  -->\n\n<resources>\n    <color name=\"colorPrimary\">#0282BE</color>\n    <color name=\"colorPrimaryDark\">#015580</color>\n    <color name=\"colorAccent\">#4FC3F7</color>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/dimens.xml",
    "content": "<!--\n  ~   Copyright (c) 2016-2019 PSPDFKit GmbH. All rights reserved.\n  ~\n  ~   THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW\n  ~   AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.\n  ~   UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.\n  ~   This notice may not be removed from this file\n  -->\n\n<resources>\n    <dimen name=\"activity_horizontal_margin\">16dp</dimen>\n    <dimen name=\"activity_vertical_margin\">16dp</dimen>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/strings.xml",
    "content": "<!--\n  ~   Copyright (c) 2016-2019 PSPDFKit GmbH. All rights reserved.\n  ~\n  ~   THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW\n  ~   AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.\n  ~   UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.\n  ~   This notice may not be removed from this file\n  -->\n\n<resources>\n    <string name=\"app_name\">QuickDemo</string>\n    <string name=\"demo_mode_tile_title\">Demo mode</string>\n    <string name=\"title_activity_configuration\">QuickDemo Settings</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/styles.xml",
    "content": "<!--\n  ~   Copyright (c) 2016-2019 PSPDFKit GmbH. All rights reserved.\n  ~\n  ~   THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW\n  ~   AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.\n  ~   UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.\n  ~   This notice may not be removed from this file\n  -->\n\n<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-w820dp/dimens.xml",
    "content": "<!--\n  ~   Copyright (c) 2016-2019 PSPDFKit GmbH. All rights reserved.\n  ~\n  ~   THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW\n  ~   AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.\n  ~   UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.\n  ~   This notice may not be removed from this file\n  -->\n\n<resources>\n    <dimen name=\"activity_horizontal_margin\">64dp</dimen>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/xml/demo_mode_preferences.xml",
    "content": "<!--\n  ~   Copyright (c) 2016-2019 PSPDFKit GmbH. All rights reserved.\n  ~\n  ~   THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW\n  ~   AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.\n  ~   UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.\n  ~   This notice may not be removed from this file\n  -->\n\n<PreferenceScreen xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\">\n\n    <SwitchPreference\n        android:defaultValue=\"false\"\n        android:key=\"enable_demo\"\n        android:title=\"Enable demo\" />\n\n    <PreferenceCategory android:title=\"Statusbar Mode\">\n        <ListPreference\n            android:defaultValue=\"transparent\"\n            android:entries=\"@array/statusBarModes\"\n            android:entryValues=\"@array/statusBarModeValues\"\n            android:key=\"statusBarMode\"\n            android:title=\"Statusbar Mode\"\n            tools:summary=\"Translucent\" />\n    </PreferenceCategory>\n\n    <PreferenceCategory android:title=\"Notifications\">\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:key=\"hideNotifications\"\n            android:title=\"Hide notifications\" />\n    </PreferenceCategory>\n\n    <PreferenceCategory android:title=\"Battery\">\n        <ListPreference\n            android:defaultValue=\"100\"\n            android:key=\"batteryLevel\"\n            android:entries=\"@array/batteryLevel\"\n            android:entryValues=\"@array/batteryLevelValues\"\n            android:title=\"Battery Level\" />\n\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:key=\"batteryPlugged\"\n            android:title=\"Show battery as charging\" />\n\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:key=\"batteryPowersave\"\n            android:title=\"Powersave mode\" />\n    </PreferenceCategory>\n\n\n    <PreferenceCategory android:title=\"Clock\">\n        <EditTextPreference\n            android:defaultValue=\"0700\"\n            android:key=\"time\"\n            android:title=\"Time (4 digits such as '0700')\" />\n            android:singleLine=\"true\"/>\n    </PreferenceCategory>\n\n    <PreferenceCategory android:title=\"Network\">\n\n        <SwitchPreference\n            android:key=\"networkShowAirplane\"\n            android:defaultValue=\"false\"\n            android:title=\"Airplane mode\"/>\n\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:key=\"networkMobileShown\"\n            android:title=\"Show network icon\" />\n\n        <ListPreference\n            android:defaultValue=\"4\"\n            android:entries=\"@array/networkReceptionLevels\"\n            android:entryValues=\"@array/networkReceptionLevelValues\"\n            android:key=\"networkMobileLevel\"\n            android:title=\"Mobile signal\" />\n\n        <ListPreference\n            android:defaultValue=\"hidden\"\n            android:entries=\"@array/networkMobileDatatypes\"\n            android:entryValues=\"@array/networkMobileDatatypeValues\"\n            android:key=\"networkMobileDatatype\"\n            android:title=\"Data type\"\n            tools:summary=\"LTE\" />\n\n        <SwitchPreference\n            android:key=\"networkFullConnectivity\"\n            android:defaultValue=\"true\"\n            android:title=\"Full connectivity\"/>\n\n        <SwitchPreference\n            android:key=\"networkCarrierNetworkChange\"\n            android:defaultValue=\"false\"\n            android:title=\"Carrier network change mode\"/>\n\n        <SwitchPreference\n            android:key=\"networkShowNoSim\"\n            android:defaultValue=\"false\"\n            android:title=\"No SIM card\"/>\n\n        <ListPreference\n            android:defaultValue=\"1\"\n            android:entries=\"@array/networkNumOfSims\"\n            android:entryValues=\"@array/networkNumOfSims\"\n            android:key=\"networkNumberOfSims\"\n            android:title=\"Number of SIM cards\" />\n    </PreferenceCategory>\n\n    <PreferenceCategory android:title=\"Wi-Fi\">\n        <SwitchPreference\n            android:key=\"networkShowWifi\"\n            android:defaultValue=\"false\"\n            android:title=\"Show Wi-Fi\"/>\n\n        <ListPreference\n            android:defaultValue=\"4\"\n            android:entries=\"@array/networkReceptionLevels\"\n            android:entryValues=\"@array/networkReceptionLevelValues\"\n            android:key=\"networkWifiLevel\"\n            android:title=\"Wi-Fi signal\" />\n    </PreferenceCategory>\n\n    <PreferenceCategory android:title=\"Status symbols\">\n        <ListPreference\n            android:defaultValue=\"hidden\"\n            android:entries=\"@array/statusBluetooth\"\n            android:entryValues=\"@array/statusBluetoothValues\"\n            android:key=\"statusBluetooth\"\n            android:title=\"Bluetooth\" />\n\n        <ListPreference\n            android:defaultValue=\"hidden\"\n            android:entries=\"@array/statusVolume\"\n            android:entryValues=\"@array/statusVolumeValues\"\n            android:key=\"statusVolume\"\n            android:title=\"Volume\" />\n\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:key=\"statusLocation\"\n            android:title=\"Show Location\" />\n        \n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:key=\"statusSync\"\n            android:title=\"Show Sync\" />\n\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:key=\"statusTty\"\n            android:title=\"Show TTY\" />\n\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:key=\"statusEri\"\n            android:title=\"Show ERI\" />\n\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:key=\"statusMute\"\n            android:title=\"Show Mute\" />\n\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:key=\"statusSpeakerphone\"\n            android:title=\"Show Speakerphone\" />\n    </PreferenceCategory>\n\n\n</PreferenceScreen>\n"
  },
  {
    "path": "app/src/test/java/com/pspdfkit/labs/quickdemo/ExampleUnitTest.kt",
    "content": "/*\n *   Copyright (c) 2016-2019 PSPDFKit GmbH. All rights reserved.\n *\n *   THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW\n *   AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.\n *   UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.\n *   This notice may not be removed from this file\n */\n\npackage com.pspdfkit.labs.quickdemo\n\nimport org.junit.Assert.assertEquals\nimport org.junit.Test\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n\n * @see [Testing documentation](http://d.android.com/tools/testing)\n */\nclass ExampleUnitTest {\n    @Test\n    @Throws(Exception::class)\n    fun addition_isCorrect() {\n        assertEquals(4, (2 + 2).toLong())\n    }\n}"
  },
  {
    "path": "build.gradle",
    "content": "/*\n *   Copyright (c) 2016-2019 PSPDFKit GmbH. All rights reserved.\n *\n *   THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW\n *   AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.\n *   UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.\n *   This notice may not be removed from this file\n */\n\nbuildscript {\n    ext.kotlin_version = '1.3.31'\n\n    repositories {\n        jcenter()\n        google()\n    }\n\n    dependencies {\n        classpath 'com.android.tools.build:gradle:3.4.1'\n        classpath \"org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version\"\n        classpath 'com.novoda:gradle-android-command-plugin:1.6.2'\n    }\n}\n\nallprojects {\n    repositories {\n        jcenter()\n        google()\n    }\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "#\n# gradle-wrapper.properties\n#\n#   PSPDFKit\n#\n#   Copyright (c) 2016 PSPDFKit GmbH. All rights reserved.\n#\n#   THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW\n#   AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.\n#   UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.\n#   This notice may not be removed from this file\n#\n\n#Mon Oct 16 10:43:14 EDT 2017\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-5.4.1-all.zip\n"
  },
  {
    "path": "gradle.properties",
    "content": "#\n#   Copyright (c) 2016-2019 PSPDFKit GmbH. All rights reserved.\n#\n#   THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW\n#   AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.\n#   UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.\n#   This notice may not be removed from this file\n#\n\norg.gradle.jvmargs=-Xmx1536m\nkotlin.incremental=true\nandroid.useAndroidX=true\nandroid.enableJetifier=true"
  },
  {
    "path": "gradlew",
    "content": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn ( ) {\n    echo \"$*\"\n}\n\ndie ( ) {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\nesac\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules\nfunction splitJvmOpts() {\n    JVM_OPTS=(\"$@\")\n}\neval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\nJVM_OPTS[${#JVM_OPTS[*]}]=\"-Dorg.gradle.appname=$APP_BASE_NAME\"\n\nexec \"$JAVACMD\" \"${JVM_OPTS[@]}\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain \"$@\"\n"
  },
  {
    "path": "gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif \"%ERRORLEVEL%\" == \"0\" goto init\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto init\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:init\n@rem Get command-line arguments, handling Windowz variants\n\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\nif \"%@eval[2+2]\" == \"4\" goto 4NT_args\n\n:win9xME_args\n@rem Slurp the command line arguments.\nset CMD_LINE_ARGS=\nset _SKIP=2\n\n:win9xME_args_slurp\nif \"x%~1\" == \"x\" goto execute\n\nset CMD_LINE_ARGS=%*\ngoto execute\n\n:4NT_args\n@rem Get arguments from the 4NT Shell from JP Software\nset CMD_LINE_ARGS=%$\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\n\n:end\n@rem End local scope for the variables with windows NT shell\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\nexit /b 1\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "settings.gradle",
    "content": "/*\n *   Copyright (c) 2016-2019 PSPDFKit GmbH. All rights reserved.\n *\n *   THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW\n *   AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.\n *   UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.\n *   This notice may not be removed from this file\n */\n\ninclude ':app'\n"
  },
  {
    "path": "setup-guide.md",
    "content": "***QuickDemo is a tool for Android developers. If you don't know what this application is for, do not use it!***\n\n## Setup\n\nTo enable _QuickDemo_ you need to do two things.\n\n1. Enable the System UI demo mode on your phone.\n2. Grant the `android.permission.DUMP` to the QuickDemo app. This permissions is protected and can't be requested at runtime.\n\nThis can be achieved by running the following `gradle` task.\n\n```\n./gradlew setupDemoMode\n```\n\nIf you don't have the project. Both steps can be performed manually from command line via `adb`.\n\n```\n# Ensure demo mode is activated.\nadb shell settings put global sysui_demo_allowed 1\n\n# Grant required permissions.\nadb shell pm grant com.pspdfkit.labs.quickdemo android.permission.DUMP\n```\n\n**Please note:** The permissions is granted until you revoke it or uninstall the app.\n"
  },
  {
    "path": "setup.sh",
    "content": "#!/usr/bin/env bash\n\nif [[ $1 ]] || [[ ${ANDROID_HOME} ]];\nthen\n    cd ~\n    git clone git@github.com:PSPDFKit-labs/QuickDemo.git\n    cd QuickDemo/\n    if [[ $1 ]]; then echo \"sdk.dir=\"$1 >>local.properties\n    fi\n    ./gradlew installDebug\n    ./gradlew setupDemoMode\n    cd ~\n    yes | rm -r QuickDemo\nelse\n    echo \"Missing ANDROID_HOME\"\n    echo \"Usage: ./quick_demo.sh ANDROID_HOME\"\n    echo \"or set an ANROID_HOME environment variable\"\nfi\n"
  }
]