├── .gitignore
├── LICENSE
├── README.md
├── app
├── .gitignore
├── build.gradle
├── gradle.properties
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── snaggly
│ │ └── ksw_toolkit
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── aidl
│ │ └── com
│ │ │ ├── snaggly
│ │ │ └── ksw_toolkit
│ │ │ │ ├── IAdvancedBrightnessControl.aidl
│ │ │ │ ├── IAutoTimeListener.aidl
│ │ │ │ ├── IKSWToolKitService.aidl
│ │ │ │ ├── IMcuListener.aidl
│ │ │ │ └── ISystemOptionsControl.aidl
│ │ │ └── wits
│ │ │ └── pms
│ │ │ ├── ICmdListener.aidl
│ │ │ ├── IContentObserver.aidl
│ │ │ ├── IPowerManagerAppService.aidl
│ │ │ └── custom
│ │ │ ├── ICallBack.aidl
│ │ │ └── ICallBackController.aidl
│ ├── ic_launcher-playstore.png
│ ├── ic_launcher_wabes-playstore.png
│ ├── ic_launcher_wabes_round-playstore.png
│ ├── java
│ │ ├── com
│ │ │ └── snaggly
│ │ │ │ └── ksw_toolkit
│ │ │ │ ├── core
│ │ │ │ ├── config
│ │ │ │ │ ├── ConfigData.kt
│ │ │ │ │ ├── ConfigManager.kt
│ │ │ │ │ └── beans
│ │ │ │ │ │ ├── AdvancedBrightness.kt
│ │ │ │ │ │ ├── EventManager.kt
│ │ │ │ │ │ └── SystemOptions.kt
│ │ │ │ └── service
│ │ │ │ │ ├── adb
│ │ │ │ │ └── AdbServiceConnection.kt
│ │ │ │ │ └── helper
│ │ │ │ │ ├── CoreServiceClient.kt
│ │ │ │ │ └── ServiceAliveCheck.kt
│ │ │ │ ├── gui
│ │ │ │ ├── AdbShell.kt
│ │ │ │ ├── AdvancedBrightness.kt
│ │ │ │ ├── ConfigImportExport.kt
│ │ │ │ ├── EventManager.kt
│ │ │ │ ├── EventManagerSelectAction.kt
│ │ │ │ ├── MainActivity.kt
│ │ │ │ ├── McuListener.kt
│ │ │ │ ├── SystemTwaks.kt
│ │ │ │ ├── ToolKit.kt
│ │ │ │ └── viewmodels
│ │ │ │ │ ├── AdbShellViewModel.kt
│ │ │ │ │ ├── ConfigImportExportViewModel.kt
│ │ │ │ │ ├── EventManagerSelectActionViewModel.kt
│ │ │ │ │ ├── EventManagerViewModel.kt
│ │ │ │ │ ├── MainActivityViewModel.kt
│ │ │ │ │ ├── McuListenerViewModel.kt
│ │ │ │ │ ├── SystemTwaksViewModel.kt
│ │ │ │ │ └── ToolKitViewModel.kt
│ │ │ │ └── util
│ │ │ │ ├── adapters
│ │ │ │ ├── ListTypeAdapter.kt
│ │ │ │ └── McuEventRVAdapter.kt
│ │ │ │ ├── adb
│ │ │ │ ├── AdbManager.kt
│ │ │ │ └── ShellObserver.kt
│ │ │ │ ├── github
│ │ │ │ ├── AssetMetaData.kt
│ │ │ │ ├── AuthorMetaData.kt
│ │ │ │ ├── DownloadController.kt
│ │ │ │ ├── GitHubRelease.kt
│ │ │ │ └── VersionTag.kt
│ │ │ │ ├── list
│ │ │ │ ├── ListType.kt
│ │ │ │ ├── app
│ │ │ │ │ ├── AppInfo.kt
│ │ │ │ │ └── AppsLister.kt
│ │ │ │ ├── eventtype
│ │ │ │ │ ├── EventManagerTypes.kt
│ │ │ │ │ └── EventMode.kt
│ │ │ │ ├── keyevent
│ │ │ │ │ ├── KeyCode.kt
│ │ │ │ │ └── KeyEvent.kt
│ │ │ │ ├── mcu
│ │ │ │ │ ├── McuCommandsEnum.kt
│ │ │ │ │ ├── McuCommandsList.kt
│ │ │ │ │ └── McuEventData.kt
│ │ │ │ └── tasker
│ │ │ │ │ ├── TakserTaskInfo.kt
│ │ │ │ │ └── TaskerTaskLister.kt
│ │ │ │ └── reflection
│ │ │ │ └── KSWSettings.kt
│ │ └── net
│ │ │ └── dinglisch
│ │ │ └── android
│ │ │ └── taskerm
│ │ │ ├── ActionCodes.java
│ │ │ └── TaskerIntent.java
│ └── res
│ │ ├── anim
│ │ ├── enter_from_buttom.xml
│ │ ├── enter_from_top.xml
│ │ ├── leave_to_buttom.xml
│ │ ├── leave_to_top.xml
│ │ ├── slide_enter_right_left.xml
│ │ └── slide_exit_right_left.xml
│ │ ├── color
│ │ ├── main_btn_selector.xml
│ │ ├── main_btn_text_selector.xml
│ │ ├── main_info_btn_selector.xml
│ │ ├── radio_selector.xml
│ │ ├── red_btn_selector.xml
│ │ ├── spinner_color.xml
│ │ ├── spinner_dropdown_color.xml
│ │ └── switch_selector.xml
│ │ ├── drawable-anydpi
│ │ └── ic_stat_name.xml
│ │ ├── drawable-hdpi
│ │ └── ic_stat_name.png
│ │ ├── drawable-mdpi
│ │ └── ic_stat_name.png
│ │ ├── drawable-v24
│ │ ├── ic_aux.png
│ │ ├── ic_dtv.png
│ │ ├── ic_dvr.png
│ │ ├── ic_launcher_foreground.xml
│ │ ├── icon_fcam.png
│ │ ├── id7_sys_factory_bg.png
│ │ └── nbt_src_icon_carinfo.png
│ │ ├── drawable-xhdpi
│ │ └── ic_stat_name.png
│ │ ├── drawable-xxhdpi
│ │ └── ic_stat_name.png
│ │ ├── drawable
│ │ ├── baseline_indeterminate_check_box_24.xml
│ │ ├── baseline_map_36.xml
│ │ ├── baseline_music_video_36.xml
│ │ ├── border.xml
│ │ ├── border_focused.xml
│ │ ├── border_pressed.xml
│ │ ├── border_selector.xml
│ │ ├── btn_1_car.png
│ │ ├── btn_1_car_cl.png
│ │ ├── btn_1_car_hl.png
│ │ ├── btn_2_radio.png
│ │ ├── btn_2_radio_cl.png
│ │ ├── btn_2_radio_hl.png
│ │ ├── btn_3_front_cam.png
│ │ ├── btn_3_front_cam_cl.png
│ │ ├── btn_3_front_cam_hl.png
│ │ ├── btn_4_aux.png
│ │ ├── btn_4_aux_cl.png
│ │ ├── btn_4_aux_hl.png
│ │ ├── btn_5_dvr.png
│ │ ├── btn_5_dvr_cl.png
│ │ ├── btn_5_dvr_hl.png
│ │ ├── btn_6_dvd.png
│ │ ├── btn_6_dvd_cl.png
│ │ ├── btn_6_dvd_hl.png
│ │ ├── btn_7_tv.png
│ │ ├── btn_7_tv_cl.png
│ │ ├── btn_7_tv_hl.png
│ │ ├── btn_aux.xml
│ │ ├── btn_car.xml
│ │ ├── btn_dvd.xml
│ │ ├── btn_dvr.xml
│ │ ├── btn_front_cam.xml
│ │ ├── btn_radio.xml
│ │ ├── btn_selector.xml
│ │ ├── btn_tv.xml
│ │ ├── ic_baseline_brightness_high_64.xml
│ │ ├── ic_baseline_brightness_low_64.xml
│ │ ├── ic_baseline_cable_64.xml
│ │ ├── ic_baseline_calculate_36.xml
│ │ ├── ic_baseline_calendar_today_36.xml
│ │ ├── ic_baseline_call_36.xml
│ │ ├── ic_baseline_call_end_36.xml
│ │ ├── ic_baseline_camera_alt_64.xml
│ │ ├── ic_baseline_center_focus_weak_36.xml
│ │ ├── ic_baseline_cloud_download_24.xml
│ │ ├── ic_baseline_cloud_upload_24.xml
│ │ ├── ic_baseline_code_36.xml
│ │ ├── ic_baseline_contacts_36.xml
│ │ ├── ic_baseline_email_36.xml
│ │ ├── ic_baseline_file_copy_36.xml
│ │ ├── ic_baseline_filter_center_focus_24.xml
│ │ ├── ic_baseline_flip_to_front_36.xml
│ │ ├── ic_baseline_home_24.xml
│ │ ├── ic_baseline_info_24.xml
│ │ ├── ic_baseline_keyboard_arrow_down_36.xml
│ │ ├── ic_baseline_keyboard_arrow_left_36.xml
│ │ ├── ic_baseline_keyboard_arrow_right_36.xml
│ │ ├── ic_baseline_keyboard_arrow_up_36.xml
│ │ ├── ic_baseline_keyboard_backspace_36.xml
│ │ ├── ic_baseline_library_music_36.xml
│ │ ├── ic_baseline_live_tv_64.xml
│ │ ├── ic_baseline_play_arrow_36.xml
│ │ ├── ic_baseline_radio_64.xml
│ │ ├── ic_baseline_radio_button_checked_24.xml
│ │ ├── ic_baseline_radio_button_checked_highlighted_24.xml
│ │ ├── ic_baseline_radio_button_unchecked_24.xml
│ │ ├── ic_baseline_radio_button_unchecked_highlighted_24.xml
│ │ ├── ic_baseline_record_voice_over_36.xml
│ │ ├── ic_baseline_settings_24.xml
│ │ ├── ic_baseline_settings_input_component_64.xml
│ │ ├── ic_baseline_settings_suggest_24.xml
│ │ ├── ic_baseline_skip_next_36.xml
│ │ ├── ic_baseline_skip_previous_36.xml
│ │ ├── ic_baseline_stop_36.xml
│ │ ├── ic_baseline_videocam_64.xml
│ │ ├── ic_baseline_volume_down_36.xml
│ │ ├── ic_baseline_volume_mute_36.xml
│ │ ├── ic_baseline_volume_off_36.xml
│ │ ├── ic_baseline_volume_up_36.xml
│ │ ├── ic_baseline_web_asset_off_64.xml
│ │ ├── ic_launcher_background.xml
│ │ ├── ic_launcher_foreground.xml
│ │ ├── ksw_id7_btn_pressed.png
│ │ ├── ksw_id7_itme_select_bg_focused.png
│ │ ├── ksw_id7_itme_select_bg_normal.png
│ │ ├── ksw_id7_itme_select_bg_pressed.png
│ │ └── radio_selector.xml
│ │ ├── layout
│ │ ├── activity_main.xml
│ │ ├── adb_shell_fragment.xml
│ │ ├── adv_brightness_fragment.xml
│ │ ├── apps_view_list.xml
│ │ ├── config_fragment.xml
│ │ ├── dummy_list.xml
│ │ ├── event_manager_fragment.xml
│ │ ├── event_manager_select_action_fragment.xml
│ │ ├── mcu_event.xml
│ │ ├── mcu_listener_fragment.xml
│ │ ├── spinner_dropdown_layout.xml
│ │ ├── spinner_layout.xml
│ │ ├── system_twaks_fragment.xml
│ │ └── toolkit_fragment.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ ├── ic_launcher_round.xml
│ │ ├── ic_launcher_wabes.xml
│ │ └── ic_launcher_wabes_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_background.png
│ │ ├── ic_launcher_background_wabes.png
│ │ ├── ic_launcher_round.png
│ │ ├── ic_launcher_wabes_round.png
│ │ └── ic_launcher_wabes_round_background.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_background.png
│ │ ├── ic_launcher_background_wabes.png
│ │ ├── ic_launcher_round.png
│ │ ├── ic_launcher_wabes_round.png
│ │ └── ic_launcher_wabes_round_background.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_background.png
│ │ ├── ic_launcher_background_wabes.png
│ │ ├── ic_launcher_round.png
│ │ ├── ic_launcher_wabes_round.png
│ │ └── ic_launcher_wabes_round_background.png
│ │ ├── mipmap-xxhdpi
│ │ ├── green_button.png
│ │ ├── grey_button.png
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_background.png
│ │ ├── ic_launcher_background_wabes.png
│ │ ├── ic_launcher_round.png
│ │ ├── ic_launcher_wabes_round.png
│ │ ├── ic_launcher_wabes_round_background.png
│ │ └── red_button.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_background.png
│ │ ├── ic_launcher_background_wabes.png
│ │ ├── ic_launcher_round.png
│ │ ├── ic_launcher_wabes_round.png
│ │ └── ic_launcher_wabes_round_background.png
│ │ ├── values
│ │ ├── arrays.xml
│ │ ├── colors.xml
│ │ ├── mcuSources.xml
│ │ ├── strings.xml
│ │ └── themes.xml
│ │ └── xml
│ │ └── file_provider_paths.xml
│ └── test
│ └── java
│ └── com
│ └── snaggly
│ └── ksw_toolkit
│ └── ExampleUnitTest.kt
├── build.gradle
├── enigma-backup
└── .gitignore
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── images
└── screenshot-eventmanager.png
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | local.properties
3 | .DS_Store
4 | .idea/*
5 | .gradle/*
6 | build/*
7 | enigma-backup/*
8 | app/release/*
9 | app/debug/*
10 | app/build/*
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Attention: This repository is hereby declared as no longer maintained.
2 | The successor, a more feature-rich version, is now accessible at the following link: https://play.google.com/store/apps/details?id=tech.snaggle.ksw_toolkit. This updated version has been meticulously developed from the ground up with an emphasis on stability and the seamless integration of new functionalities. Although this repository is no longer actively maintained, it remains available for the submission of any arising issues.
3 |
4 | # KSW-ToolKit
5 |
6 | 
7 |
8 | KSW-ToolKit is an extension to your KSW Android screen. Once the service is installed, it will hijack the original McuService and will work as replacement which you can highly customize. This service allows you to remap your buttons to invoke various Android keystrokes, start any App of your desire or invoke various MCU hardware commands like switching sources or tuning the brightness. The service also bypasses various inconveniances the original McuService caused, like not hearing your Android when you're in OEM side, keeping your Apps open when you switch sources or generally having the Android react faster to your hardware inputs.
9 |
10 | ...in short KSW-ToolKit
11 | ## Features:
12 | * Rich customizability
13 | * Remapping of your hardware buttons
14 | * Automatic Day/Night switching
15 | * Auto Volumes
16 | * Sound Restorer to keep sound running on OEM side
17 | * Enables extra hardware buttons*
18 | * Built in ADB Shell to manipulate and have more control over your Android
19 | * And much more to discover...
20 |
21 | *This is the "Media-Button Hack". It will depend on the car and MCU model you have. In BMWs for example this hack will allow the Tel and Media/CD button on your iDrive to also get triggered as Phone and MODE event in Android. Check MCU Listener if this hack works for you.
22 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.application'
3 | id 'kotlin-android'
4 | }
5 |
6 | android {
7 | compileSdkVersion 32
8 | buildToolsVersion "30.0.3"
9 |
10 | defaultConfig {
11 | applicationId "com.snaggly.wits.ksw_toolkit.client"
12 | minSdkVersion 28
13 | targetSdkVersion 32
14 | versionCode 1
15 | versionName "1.2"
16 |
17 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
18 | }
19 |
20 | buildTypes {
21 | release {
22 | minifyEnabled true
23 | shrinkResources true
24 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
25 | }
26 | }
27 | compileOptions {
28 | sourceCompatibility JavaVersion.VERSION_1_8
29 | targetCompatibility JavaVersion.VERSION_1_8
30 | }
31 | kotlinOptions {
32 | jvmTarget = '1.8'
33 | }
34 | buildFeatures {
35 | aidl true
36 | }
37 | namespace 'com.snaggly.ksw_toolkit'
38 | }
39 |
40 | dependencies {
41 | implementation 'com.google.code.gson:gson:2.8.6'
42 | implementation "org.jetbrains.kotlin:kotlin-stdlib:1.5.30"
43 | implementation 'androidx.appcompat:appcompat:1.3.1'
44 | implementation 'com.google.android.material:material:1.4.0'
45 | implementation 'androidx.constraintlayout:constraintlayout:2.1.1'
46 | implementation 'androidx.preference:preference-ktx:1.1.1'
47 | implementation 'androidx.legacy:legacy-support-v4:1.0.0'
48 | implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
49 | implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
50 | implementation "androidx.recyclerview:recyclerview:1.2.1"
51 | implementation "androidx.recyclerview:recyclerview-selection:1.1.0"
52 | implementation 'com.github.KswCarProject:McuCommunicator:1.0.2'
53 | testImplementation 'junit:junit:4.13.2'
54 | androidTestImplementation 'androidx.test.ext:junit:1.1.3'
55 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
56 | }
--------------------------------------------------------------------------------
/app/gradle.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Snaggly/KSW-ToolKit/cd4f2a88a04ac21ec6c814eec942c36859afc510/app/gradle.properties
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
23 | -keep class com.snaggly.ksw_toolkit.core.config.ConfigData {*;}
24 | -keep class com.snaggly.ksw_toolkit.core.config.beans.** {*;}
25 | -keep class com.snaggly.ksw_toolkit.util.list.eventtype.EventManagerTypes {*;}
26 | -keep class com.snaggly.ksw_toolkit.util.list.eventtype.EventMode {*;}
27 | -keep class com.snaggly.ksw_toolkit.util.list.keyevent.KeyCode {*;}
28 | -keep class com.snaggly.ksw_toolkit.util.list.mcu.McuCommandsList {*;}
29 | -keep class com.snaggly.ksw_toolkit.util.github.** {*;}
30 | -keep class com.snaggly.ksw_toolkit.IKSWToolKitService {*;}
31 | -keep class com.snaggly.ksw_toolkit.IMcuListener {*;}
32 | -keep class com.snaggly.ksw_toolkit.IAdvancedBrightnessControl {*;}
33 | -keep class com.snaggly.ksw_toolkit.IAutoTimeListener {*;}
34 | -keep class com.snaggly.ksw_toolkit.ISystemOptionsControl {*;}
35 | -keep class net.dinglisch.android.taskerm.** {*;}
36 | -keep class projekt.auto.mcu.** {*;}
37 | -keep class * implements android.os.Parcelable {
38 | public static final android.os.Parcelable$Creator *;
39 | }
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/snaggly/ksw_toolkit/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.snaggly.ksw_toolkit
2 |
3 | import androidx.test.ext.junit.runners.AndroidJUnit4
4 | import androidx.test.platform.app.InstrumentationRegistry
5 | import org.junit.Assert
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | /**
10 | * Instrumented test, which will execute on an Android device.
11 | *
12 | * @see [Testing documentation](http://d.android.com/tools/testing)
13 | */
14 | @RunWith(AndroidJUnit4::class)
15 | class ExampleInstrumentedTest {
16 | @Test
17 | fun useAppContext() {
18 | // Context of the app under test.
19 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
20 | Assert.assertEquals("com.snaggly.ksw_toolkit", appContext.packageName)
21 | }
22 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
7 |
8 |
9 |
10 |
11 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
27 |
29 |
30 |
31 |
32 |
33 |
34 |
39 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/app/src/main/aidl/com/snaggly/ksw_toolkit/IAdvancedBrightnessControl.aidl:
--------------------------------------------------------------------------------
1 | package com.snaggly.ksw_toolkit;
2 |
3 | import com.snaggly.ksw_toolkit.IAutoTimeListener;
4 |
5 | interface IAdvancedBrightnessControl {
6 | boolean getAdvBri_IsTimeBased();
7 | void setAdvBri_IsTimeBased(boolean value);
8 | boolean getAdvBri_IsUSBBased();
9 | void setAdvBri_IsUSBBased(boolean value);
10 | String getAdvBri_SunriseAt();
11 | void setAdvBri_SunriseAt(String value);
12 | String getAdvBri_SunsetAt();
13 | void setAdvBri_SunsetAt(String value);
14 | boolean getAdvBri_Autotimes();
15 | void setAdvBri_Autotimes(boolean value);
16 | int getAdvBri_DaylightBri();
17 | void setAdvBri_DaylightBri(int value);
18 | int getAdvBri_DaylightHLBri();
19 | void setAdvBri_DaylightHLBri(int value);
20 | int getAdvBri_NightBri();
21 | void setAdvBri_NightBri(int value);
22 | int getAdvBri_NightHLBri();
23 | void setAdvBri_NightHLBri(int value);
24 |
25 | void registerAutoTimeListener(IAutoTimeListener listener);
26 | void unregisterAutoTimeListener(IAutoTimeListener listener);
27 | }
--------------------------------------------------------------------------------
/app/src/main/aidl/com/snaggly/ksw_toolkit/IAutoTimeListener.aidl:
--------------------------------------------------------------------------------
1 | package com.snaggly.ksw_toolkit;
2 |
3 | interface IAutoTimeListener {
4 | void updateAutoTime(String sunrise, String sunset);
5 | }
--------------------------------------------------------------------------------
/app/src/main/aidl/com/snaggly/ksw_toolkit/IKSWToolKitService.aidl:
--------------------------------------------------------------------------------
1 | // IKSWToolKitService.aidl
2 | package com.snaggly.ksw_toolkit;
3 |
4 | import com.snaggly.ksw_toolkit.IMcuListener;
5 | import com.snaggly.ksw_toolkit.ISystemOptionsControl;
6 | import com.snaggly.ksw_toolkit.IAdvancedBrightnessControl;
7 |
8 | interface IKSWToolKitService {
9 | boolean sendMcuCommand(int cmdType, in byte[] data);
10 |
11 | boolean changeBtnConfig(int btnType, int cmdType, String cmdValue);
12 | void setDefaultBtnLayout();
13 |
14 | String getConfig();
15 | boolean setConfig(String configJson);
16 |
17 | boolean registerMcuListener(IMcuListener listener);
18 | boolean unregisterMcuListener(IMcuListener listener);
19 |
20 | ISystemOptionsControl getSystemOptionsController();
21 | IAdvancedBrightnessControl getAdvancedBrightnessController();
22 | }
--------------------------------------------------------------------------------
/app/src/main/aidl/com/snaggly/ksw_toolkit/IMcuListener.aidl:
--------------------------------------------------------------------------------
1 | // IMcuListener.aidl
2 | package com.snaggly.ksw_toolkit;
3 |
4 | interface IMcuListener {
5 | void updateMcu(String eventName, int cmdType, in byte[] data);
6 | }
--------------------------------------------------------------------------------
/app/src/main/aidl/com/snaggly/ksw_toolkit/ISystemOptionsControl.aidl:
--------------------------------------------------------------------------------
1 | package com.snaggly.ksw_toolkit;
2 |
3 | interface ISystemOptionsControl {
4 | int getNightBrightnessLevel();
5 | void setNightBrightnessLevel(int value);
6 |
7 | boolean getTabletMode();
8 | void setTabletMode(boolean value);
9 |
10 | boolean getStartAtBoot();
11 | void setStartAtBoot(boolean value);
12 |
13 | boolean getHijackCS();
14 | void setHijackCS(boolean value);
15 |
16 | boolean getSoundRestorer();
17 | void setSoundRestorer(boolean value);
18 |
19 | boolean getAutoTheme();
20 | void setAutoTheme(boolean value);
21 |
22 | boolean getAutoVolume();
23 | void setAutoVolume(boolean value);
24 |
25 | boolean getRetainVolume();
26 | void setRetainVolume(boolean value);
27 |
28 | boolean getLogMcuEvent();
29 | void setLogMcuEvent(boolean value);
30 |
31 | boolean getInterceptMcuCommand();
32 | void setInterceptMcuCommand(boolean value);
33 |
34 | boolean getExtraMediaButtonHandle();
35 | void setExtraMediaButtonHandle(boolean value);
36 |
37 | boolean getNightBrightness();
38 | void setNightBrightness(boolean value);
39 |
40 | String getMcuPath();
41 | boolean setMcuPath(String path);
42 |
43 | boolean getHideStartMessage();
44 | void setHideStartMessage(boolean value);
45 |
46 | boolean getDecoupleNAVBtn();
47 | void setDecoupleNAVBtn(boolean value);
48 | }
--------------------------------------------------------------------------------
/app/src/main/aidl/com/wits/pms/ICmdListener.aidl:
--------------------------------------------------------------------------------
1 | package com.wits.pms;
2 |
3 | interface ICmdListener {
4 | boolean handleCommand(String str);
5 | void updateStatusInfo(String str);
6 | }
--------------------------------------------------------------------------------
/app/src/main/aidl/com/wits/pms/IContentObserver.aidl:
--------------------------------------------------------------------------------
1 | package com.wits.pms;
2 |
3 | interface IContentObserver {
4 | void onChange();
5 | }
--------------------------------------------------------------------------------
/app/src/main/aidl/com/wits/pms/IPowerManagerAppService.aidl:
--------------------------------------------------------------------------------
1 | package com.wits.pms;
2 |
3 | interface IPowerManagerAppService {
4 | boolean sendCommand(String str);
5 | boolean sendStatus(String str);
6 | void registerCmdListener(com.wits.pms.ICmdListener iCmdListener);
7 | void unregisterCmdListener(com.wits.pms.ICmdListener iCmdListener);
8 | void registerObserver(String str, com.wits.pms.IContentObserver iContentObserver);
9 | void unregisterObserver(com.wits.pms.IContentObserver iContentObserver);
10 | boolean getStatusBoolean(String str);
11 | int getStatusInt(String str);
12 | String getStatusString(String str);
13 | int getSettingsInt(String str);
14 | String getSettingsString(String str);
15 | void setSettingsInt(String str, int i);
16 | void setSettingsString(String str, String str2);
17 | void addIntStatus(String str, int i);
18 | void addBooleanStatus(String str, boolean z);
19 | void addStringStatus(String str, String str2);
20 | void saveJsonConfig(String str, String str2);
21 | String getJsonConfig(String str);
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/aidl/com/wits/pms/custom/ICallBack.aidl:
--------------------------------------------------------------------------------
1 | package com.wits.pms.custom;
2 |
3 | interface ICallBack {
4 | void onReverse(int z);
5 | void onLRReverse(int i);
6 | void onRRadar(int i, int i2, int i3, int i4, int i5);
7 | void onFRadar(int i, int i2, int i3, int i4, int i5);
8 | void onAngle(int i);
9 | void onDoor(boolean z, boolean z2, boolean z3, boolean z4, boolean z5, boolean z6);
10 | void onAcc(boolean z);
11 | }
--------------------------------------------------------------------------------
/app/src/main/aidl/com/wits/pms/custom/ICallBackController.aidl:
--------------------------------------------------------------------------------
1 | package com.wits.pms.custom;
2 |
3 | interface ICallBackController {
4 | void setICallBack(com.wits.pms.custom.ICallBack iCallBack);
5 | com.wits.pms.custom.ICallBack getICallBack();
6 | }
--------------------------------------------------------------------------------
/app/src/main/ic_launcher-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Snaggly/KSW-ToolKit/cd4f2a88a04ac21ec6c814eec942c36859afc510/app/src/main/ic_launcher-playstore.png
--------------------------------------------------------------------------------
/app/src/main/ic_launcher_wabes-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Snaggly/KSW-ToolKit/cd4f2a88a04ac21ec6c814eec942c36859afc510/app/src/main/ic_launcher_wabes-playstore.png
--------------------------------------------------------------------------------
/app/src/main/ic_launcher_wabes_round-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Snaggly/KSW-ToolKit/cd4f2a88a04ac21ec6c814eec942c36859afc510/app/src/main/ic_launcher_wabes_round-playstore.png
--------------------------------------------------------------------------------
/app/src/main/java/com/snaggly/ksw_toolkit/core/config/ConfigData.kt:
--------------------------------------------------------------------------------
1 | package com.snaggly.ksw_toolkit.core.config
2 |
3 | import com.snaggly.ksw_toolkit.core.config.beans.AdvancedBrightness
4 | import com.snaggly.ksw_toolkit.core.config.beans.EventManager
5 | import com.snaggly.ksw_toolkit.core.config.beans.SystemOptions
6 | import com.snaggly.ksw_toolkit.util.list.eventtype.EventManagerTypes
7 |
8 | data class ConfigData(
9 | var systemOptions: SystemOptions,
10 | var eventManagers : HashMap,
11 | var advancedBrightness: AdvancedBrightness
12 | )
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/snaggly/ksw_toolkit/core/config/ConfigManager.kt:
--------------------------------------------------------------------------------
1 | package com.snaggly.ksw_toolkit.core.config
2 |
3 | import com.google.gson.Gson
4 | import com.snaggly.ksw_toolkit.core.config.beans.SystemOptions
5 | import com.snaggly.ksw_toolkit.core.service.helper.CoreServiceClient
6 | import java.io.*
7 |
8 | class ConfigManager private constructor() {
9 | companion object {
10 | private val gson = Gson()
11 |
12 | fun getConfigFromJson(json : String) : ConfigData{
13 | return gson.fromJson(json, ConfigData::class.java)
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/snaggly/ksw_toolkit/core/config/beans/AdvancedBrightness.kt:
--------------------------------------------------------------------------------
1 | package com.snaggly.ksw_toolkit.core.config.beans
2 |
3 | class AdvancedBrightness (
4 | var isTimeBasedEnabled: Boolean?,
5 | var isUSBBasedEnabled: Boolean?,
6 | var sunriseAt: String?,
7 | var sunsetAt: String?,
8 | var autoTimes: Boolean?,
9 | var daylightBrightness: Int?,
10 | var daylightHLBrightness: Int?,
11 | var nightBrightnessLevel: Int?,
12 | var nightHLBrightnessLevel: Int?
13 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/snaggly/ksw_toolkit/core/config/beans/EventManager.kt:
--------------------------------------------------------------------------------
1 | package com.snaggly.ksw_toolkit.core.config.beans
2 |
3 | import com.snaggly.ksw_toolkit.util.list.eventtype.EventMode
4 |
5 | class EventManager(var eventMode: EventMode, var keyCode: Int, var appName: String,
6 | var mcuCommandMode: Int, var taskerTaskName: String
7 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/snaggly/ksw_toolkit/core/config/beans/SystemOptions.kt:
--------------------------------------------------------------------------------
1 | package com.snaggly.ksw_toolkit.core.config.beans
2 |
3 | class SystemOptions(
4 | var startAtBoot: Boolean? = false,
5 | var hijackCS: Boolean? = false,
6 | var soundRestorer: Boolean? = false,
7 | var autoTheme: Boolean? = false,
8 | var autoVolume: Boolean? = false,
9 | var retainVolume: Boolean? = false,
10 | var logMcuEvent: Boolean? = true,
11 | var interceptMcuCommand: Boolean? = true,
12 | var extraMediaButtonHandle: Boolean? = false,
13 | var nightBrightness: Boolean? = false,
14 | var nightBrightnessLevel: Int? = 65,
15 | var mcuPath: String? = "",
16 | var tabletMode: Boolean? = false,
17 | var hideStartMessage: Boolean? = false,
18 | var decoupleNAVBtn: Boolean?
19 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/snaggly/ksw_toolkit/core/service/adb/AdbServiceConnection.kt:
--------------------------------------------------------------------------------
1 | package com.snaggly.ksw_toolkit.core.service.adb
2 |
3 | import android.content.Context
4 | import com.snaggly.ksw_toolkit.core.service.helper.CoreServiceClient
5 | import com.snaggly.ksw_toolkit.util.adb.AdbManager
6 |
7 | object AdbServiceConnection {
8 | fun stopKsw(context: Context) {
9 | AdbManager.sendCommand("am stopservice --user 0 com.wits.pms/com.wits.pms.mcu.McuService\nappops set com.wits.pms SYSTEM_ALERT_WINDOW deny", context)
10 | }
11 |
12 | fun startKsw(context: Context) {
13 | AdbManager.sendCommand("am startservice --user 0 com.wits.pms/com.wits.pms.mcu.McuService\nappops set com.wits.pms SYSTEM_ALERT_WINDOW allow", context)
14 | }
15 |
16 | fun startThisService(context: Context) {
17 | AdbManager.sendCommand("am startservice --user 0 ${CoreServiceClient.packageName}/${CoreServiceClient.className}", context)
18 | //AdbManager.sendCommand("am startservice --user 0 com.snaggly.wits.ksw_toolkit.service/com.snaggly.ksw_toolkit.core.service.CoreService", context)
19 | }
20 |
21 | fun stopThisService(context: Context) {
22 | AdbManager.sendCommand("am stopservice --user 0 ${CoreServiceClient.packageName}/${CoreServiceClient.className}", context)
23 | }
24 |
25 | fun sendKeyEvent(code: Int, context: Context) {
26 | AdbManager.sendCommand("input keyevent $code", context)
27 | }
28 |
29 | fun startApp(appId: String, context: Context) {
30 | AdbManager.sendCommand("monkey -p $appId -c android.intent.category.LAUNCHER 1", context)
31 | }
32 |
33 | fun sendCommand(command: String, context: Context) {
34 | AdbManager.sendCommand("$command\n", context)
35 | }
36 |
37 | fun checkIfThisServiceIsAlive(context: Context) {
38 | AdbManager.sendCommand("dumpsys activity services ${CoreServiceClient.packageName} | grep \"ServiceRecord\" | awk '{print $4}' | sed 's/.$//'", context)
39 | }
40 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/snaggly/ksw_toolkit/core/service/helper/ServiceAliveCheck.kt:
--------------------------------------------------------------------------------
1 | package com.snaggly.ksw_toolkit.core.service.helper
2 |
3 | import android.content.Context
4 | import androidx.lifecycle.Observer
5 | import com.snaggly.ksw_toolkit.core.service.adb.AdbServiceConnection
6 | import com.snaggly.ksw_toolkit.util.adb.AdbManager
7 | import com.snaggly.ksw_toolkit.util.adb.ShellObserver
8 | import java.util.*
9 | import kotlin.collections.ArrayList
10 |
11 | object ServiceAliveCheck {
12 | val serviceAliveObservers = LinkedList>()
13 |
14 | fun checkIfServiceIsAlive(context: Context) {
15 | AdbManager.connect(context)
16 | AdbManager.registerShellListener( object : ShellObserver {
17 | override fun update(newLines: ArrayList) {
18 | var isRunning = false
19 | for (line in newLines) {
20 | if (line.contains("${CoreServiceClient.packageName}/${CoreServiceClient.className}")) {
21 | isRunning = true
22 | break
23 | }
24 | }
25 | if (isRunning || newLines.size > 1) {
26 | AdbManager.unregisterShellListener()
27 | serviceAliveObservers.forEach {
28 | it.onChanged(isRunning)
29 | }
30 | }
31 | }
32 | }, context)
33 | AdbServiceConnection.checkIfThisServiceIsAlive(context)
34 | }
35 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/snaggly/ksw_toolkit/gui/AdbShell.kt:
--------------------------------------------------------------------------------
1 | package com.snaggly.ksw_toolkit.gui
2 |
3 | import android.os.Bundle
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import android.widget.ArrayAdapter
8 | import android.widget.Button
9 | import android.widget.ListView
10 | import android.widget.Toast
11 | import androidx.fragment.app.Fragment
12 | import androidx.lifecycle.ViewModelProvider
13 | import com.google.android.material.textfield.TextInputEditText
14 | import com.snaggly.ksw_toolkit.R
15 | import com.snaggly.ksw_toolkit.util.adb.ShellObserver
16 | import com.snaggly.ksw_toolkit.gui.viewmodels.AdbShellViewModel
17 | import com.snaggly.ksw_toolkit.util.adb.AdbManager
18 |
19 | class AdbShell : Fragment() {
20 |
21 | private val adbShellObserver = object : ShellObserver {
22 | override fun update(newLines: ArrayList) {
23 | requireActivity().runOnUiThread {
24 | newLines.forEach {
25 | adbLines[0] += it
26 | }
27 | listAdapter.notifyDataSetChanged()
28 | }
29 | }
30 | }
31 |
32 | companion object {
33 | fun newInstance() = AdbShell()
34 | }
35 |
36 | private lateinit var viewModel: AdbShellViewModel
37 | private lateinit var shellListView: ListView
38 | private lateinit var textInput: TextInputEditText
39 | private lateinit var sendButton: Button
40 | private lateinit var listAdapter: ArrayAdapter
41 | private val adbLines : ArrayList = arrayListOf("")
42 |
43 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
44 | savedInstanceState: Bundle?): View? {
45 | return inflater.inflate(R.layout.adb_shell_fragment, container, false)
46 | }
47 |
48 | override fun onActivityCreated(savedInstanceState: Bundle?) {
49 | super.onActivityCreated(savedInstanceState)
50 | viewModel = ViewModelProvider(this).get(AdbShellViewModel::class.java)
51 | initElements()
52 | initClickEvent()
53 | }
54 |
55 | override fun onStart() {
56 | super.onStart()
57 | sendButton.requestFocus()
58 | initList()
59 | try {
60 | AdbManager.registerShellListener(adbShellObserver, requireContext())
61 | }
62 | catch (e : Exception) {
63 | Toast.makeText(requireContext(), "Could not start Service", Toast.LENGTH_LONG).show()
64 | }
65 | }
66 |
67 | override fun onResume() {
68 | super.onResume()
69 | adbLines[0] = ""
70 | listAdapter.notifyDataSetChanged()
71 | }
72 |
73 | override fun onStop() {
74 | super.onStop()
75 | try {
76 | AdbManager.unregisterShellListener()
77 | }
78 | catch (e : Exception) {}
79 | }
80 |
81 | private fun initElements() {
82 | shellListView = requireView().findViewById(R.id.adbShellStdoutListView)
83 | textInput = requireView().findViewById(R.id.adbEditText)
84 | sendButton = requireView().findViewById(R.id.adbSend)
85 | }
86 |
87 | private fun initList() {
88 | listAdapter = ArrayAdapter(requireContext(), android.R.layout.simple_list_item_1, adbLines)
89 | shellListView.adapter = listAdapter
90 | }
91 |
92 | private fun initClickEvent() {
93 | sendButton.setOnClickListener {
94 | AdbManager.sendCommand(textInput.text.toString(), requireContext())
95 | textInput.setText("")
96 | }
97 | }
98 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/snaggly/ksw_toolkit/gui/ConfigImportExport.kt:
--------------------------------------------------------------------------------
1 | package com.snaggly.ksw_toolkit.gui
2 |
3 | import android.app.AlertDialog
4 | import android.content.Intent
5 | import androidx.lifecycle.ViewModelProvider
6 | import android.os.Bundle
7 | import android.view.LayoutInflater
8 | import android.view.View
9 | import android.view.ViewGroup
10 | import android.view.WindowManager
11 | import android.widget.Button
12 | import android.widget.Toast
13 | import androidx.activity.result.ActivityResultLauncher
14 | import androidx.activity.result.contract.ActivityResultContract
15 | import androidx.activity.result.contract.ActivityResultContracts
16 | import androidx.fragment.app.Fragment
17 | import com.snaggly.ksw_toolkit.R
18 | import com.snaggly.ksw_toolkit.gui.viewmodels.ConfigImportExportViewModel
19 | import com.snaggly.ksw_toolkit.util.adb.AdbManager
20 |
21 | class ConfigImportExport(private val getContent: ActivityResultLauncher,
22 | private val createDocument: ActivityResultLauncher) : Fragment() {
23 | private lateinit var importExportViewModel: ConfigImportExportViewModel
24 | private lateinit var importConfigBtn: Button
25 | private lateinit var exportConfigBtn: Button
26 | private lateinit var restartBtn: Button
27 |
28 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
29 | savedInstanceState: Bundle?): View? {
30 |
31 | return inflater.inflate(R.layout.config_fragment, container, false)
32 | }
33 |
34 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
35 | super.onViewCreated(view, savedInstanceState)
36 | importExportViewModel = ViewModelProvider(this).get(ConfigImportExportViewModel::class.java)
37 | initBtns()
38 | initBtnClicks()
39 | }
40 |
41 | private fun initBtns() {
42 | importConfigBtn = requireView().findViewById(R.id.importConfigBtn)
43 | exportConfigBtn = requireView().findViewById(R.id.exportConfigBtn)
44 | restartBtn = requireView().findViewById(R.id.restartSystemBtn)
45 | }
46 |
47 | private fun initBtnClicks() {
48 | importConfigBtn.setOnClickListener {
49 | try {
50 | getContent.launch("*/*")
51 | } catch (exception: Exception) {
52 | val alertExc = AlertDialog.Builder(activity, R.style.alertDialogNight).setTitle("KSW-ToolKit-Config")
53 | .setMessage("Unable to import!\n\n$exception").create()
54 | alertExc.show()
55 | }
56 | }
57 |
58 | exportConfigBtn.setOnClickListener {
59 | try {
60 | createDocument.launch("KSW-ToolKit.json")
61 | } catch (exception: Exception) {
62 | val alertExc = AlertDialog.Builder(activity, R.style.alertDialogNight).setTitle("KSW-ToolKit-Config")
63 | .setMessage("Unable to export!\n\n$exception").create()
64 | alertExc.show()
65 | }
66 | }
67 |
68 | restartBtn.setOnClickListener {
69 | try {
70 | AdbManager.sendCommand("reboot", requireContext())
71 | } catch (exception: Exception) {
72 | val alertExc = AlertDialog.Builder(activity, R.style.alertDialogNight).setTitle("KSW-ToolKit-Config")
73 | .setMessage("Unable to restart!\n\n${exception.stackTrace}").create()
74 | alertExc.show()
75 | }
76 | }
77 | }
78 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/snaggly/ksw_toolkit/gui/McuListener.kt:
--------------------------------------------------------------------------------
1 | package com.snaggly.ksw_toolkit.gui
2 |
3 | import androidx.lifecycle.ViewModelProvider
4 | import android.os.Bundle
5 | import android.view.LayoutInflater
6 | import android.view.MenuItem
7 | import android.view.View
8 | import android.view.ViewGroup
9 | import android.widget.Button
10 | import android.widget.TextView
11 | import androidx.fragment.app.Fragment
12 | import androidx.recyclerview.widget.LinearLayoutManager
13 | import androidx.recyclerview.widget.RecyclerView
14 | import com.google.android.material.textfield.TextInputEditText
15 | import com.snaggly.ksw_toolkit.IMcuListener
16 | import com.snaggly.ksw_toolkit.R
17 | import com.snaggly.ksw_toolkit.core.service.helper.CoreServiceClient
18 | import com.snaggly.ksw_toolkit.gui.viewmodels.McuListenerViewModel
19 | import com.snaggly.ksw_toolkit.util.list.mcu.McuData
20 | import java.lang.NumberFormatException
21 |
22 | class McuListener(private val coreServiceClient: CoreServiceClient) : Fragment() {
23 |
24 | private lateinit var viewModel: McuListenerViewModel
25 | private lateinit var mcuEventRV: RecyclerView
26 | private lateinit var mcuEventFilterRV: RecyclerView
27 |
28 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
29 | savedInstanceState: Bundle?): View? {
30 | return inflater.inflate(R.layout.mcu_listener_fragment, container, false)
31 | }
32 |
33 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
34 | super.onViewCreated(view, savedInstanceState)
35 | viewModel = ViewModelProvider(this).get(McuListenerViewModel::class.java)
36 | initElements()
37 | }
38 |
39 | override fun onResume() {
40 | super.onResume()
41 | coreServiceClient.coreService?.registerMcuListener(mcuObserver)
42 | }
43 |
44 | override fun onPause() {
45 | coreServiceClient.coreService?.unregisterMcuListener(mcuObserver)
46 | super.onPause()
47 | }
48 |
49 | override fun onContextItemSelected(item: MenuItem): Boolean {
50 | if (item.itemId == 1) {
51 | viewModel.getLastSelectedEvent()?.let { addFilterElement(it) }
52 | }
53 | return super.onContextItemSelected(item)
54 | }
55 |
56 | private fun addFilterElement(mcuData: McuData) {
57 | if (!viewModel.mcuFilter.contains(mcuData))
58 | viewModel.mcuFilter.add(mcuData)
59 | viewModel.addFilterEntryToAdapter(mcuData)
60 | }
61 |
62 | private fun initElements() {
63 | mcuEventRV = requireView().findViewById(R.id.McuEventsRV);
64 | mcuEventRV.layoutManager = LinearLayoutManager(context)
65 | mcuEventRV.adapter = viewModel.getMcuEventAdapter()
66 |
67 | mcuEventFilterRV = requireView().findViewById(R.id.filterListRV);
68 | mcuEventFilterRV.layoutManager = LinearLayoutManager(context)
69 | mcuEventFilterRV.adapter = viewModel.getMcuEventFilterAdapter()
70 |
71 | val filterNoticeTV = requireView().findViewById(R.id.noFiltersNoticeTV).apply {
72 | viewModel.filterListChangedObserver = {
73 | visibility = if (mcuEventFilterRV.visibility == View.GONE || viewModel.mcuFilter.size > 0)
74 | View.GONE
75 | else
76 | View.VISIBLE
77 | }
78 | }
79 |
80 | requireView().findViewById