├── .gitignore ├── .idea ├── .gitignore ├── .name ├── androidTestResultsUserPreferences.xml ├── compiler.xml ├── copyright │ ├── profiles_settings.xml │ └── xjunz.xml ├── gradle.xml ├── inspectionProfiles │ └── Project_Default.xml ├── kotlinc.xml ├── misc.xml └── vcs.xml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── dprotect-rules.pro ├── proguard-rules.pro ├── screenshots │ ├── Screenshot_light_1.png │ ├── Screenshot_light_2.png │ ├── Screenshot_night_1.png │ └── Screenshot_night_2.png └── src │ ├── androidTest │ └── kotlin │ │ └── top │ │ └── xjunz │ │ └── tasker │ │ ├── UiAutomationRegistry.kt │ │ ├── bridge │ │ ├── ClipboardManagerBridgeTest.kt │ │ └── PackageManagerBridgeTest.kt │ │ └── task │ │ ├── AccessibilityNodeInfo.kt │ │ └── event │ │ └── A11yEventDispatcherTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── aidl │ │ └── top │ │ │ └── xjunz │ │ │ └── tasker │ │ │ ├── service │ │ │ └── IRemoteAutomatorService.aidl │ │ │ └── task │ │ │ └── runtime │ │ │ ├── IOnTaskPauseStateListener.aidl │ │ │ ├── IRemoteTaskManager.aidl │ │ │ └── ITaskCompletionCallback.aidl │ ├── assets │ │ ├── confetti.js │ │ ├── examples.xtsks │ │ ├── index-cannon.html │ │ ├── index-continuous.html │ │ ├── presets.xtsks │ │ └── privacy-policy.html │ ├── ic_launcher-playstore.png │ ├── java │ │ └── top │ │ │ └── xjunz │ │ │ └── tasker │ │ │ ├── App.kt │ │ │ ├── Preferences.kt │ │ │ ├── annotation │ │ │ ├── Anywhere.kt │ │ │ ├── FieldOrder.kt │ │ │ ├── Local.kt │ │ │ └── Privileged.kt │ │ │ ├── api │ │ │ ├── Client.kt │ │ │ ├── CodeBodyReply.kt │ │ │ ├── DTOExt.kt │ │ │ ├── DTOs.kt │ │ │ ├── SecurityUtil.kt │ │ │ └── UpdateInfo.kt │ │ │ ├── autostart │ │ │ ├── AutoStartUtil.kt │ │ │ └── AutoStarter.kt │ │ │ ├── bridge │ │ │ ├── A11yUiAutomatorBridge.kt │ │ │ ├── ActivityManagerBridge.kt │ │ │ ├── BatteryManagerBridge.kt │ │ │ ├── ClipboardManagerBridge.kt │ │ │ ├── ConnectivityManagerBridge.kt │ │ │ ├── ContextBridge.kt │ │ │ ├── ContextUiAutomatorBridge.kt │ │ │ ├── DisplayManagerBridge.kt │ │ │ ├── OverlayToastBridge.kt │ │ │ ├── PackageManagerBridge.kt │ │ │ ├── PowerManagerBridge.kt │ │ │ ├── PrivilegedUiAutomatorBridge.kt │ │ │ ├── ThemedWindowContext.kt │ │ │ └── VibratorBridge.kt │ │ │ ├── ktx │ │ │ ├── AccessibilityNodeInfo.kt │ │ │ ├── BindingAdapters.kt │ │ │ ├── Bitmap.kt │ │ │ ├── BottomSheet.kt │ │ │ ├── Color.kt │ │ │ ├── Context.kt │ │ │ ├── Defer.kt │ │ │ ├── Dialogs.kt │ │ │ ├── Fragment.kt │ │ │ ├── IBinder.kt │ │ │ ├── LifecycleOwner.kt │ │ │ ├── LiveData.kt │ │ │ ├── MaterialShapeDrawable.kt │ │ │ ├── PopupMenu.kt │ │ │ ├── RecyclerView.kt │ │ │ ├── Resources.kt │ │ │ ├── Spannable.kt │ │ │ ├── String.kt │ │ │ ├── Toast.kt │ │ │ ├── Views.kt │ │ │ └── ZipOutputStream.kt │ │ │ ├── premium │ │ │ ├── FieldOrdinal.kt │ │ │ ├── PaymentRequiredException.kt │ │ │ ├── PremiumContext.java │ │ │ └── PremiumMixin.kt │ │ │ ├── service │ │ │ ├── A11yAutomatorService.kt │ │ │ ├── AutomatorService.kt │ │ │ ├── Environment.kt │ │ │ ├── OperatingMode.kt │ │ │ ├── ShizukuAutomatorService.kt │ │ │ └── controller │ │ │ │ ├── A11yAutomatorServiceController.kt │ │ │ │ ├── ServiceController.kt │ │ │ │ ├── ShizukuAutomatorServiceController.kt │ │ │ │ └── ShizukuServiceController.kt │ │ │ ├── task │ │ │ ├── applet │ │ │ │ ├── action │ │ │ │ │ ├── FileAction.kt │ │ │ │ │ ├── GestureAction.kt │ │ │ │ │ ├── PauseFor.kt │ │ │ │ │ ├── PauseUntilTomorrow.kt │ │ │ │ │ ├── ShellCmdAction.kt │ │ │ │ │ └── Vibrate.kt │ │ │ │ ├── anno │ │ │ │ │ └── AppletOrdinal.kt │ │ │ │ ├── criterion │ │ │ │ │ ├── BoundsCriterion.kt │ │ │ │ │ ├── EventFilter.kt │ │ │ │ │ ├── FileEventCriterion.kt │ │ │ │ │ └── NumberRangeCriterion.kt │ │ │ │ ├── flow │ │ │ │ │ ├── ClickButtonWithText.kt │ │ │ │ │ ├── ClickUiObjectIfExists.kt │ │ │ │ │ ├── ClickUiObjectWithText.kt │ │ │ │ │ ├── ContainsUiObject.kt │ │ │ │ │ ├── ElseStopship.kt │ │ │ │ │ ├── ForEachUiScrollable.kt │ │ │ │ │ ├── InputTextToFirstTextField.kt │ │ │ │ │ ├── PerformActionIfUiObjectExistsInCurrentWindow.kt │ │ │ │ │ ├── PhantomFlow.kt │ │ │ │ │ ├── PreloadFlow.kt │ │ │ │ │ ├── ScrollIntoUiObject.kt │ │ │ │ │ ├── TimeFlow.kt │ │ │ │ │ ├── UiObjectMatches.kt │ │ │ │ │ ├── UiObjectTarget.kt │ │ │ │ │ └── ref │ │ │ │ │ │ ├── ComponentInfoWrapper.kt │ │ │ │ │ │ ├── NotificationReferent.kt │ │ │ │ │ │ └── UiObjectReferent.kt │ │ │ │ ├── option │ │ │ │ │ ├── AppletFactoryUpdateHelper.kt │ │ │ │ │ ├── AppletOption.kt │ │ │ │ │ ├── AppletOptionFactory.kt │ │ │ │ │ ├── descriptor │ │ │ │ │ │ ├── ArgumentDescriptor.kt │ │ │ │ │ │ └── ValueDescriptor.kt │ │ │ │ │ └── registry │ │ │ │ │ │ ├── AppletOptionRegistry.kt │ │ │ │ │ │ ├── ApplicationActionRegistry.kt │ │ │ │ │ │ ├── ApplicationCriterionRegistry.kt │ │ │ │ │ │ ├── BootstrapOptionRegistry.kt │ │ │ │ │ │ ├── ControlActionRegistry.kt │ │ │ │ │ │ ├── EventCriterionRegistry.kt │ │ │ │ │ │ ├── FileActionRegistry.kt │ │ │ │ │ │ ├── GestureActionRegistry.kt │ │ │ │ │ │ ├── GlobalActionRegistry.kt │ │ │ │ │ │ ├── GlobalCriterionRegistry.kt │ │ │ │ │ │ ├── NetworkCriterionRegistry.kt │ │ │ │ │ │ ├── ShellCmdActionRegistry.kt │ │ │ │ │ │ ├── TextActionRegistry.kt │ │ │ │ │ │ ├── TextCriterionRegistry.kt │ │ │ │ │ │ ├── TimeCriterionRegistry.kt │ │ │ │ │ │ ├── UiObjectActionRegistry.kt │ │ │ │ │ │ ├── UiObjectCriterionRegistry.kt │ │ │ │ │ │ ├── UiObjectFlowRegistry.kt │ │ │ │ │ │ └── VibrationActionRegistry.kt │ │ │ │ ├── util │ │ │ │ │ ├── IntValueUtil.kt │ │ │ │ │ └── NumberRangeUtil.kt │ │ │ │ └── value │ │ │ │ │ ├── BitwiseValueComposer.kt │ │ │ │ │ ├── Distance.kt │ │ │ │ │ ├── LongDuration.kt │ │ │ │ │ ├── ScrollMetrics.kt │ │ │ │ │ ├── SwipeMetrics.kt │ │ │ │ │ ├── ValueComposer.kt │ │ │ │ │ └── VariantArgType.kt │ │ │ ├── editor │ │ │ │ └── AppletReferenceEditor.kt │ │ │ ├── event │ │ │ │ ├── A11yEventDispatcher.kt │ │ │ │ ├── ClipboardEventDispatcher.kt │ │ │ │ ├── MetaEventDispatcher.kt │ │ │ │ ├── NetworkEventDispatcher.kt │ │ │ │ └── PollEventDispatcher.kt │ │ │ ├── gesture │ │ │ │ ├── GestureRecorder.kt │ │ │ │ └── SerializableInputEvent.kt │ │ │ ├── inspector │ │ │ │ ├── FloatingInspector.kt │ │ │ │ ├── InspectorMode.kt │ │ │ │ ├── InspectorViewModel.kt │ │ │ │ ├── StableNodeInfo.kt │ │ │ │ └── overlay │ │ │ │ │ ├── BoundsDetectorOverlay.kt │ │ │ │ │ ├── CollapsedBubbleOverlay.kt │ │ │ │ │ ├── ComponentOverlay.kt │ │ │ │ │ ├── ExpandedBubbleOverlay.kt │ │ │ │ │ ├── FloatingInspectorOverlay.kt │ │ │ │ │ ├── GestureShowcaseOverlay.kt │ │ │ │ │ ├── InspectorViewOverlay.kt │ │ │ │ │ ├── NodeInfoOverlay.kt │ │ │ │ │ ├── NodeTreeOverlay.kt │ │ │ │ │ ├── TaskAssistantOverlay.kt │ │ │ │ │ ├── ToastOverlay.kt │ │ │ │ │ └── TrashBinOverlay.kt │ │ │ ├── runtime │ │ │ │ ├── LocalTaskManager.kt │ │ │ │ ├── OneshotTaskScheduler.kt │ │ │ │ ├── PrivilegedTaskManager.kt │ │ │ │ └── ResidentTaskScheduler.kt │ │ │ └── storage │ │ │ │ └── TaskStorage.kt │ │ │ ├── ui │ │ │ ├── base │ │ │ │ ├── BaseBottomSheetDialog.kt │ │ │ │ ├── BaseDialogFragment.kt │ │ │ │ ├── BaseFragment.kt │ │ │ │ ├── DialogStackMixin.kt │ │ │ │ ├── InlineAdapter.kt │ │ │ │ ├── InnerViewModelFactory.kt │ │ │ │ └── SavedStateViewModel.kt │ │ │ ├── common │ │ │ │ ├── DropdownArrayAdapter.kt │ │ │ │ ├── PreferenceHelpDialog.kt │ │ │ │ └── TextEditorDialog.kt │ │ │ ├── demo │ │ │ │ ├── Demonstration.kt │ │ │ │ ├── DragToMoveDemo.kt │ │ │ │ ├── LongClickToSelectDemo.kt │ │ │ │ └── SwipeToRemoveDemo.kt │ │ │ ├── main │ │ │ │ ├── AboutFragment.kt │ │ │ │ ├── ColorScheme.kt │ │ │ │ ├── DialogStackManager.kt │ │ │ │ ├── EventCenter.kt │ │ │ │ ├── MainActivity.kt │ │ │ │ ├── MainOption.kt │ │ │ │ ├── MainViewModel.kt │ │ │ │ ├── PrivacyPolicyDialog.kt │ │ │ │ ├── ScrollTarget.kt │ │ │ │ └── VersionInfoDialog.kt │ │ │ ├── model │ │ │ │ ├── ActivityInfoWrapper.kt │ │ │ │ └── PackageInfoWrapper.kt │ │ │ ├── outer │ │ │ │ ├── CrashReportActivity.kt │ │ │ │ └── GlobalCrashHandler.kt │ │ │ ├── purchase │ │ │ │ ├── PurchaseDialog.kt │ │ │ │ └── PurchaseViewModel.kt │ │ │ ├── service │ │ │ │ └── ServiceStarterDialog.kt │ │ │ ├── task │ │ │ │ ├── editor │ │ │ │ │ ├── AppletOperationMenuHelper.kt │ │ │ │ │ ├── FlowCascadeAdapter.kt │ │ │ │ │ ├── FlowEditorDialog.kt │ │ │ │ │ ├── FlowEditorViewModel.kt │ │ │ │ │ ├── FlowItemTouchHelperCallback.kt │ │ │ │ │ ├── FlowItemViewBinder.kt │ │ │ │ │ ├── FlowViewModel.kt │ │ │ │ │ ├── GlobalFlowEditorViewModel.kt │ │ │ │ │ ├── SnapshotLogDialog.kt │ │ │ │ │ ├── TaskFlowAdapter.kt │ │ │ │ │ ├── TaskMetadataEditor.kt │ │ │ │ │ ├── TaskSnapshotSelectorDialog.kt │ │ │ │ │ ├── VarargTextEditorDialog.kt │ │ │ │ │ └── VibrationPatternEditorDialog.kt │ │ │ │ ├── inspector │ │ │ │ │ └── FloatingInspectorDialog.kt │ │ │ │ ├── selector │ │ │ │ │ ├── AppletCandidatesAdapter.kt │ │ │ │ │ ├── AppletOptionClickHandler.kt │ │ │ │ │ ├── AppletSelectorDialog.kt │ │ │ │ │ ├── AppletSelectorViewModel.kt │ │ │ │ │ ├── ShoppingCartIntegration.kt │ │ │ │ │ └── argument │ │ │ │ │ │ ├── ActivityInfoAdapter.kt │ │ │ │ │ │ ├── ActivitySelectorFragment.kt │ │ │ │ │ │ ├── ArgumentsEditorDialog.kt │ │ │ │ │ │ ├── BaseComponentFragment.kt │ │ │ │ │ │ ├── BitsValueEditorDialog.kt │ │ │ │ │ │ ├── ComponentSelectorDialog.kt │ │ │ │ │ │ ├── ComponentSelectorViewModel.kt │ │ │ │ │ │ ├── DateTimeRangeEditorDialog.kt │ │ │ │ │ │ ├── DistanceEditorDialog.kt │ │ │ │ │ │ ├── EnumSelectorDialog.kt │ │ │ │ │ │ ├── PackageInfoAdapter.kt │ │ │ │ │ │ ├── PackageSelectorFragment.kt │ │ │ │ │ │ ├── RangeEditorDialog.kt │ │ │ │ │ │ ├── TimeIntervalEditorDialog.kt │ │ │ │ │ │ ├── TimeRangeEditorDialog.kt │ │ │ │ │ │ └── XYEditorDialog.kt │ │ │ │ └── showcase │ │ │ │ │ ├── BaseTaskShowcaseFragment.kt │ │ │ │ │ ├── EnabledTaskFragment.kt │ │ │ │ │ ├── OneshotTaskFragment.kt │ │ │ │ │ ├── ResidentTaskFragment.kt │ │ │ │ │ ├── TaskCollectionSelectorDialog.kt │ │ │ │ │ ├── TaskCreatorDialog.kt │ │ │ │ │ ├── TaskListDialog.kt │ │ │ │ │ └── TaskShowcaseViewModel.kt │ │ │ └── widget │ │ │ │ ├── DrawBoundsFrameLayout.kt │ │ │ │ ├── FloatingDraggableLayout.kt │ │ │ │ ├── GamePadLayout.kt │ │ │ │ ├── GesturePlaybackView.kt │ │ │ │ ├── GestureRecorderView.kt │ │ │ │ ├── LayoutInspectorView.kt │ │ │ │ ├── LeftCorneredTextView.kt │ │ │ │ ├── LineCounterView.java │ │ │ │ ├── MaterialButtonSpreadContainer.kt │ │ │ │ ├── PopupListMenu.kt │ │ │ │ └── WaveDivider.kt │ │ │ └── util │ │ │ ├── ApplicationIconLoader.kt │ │ │ ├── ClickListenerUtil.kt │ │ │ ├── Feedbacks.kt │ │ │ ├── Icons.kt │ │ │ ├── Motions.kt │ │ │ ├── ReflectionUtil.kt │ │ │ ├── ShizukuUtil.kt │ │ │ └── TimeFormtter.kt │ └── res │ │ ├── anim │ │ ├── dialog_window_enter_sade.xml │ │ ├── dialog_window_enter_slide.xml │ │ ├── dialog_window_exit_sade.xml │ │ ├── dialog_window_exit_slide.xml │ │ └── mtrl_item_ease_enter.xml │ │ ├── animator │ │ ├── sla_appbar.xml │ │ └── sla_extended_fab.xml │ │ ├── color │ │ ├── color_bg_item_enum_selector.xml │ │ ├── color_control_highlight.xml │ │ ├── color_control_on_primary.xml │ │ ├── color_drop_target_stroke_color.xml │ │ ├── color_primary_background.xml │ │ ├── color_status_icon.xml │ │ ├── color_status_text.xml │ │ ├── color_status_tint.xml │ │ ├── color_text_control_highlight.xml │ │ ├── color_text_control_normal.xml │ │ ├── color_text_item_enum_selector.xml │ │ ├── color_text_selectable.xml │ │ └── icon_background.xml │ │ ├── drawable │ │ ├── baseline_add_circle_outline_24.xml │ │ ├── baseline_backup_24.xml │ │ ├── baseline_chat_24.xml │ │ ├── baseline_group_add_24.xml │ │ ├── baseline_hourglass_empty_24.xml │ │ ├── baseline_info_24.xml │ │ ├── baseline_nights_stay_24.xml │ │ ├── baseline_restart_alt_24.xml │ │ ├── bg_badge.xml │ │ ├── bg_bottom_sheet_handler.xml │ │ ├── bg_dialog.xml │ │ ├── bg_drop_target.xml │ │ ├── bg_dummy_target.xml │ │ ├── bg_floating_inspector_trash_bin.xml │ │ ├── bg_selectable_circle.xml │ │ ├── bg_selectable_item.xml │ │ ├── bg_selectable_outlined_surface.xml │ │ ├── bg_selectable_primary_surface.xml │ │ ├── bg_selectable_surface.xml │ │ ├── bg_selectable_tinted_circle.xml │ │ ├── bg_selector_applet_factory.xml │ │ ├── bg_solid_circle.xml │ │ ├── bg_surface.xml │ │ ├── bg_tinted_chip.xml │ │ ├── ic_ads_click_24px.xml │ │ ├── ic_arrow_back_24px.xml │ │ ├── ic_baseline_add_24.xml │ │ ├── ic_baseline_add_link_24.xml │ │ ├── ic_baseline_android_24.xml │ │ ├── ic_baseline_auto_awesome_24.xml │ │ ├── ic_baseline_bug_report_24.xml │ │ ├── ic_baseline_chevron_left_24.xml │ │ ├── ic_baseline_close_24.xml │ │ ├── ic_baseline_expand_less_24.xml │ │ ├── ic_baseline_expand_more_24.xml │ │ ├── ic_baseline_gamepad_24.xml │ │ ├── ic_baseline_grid_off_24.xml │ │ ├── ic_baseline_grid_on_24.xml │ │ ├── ic_baseline_help_outline_24.xml │ │ ├── ic_baseline_keyboard_arrow_down_24.xml │ │ ├── ic_baseline_keyboard_arrow_up_24.xml │ │ ├── ic_baseline_link_24.xml │ │ ├── ic_baseline_more_vert_24.xml │ │ ├── ic_baseline_my_location_24.xml │ │ ├── ic_baseline_navigate_before_24.xml │ │ ├── ic_baseline_navigate_next_24.xml │ │ ├── ic_baseline_open_in_new_24.xml │ │ ├── ic_baseline_play_arrow_24.xml │ │ ├── ic_baseline_schedule_24.xml │ │ ├── ic_baseline_send_24.xml │ │ ├── ic_baseline_stop_24.xml │ │ ├── ic_baseline_switch_24.xml │ │ ├── ic_baseline_task_alt_24.xml │ │ ├── ic_baseline_unfold_less_24.xml │ │ ├── ic_baseline_unfold_more_24.xml │ │ ├── ic_call_split_24px.xml │ │ ├── ic_cancel_24px.xml │ │ ├── ic_check_circle_24px.xml │ │ ├── ic_chevron_right_24px.xml │ │ ├── ic_clear_all_24px.xml │ │ ├── ic_content_copy_24px.xml │ │ ├── ic_delete_forever_24px.xml │ │ ├── ic_description_24px.xml │ │ ├── ic_do_not_disturb_24px.xml │ │ ├── ic_done_24px.xml │ │ ├── ic_edit_24dp.xml │ │ ├── ic_filter_list_24px.xml │ │ ├── ic_gesture_24px.xml │ │ ├── ic_help_24px.xml │ │ ├── ic_history_24px.xml │ │ ├── ic_hourglass_bottom_24px.xml │ │ ├── ic_import_24dp.xml │ │ ├── ic_launcher_background.xml │ │ ├── ic_launcher_foreground.xml │ │ ├── ic_line_end_arrow_notch_24dp.xml │ │ ├── ic_line_start_24dp.xml │ │ ├── ic_menu_24px.xml │ │ ├── ic_outline_hide_image_24.xml │ │ ├── ic_outline_image_24.xml │ │ ├── ic_outline_lock_24.xml │ │ ├── ic_outline_share_24.xml │ │ ├── ic_playlist_add_24px.xml │ │ ├── ic_redeem_24px.xml │ │ ├── ic_remove_shopping_cart.xml │ │ ├── ic_replay_24px.xml │ │ ├── ic_save_24px.xml │ │ ├── ic_search_24px.xml │ │ ├── ic_status_control.xml │ │ ├── ic_swap_horiz_24px.xml │ │ ├── ic_text_fields_24px.xml │ │ ├── ic_tips_and_updates_24dp.xml │ │ ├── ic_touch_app_24px.xml │ │ ├── ic_tune_24px.xml │ │ ├── ic_twotone_cancel_24.xml │ │ ├── ic_twotone_check_circle_24.xml │ │ ├── ic_twotone_format_list_bulleted_24.xml │ │ ├── ic_twotone_layers_24.xml │ │ ├── ic_twotone_navigation_24.xml │ │ ├── ic_verified_24px.xml │ │ ├── ic_widgets_24px.xml │ │ ├── selector_bg_flow_item_demo.xml │ │ ├── selector_bg_selectable_item.xml │ │ └── selector_bg_selectable_surface_item.xml │ │ ├── layout-land │ │ ├── overlay_node_info.xml │ │ └── overlay_node_tree.xml │ │ ├── layout │ │ ├── activity_crash_report.xml │ │ ├── activity_main.xml │ │ ├── dialog_activity_selector.xml │ │ ├── dialog_applet_selector.xml │ │ ├── dialog_arguments_editor.xml │ │ ├── dialog_bits_value_editor.xml │ │ ├── dialog_component_selector.xml │ │ ├── dialog_coordinate_editor.xml │ │ ├── dialog_distance_editor.xml │ │ ├── dialog_enum_selector.xml │ │ ├── dialog_floating_inspector.xml │ │ ├── dialog_flow_editor.xml │ │ ├── dialog_gestures_editor.xml │ │ ├── dialog_preference_help.xml │ │ ├── dialog_privacy_policy.xml │ │ ├── dialog_purchase.xml │ │ ├── dialog_range_editor.xml │ │ ├── dialog_service_starter.xml │ │ ├── dialog_snapshot_selector.xml │ │ ├── dialog_task_collection_selector.xml │ │ ├── dialog_task_creator.xml │ │ ├── dialog_task_list.xml │ │ ├── dialog_task_log.xml │ │ ├── dialog_task_metadata_editor.xml │ │ ├── dialog_task_showcase.xml │ │ ├── dialog_text_editor.xml │ │ ├── dialog_time_interval_editor.xml │ │ ├── dialog_vararg_text_editor.xml │ │ ├── dialog_version_info.xml │ │ ├── dialog_vibration_pattern_editor.xml │ │ ├── fragment_about.xml │ │ ├── fragment_component_selector.xml │ │ ├── fragment_task_showcase.xml │ │ ├── item_activity_info.xml │ │ ├── item_applet_candidate.xml │ │ ├── item_applet_cateory.xml │ │ ├── item_applet_factory.xml │ │ ├── item_applet_option.xml │ │ ├── item_application_info.xml │ │ ├── item_argument_editor.xml │ │ ├── item_bread_crumbs.xml │ │ ├── item_check_case.xml │ │ ├── item_enum_selector.xml │ │ ├── item_flow_cascade.xml │ │ ├── item_flow_item.xml │ │ ├── item_flow_name.xml │ │ ├── item_flow_opt_demo.xml │ │ ├── item_gesture.xml │ │ ├── item_input_layout.xml │ │ ├── item_main_option.xml │ │ ├── item_menu.xml │ │ ├── item_node_info.xml │ │ ├── item_node_tree.xml │ │ ├── item_task_assistant.xml │ │ ├── item_task_list.xml │ │ ├── item_task_showcase.xml │ │ ├── item_task_snapshot.xml │ │ ├── item_vararg_text.xml │ │ ├── item_vibration_pattern.xml │ │ ├── layout_flow_operation_demo.xml │ │ ├── layout_menu_list.xml │ │ ├── layout_progress.xml │ │ ├── layout_shopping_cart.xml │ │ ├── overlay_bubble_collapsed.xml │ │ ├── overlay_bubble_expanded.xml │ │ ├── overlay_component.xml │ │ ├── overlay_gesture_showcase.xml │ │ ├── overlay_inspector.xml │ │ ├── overlay_node_info.xml │ │ ├── overlay_node_tree.xml │ │ ├── overlay_task_assistant.xml │ │ ├── overlay_toast.xml │ │ ├── overlay_trash_bin.xml │ │ └── overlay_window_bounds_detector.xml │ │ ├── menu │ │ ├── applet_batch_operation.xml │ │ ├── applet_operation.xml │ │ ├── feedbacks.xml │ │ ├── main.xml │ │ ├── night_modes.xml │ │ ├── operating_modes.xml │ │ ├── package_filter.xml │ │ └── task_bottom_bar.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── values-night │ │ ├── styles.xml │ │ └── themes.xml │ │ ├── values │ │ ├── arrays.xml │ │ ├── attrs.xml │ │ ├── check_cases.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── ic_launcher_background.xml │ │ ├── options.xml │ │ ├── strings.xml │ │ ├── styles.xml │ │ ├── themes.xml │ │ ├── themes_custom.xml │ │ └── values.xml │ │ └── xml │ │ ├── automator_service.xml │ │ └── file_paths.xml │ └── test │ └── kotlin │ └── top │ └── xjunz │ └── tasker │ └── task │ └── applet │ ├── util │ └── IntValueUtilTest.kt │ └── value │ └── BitwiseValueComposerTest.kt ├── build.gradle ├── coroutine-ui-automator ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── top │ │ └── xjunz │ │ └── tasker │ │ └── uiautomator │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ └── java │ │ └── top │ │ └── xjunz │ │ └── tasker │ │ └── uiautomator │ │ ├── A11yGestureController.kt │ │ ├── A11yInteractionController.kt │ │ ├── CoroutineGestureController.kt │ │ ├── CoroutineInteractionController.kt │ │ ├── CoroutineUiAutomatorBridge.kt │ │ ├── CoroutineUiDevice.kt │ │ ├── CoroutineUiObject.kt │ │ ├── CoroutineUiScrollable.kt │ │ ├── GestureGenerator.kt │ │ ├── Gestures.java │ │ ├── PrivilegedGestureController.kt │ │ └── PrivilegedInteractionController.kt │ └── test │ └── java │ └── top │ └── xjunz │ └── tasker │ └── uiautomator │ └── ExampleUnitTest.kt ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── hidden-apis ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── top │ │ └── xjunz │ │ └── hidden_api │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── aidl │ │ └── android │ │ │ ├── accessibilityservice │ │ │ ├── IAccessibilityServiceClient.aidl │ │ │ └── IAccessibilityServiceConnection.aidl │ │ │ └── app │ │ │ └── IUiAutomationConnection.aidl │ └── java │ │ └── android │ │ ├── accessibilityservice │ │ └── AccessibilityServiceHidden.java │ │ ├── app │ │ ├── ActivityManagerNative.java │ │ ├── ActivityThread.java │ │ ├── ContextImpl.java │ │ ├── IActivityManager.java │ │ ├── UiAutomationConnection.java │ │ └── UiAutomationHidden.java │ │ ├── content │ │ ├── ContextHidden.java │ │ ├── IClipboard.java │ │ └── pm │ │ │ └── IPackageManager.java │ │ ├── hardware │ │ └── input │ │ │ └── IInputManager.java │ │ ├── os │ │ ├── BatteryManagerHidden.java │ │ ├── IBinderHidden.java │ │ └── UserHandleHidden.java │ │ └── view │ │ └── WindowManagerImpl.java │ └── test │ └── java │ └── top │ └── xjunz │ └── hidden_api │ └── ExampleUnitTest.java ├── settings.gradle ├── shared-library ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── top │ │ └── xjunz │ │ └── shared │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ └── java │ │ └── top │ │ └── xjunz │ │ └── shared │ │ ├── ktx │ │ ├── Any.kt │ │ ├── Collections.kt │ │ ├── Digest.kt │ │ └── Parcel.kt │ │ ├── trace │ │ └── Logger.kt │ │ └── utils │ │ ├── Exceptions.kt │ │ └── OsUtil.kt │ └── test │ └── java │ └── top │ └── xjunz │ └── shared │ └── ExampleUnitTest.kt ├── ssl ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── top │ │ └── xjunz │ │ └── tasker │ │ └── ssl │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── cpp │ │ ├── CMakeLists.txt │ │ ├── aes.c │ │ ├── aes.h │ │ ├── android_log.h │ │ ├── apkprotect.cpp │ │ ├── base64.c │ │ ├── base64.h │ │ ├── md5.cpp │ │ └── md5.h │ └── java │ │ └── x │ │ └── f.java │ └── test │ └── java │ └── top │ └── xjunz │ └── tasker │ └── ssl │ └── ExampleUnitTest.kt ├── tasker-engine ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── top │ │ └── xjunz │ │ └── tasker │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── aidl │ │ └── top │ │ │ └── xjunz │ │ │ └── tasker │ │ │ └── engine │ │ │ ├── dto │ │ │ └── XTaskDTO.aidl │ │ │ └── task │ │ │ └── TaskSnapshot.aidl │ └── java │ │ └── top │ │ └── xjunz │ │ └── tasker │ │ └── engine │ │ ├── applet │ │ ├── action │ │ │ ├── Action.kt │ │ │ ├── ActionCreator.kt │ │ │ ├── ArgumentAction.kt │ │ │ ├── Break.kt │ │ │ ├── Continue.kt │ │ │ ├── Processor.kt │ │ │ ├── Repeat.kt │ │ │ ├── SingleArgAction.kt │ │ │ ├── Suspension.kt │ │ │ └── VarRefAction.kt │ │ ├── base │ │ │ ├── Anyway.kt │ │ │ ├── Applet.kt │ │ │ ├── AppletResult.kt │ │ │ ├── ContainerFlow.kt │ │ │ ├── ControlFlow.kt │ │ │ ├── Do.kt │ │ │ ├── DslFlow.kt │ │ │ ├── Else.kt │ │ │ ├── ElseIf.kt │ │ │ ├── Flow.kt │ │ │ ├── If.kt │ │ │ ├── Loop.kt │ │ │ ├── RootFlow.kt │ │ │ ├── ScopeFlow.kt │ │ │ ├── StaticError.kt │ │ │ ├── Then.kt │ │ │ ├── WaitFor.kt │ │ │ ├── WaitUntil.kt │ │ │ └── When.kt │ │ ├── criterion │ │ │ ├── Criterion.kt │ │ │ ├── CriterionCreator.kt │ │ │ └── DslCriterion.kt │ │ ├── factory │ │ │ └── AppletFactory.kt │ │ └── util │ │ │ ├── Applets.kt │ │ │ └── FlowDsl.kt │ │ ├── dto │ │ ├── AppletArgumentSerializer.kt │ │ ├── AppletChecksum.kt │ │ ├── AppletDTO.kt │ │ └── XTaskDTO.kt │ │ ├── runtime │ │ ├── AppletIndexer.kt │ │ ├── ComponentInfo.kt │ │ ├── Event.kt │ │ ├── Referent.kt │ │ ├── TaskRuntime.kt │ │ └── ValueRegistry.kt │ │ └── task │ │ ├── EventDispatcher.kt │ │ ├── TaskManager.kt │ │ ├── TaskScheduler.kt │ │ ├── TaskSnapshot.kt │ │ └── XTask.kt │ └── test │ └── java │ └── top │ └── xjunz │ └── tasker │ ├── ExampleUnitTest.kt │ └── engine │ ├── applet │ └── util │ │ └── AppletsKtTest.kt │ ├── dto │ └── AppletDTOTest.kt │ └── runtime │ └── AppletIndexerTest.kt └── ui-automator ├── .gitignore ├── README.md ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src ├── androidTest └── java │ └── androidx │ └── test │ └── uiautomator │ └── ExampleInstrumentedTest.java ├── main ├── AndroidManifest.xml └── java │ └── androidx │ └── test │ └── uiautomator │ ├── AccessibilityNodeInfoDumper.java │ ├── AccessibilityNodeInfoHelper.java │ ├── By.java │ ├── ByMatcher.java │ ├── BySelector.java │ ├── Condition.java │ ├── Configurator.java │ ├── Direction.java │ ├── EventCondition.java │ ├── GestureController.java │ ├── Gestures.java │ ├── IAutomationSupport.java │ ├── InstrumentationAutomationSupport.java │ ├── InteractionController.java │ ├── PointerGesture.java │ ├── QueryController.java │ ├── SearchCondition.java │ ├── Searchable.java │ ├── StaleObjectException.java │ ├── Tracer.java │ ├── UiCollection.java │ ├── UiDevice.java │ ├── UiObject.java │ ├── UiObject2.java │ ├── UiObject2Condition.java │ ├── UiObjectNotFoundException.java │ ├── UiScrollable.java │ ├── UiSelector.java │ ├── UiWatcher.java │ ├── Until.java │ ├── WaitMixin.java │ └── bridge │ └── UiAutomatorBridge.java └── test └── java └── androidx └── test └── uiautomator └── ExampleUnitTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | sign.properties 16 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | 自动任务 -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/copyright/xjunz.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/kotlinc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 17 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /src/main/java/top/xjunz/tasker/Constants.kt -------------------------------------------------------------------------------- /app/dprotect-rules.pro: -------------------------------------------------------------------------------- 1 | #dProtect 2 | #noinspection ShrinkerInvalidFlags 3 | 4 | -obfuscate-control-flow class top.xjunz.tasker.task.event.A11yEventDispatcher { *; } 5 | 6 | # Strings Obfuscation 7 | -obfuscate-strings class top.xjunz.tasker.App { 8 | *; 9 | } 10 | -obfuscate-strings class top.xjunz.tasker.service.A11yAutomatorService { 11 | *; 12 | } 13 | -obfuscate-strings class top.xjunz.tasker.premium.PremiumMixin { 14 | *; 15 | } 16 | -obfuscate-strings class top.xjunz.tasker.api.Client { 17 | *; 18 | } 19 | -------------------------------------------------------------------------------- /app/screenshots/Screenshot_light_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjunz/AutoTask/50efc671a84425bf1f9f38d42b3238b3a055467c/app/screenshots/Screenshot_light_1.png -------------------------------------------------------------------------------- /app/screenshots/Screenshot_light_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjunz/AutoTask/50efc671a84425bf1f9f38d42b3238b3a055467c/app/screenshots/Screenshot_light_2.png -------------------------------------------------------------------------------- /app/screenshots/Screenshot_night_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjunz/AutoTask/50efc671a84425bf1f9f38d42b3238b3a055467c/app/screenshots/Screenshot_night_1.png -------------------------------------------------------------------------------- /app/screenshots/Screenshot_night_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjunz/AutoTask/50efc671a84425bf1f9f38d42b3238b3a055467c/app/screenshots/Screenshot_night_2.png -------------------------------------------------------------------------------- /app/src/androidTest/kotlin/top/xjunz/tasker/bridge/ClipboardManagerBridgeTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.bridge 6 | 7 | import org.junit.Test 8 | 9 | /** 10 | * @author xjunz 2022/11/16 11 | */ 12 | internal class ClipboardManagerBridgeTest { 13 | 14 | @Test 15 | fun copyToClipboard() { 16 | ClipboardManagerBridge.copyToClipboard("hello") 17 | } 18 | } -------------------------------------------------------------------------------- /app/src/androidTest/kotlin/top/xjunz/tasker/bridge/PackageManagerBridgeTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.bridge 6 | 7 | import org.junit.Test 8 | import top.xjunz.tasker.BuildConfig 9 | 10 | 11 | /** 12 | * @author xjunz 2023/01/06 13 | */ 14 | internal class PackageManagerBridgeTest { 15 | 16 | @Test 17 | fun loadPackageInfo() { 18 | val info = PackageManagerBridge.loadPackageInfo(BuildConfig.APPLICATION_ID) 19 | assert(info!!.packageName == BuildConfig.APPLICATION_ID) 20 | } 21 | 22 | @Test 23 | fun loadAllPackages() { 24 | } 25 | } -------------------------------------------------------------------------------- /app/src/androidTest/kotlin/top/xjunz/tasker/task/event/A11yEventDispatcherTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.task.event 6 | 7 | import android.os.Handler 8 | import android.os.Looper 9 | import kotlinx.coroutines.CoroutineScope 10 | import kotlinx.coroutines.android.asCoroutineDispatcher 11 | import org.junit.Test 12 | import top.xjunz.tasker.UiAutomationRegistry 13 | import kotlin.coroutines.CoroutineContext 14 | 15 | /** 16 | * @author xjunz 2022/11/01 17 | */ 18 | internal class A11yEventDispatcherTest : CoroutineScope { 19 | 20 | 21 | @Test 22 | fun processAccessibilityEvent() { 23 | UiAutomationRegistry.getUiAutomation().setOnAccessibilityEventListener { 24 | println(it) 25 | } 26 | } 27 | 28 | override val coroutineContext: CoroutineContext by lazy { 29 | Handler(Looper.getMainLooper()).asCoroutineDispatcher() 30 | } 31 | } -------------------------------------------------------------------------------- /app/src/main/aidl/top/xjunz/tasker/task/runtime/IOnTaskPauseStateListener.aidl: -------------------------------------------------------------------------------- 1 | // IOnTaskPauseStateListener.aidl 2 | package top.xjunz.tasker.task.runtime; 3 | 4 | // Declare any non-default types here with import statements 5 | 6 | interface IOnTaskPauseStateListener { 7 | 8 | void onTaskPauseStateChanged(long checksum); 9 | 10 | } -------------------------------------------------------------------------------- /app/src/main/aidl/top/xjunz/tasker/task/runtime/IRemoteTaskManager.aidl: -------------------------------------------------------------------------------- 1 | // IRemoteTaskManager.aidl 2 | package top.xjunz.tasker.task.runtime; 3 | 4 | import top.xjunz.tasker.task.runtime.IOnTaskPauseStateListener; 5 | import top.xjunz.tasker.engine.dto.XTaskDTO; 6 | import top.xjunz.tasker.engine.task.TaskSnapshot; 7 | 8 | interface IRemoteTaskManager { 9 | 10 | void initialize(in List carriers); 11 | 12 | boolean isInitialized(); 13 | 14 | void updateTask(long previous, in XTaskDTO updated); 15 | 16 | void removeTask(long identifier); 17 | 18 | void enableResidentTask(in XTaskDTO carrier); 19 | 20 | void addOneshotTaskIfAbsent(in XTaskDTO carrier); 21 | 22 | int getSnapshotCount(long identifier); 23 | 24 | void clearSnapshots(long identifier); 25 | 26 | void clearLog(long checksum, String snapshotId); 27 | 28 | TaskSnapshot[] getAllSnapshots(long identifier); 29 | 30 | void setOnTaskPausedListener(in IOnTaskPauseStateListener listener); 31 | 32 | long[] getTaskPauseInfo(long identifier); 33 | } -------------------------------------------------------------------------------- /app/src/main/aidl/top/xjunz/tasker/task/runtime/ITaskCompletionCallback.aidl: -------------------------------------------------------------------------------- 1 | // ITaskCompletionCallback.aidl 2 | package top.xjunz.tasker.task.runtime; 3 | 4 | // Declare any non-default types here with import statements 5 | 6 | interface ITaskCompletionCallback { 7 | 8 | void onTaskCompleted(boolean isSuccessful); 9 | 10 | } -------------------------------------------------------------------------------- /app/src/main/assets/examples.xtsks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjunz/AutoTask/50efc671a84425bf1f9f38d42b3238b3a055467c/app/src/main/assets/examples.xtsks -------------------------------------------------------------------------------- /app/src/main/assets/presets.xtsks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjunz/AutoTask/50efc671a84425bf1f9f38d42b3238b3a055467c/app/src/main/assets/presets.xtsks -------------------------------------------------------------------------------- /app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjunz/AutoTask/50efc671a84425bf1f9f38d42b3238b3a055467c/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/annotation/Anywhere.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.annotation 6 | 7 | import java.lang.annotation.Inherited 8 | 9 | /** 10 | * The annotation indicating that its target may be used in both local and privileged processes. 11 | * You should deal with these two situations carefully. 12 | * 13 | * @see Local 14 | * @see Privileged 15 | * 16 | * @author xjunz 2022/04/30 17 | */ 18 | @Inherited 19 | @Retention(AnnotationRetention.SOURCE) 20 | annotation class Anywhere -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/annotation/FieldOrder.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.annotation 6 | 7 | /** 8 | * @author xjunz 2022/08/09 9 | */ 10 | @Retention(AnnotationRetention.RUNTIME) 11 | @Target(AnnotationTarget.FIELD) 12 | annotation class FieldOrder(val ordinal: Int) -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/annotation/Local.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.annotation 6 | 7 | /** 8 | * The annotation indicating that its targets are only used in the local process. 9 | * 10 | * @author xjunz 2022/05/25 11 | */ 12 | @Retention(AnnotationRetention.SOURCE) 13 | annotation class Local 14 | -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/annotation/Privileged.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.annotation 6 | 7 | /** 8 | * The annotation indicating that its target is only used in a privileged process. Do not use any 9 | * resources only available in local process such as application context. 10 | * 11 | * @author xjunz 2022/04/29 12 | */ 13 | @Retention(AnnotationRetention.SOURCE) 14 | annotation class Privileged 15 | -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/api/DTOExt.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.api 6 | 7 | import java.math.BigDecimal 8 | import java.math.RoundingMode 9 | 10 | /** 11 | * @author xjunz 2022/06/15 12 | */ 13 | private fun toLiteralPrice(amount: Int): String { 14 | val ret = BigDecimal(amount).divide(BigDecimal(100), 2, RoundingMode.UNNECESSARY) 15 | return ret.toString() 16 | } 17 | 18 | val OrderDTO.discountedPrice: Int get() = originPrice - randomDiscount 19 | 20 | val OrderDTO.discountedPriceLiteral: String get() = toLiteralPrice(discountedPrice) 21 | 22 | val OrderDTO.discountLiteral: String get() = toLiteralPrice(randomDiscount) 23 | 24 | val PriceDTO.currentPriceLiteral: String get() = toLiteralPrice(currentValue) 25 | 26 | val PriceDTO.originalPriceLiteral: String? 27 | get() = if (originalValue == null) null else toLiteralPrice( 28 | originalValue 29 | ) -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/api/SecurityUtil.kt: -------------------------------------------------------------------------------- 1 | package top.xjunz.tasker.api 2 | 3 | import io.ktor.client.request.* 4 | import x.f 5 | 6 | fun String.encrypt(): String { 7 | return f.alpha(toByteArray()) 8 | } 9 | 10 | fun String.decrypt(): String { 11 | return String(f.delta(this)) 12 | } 13 | 14 | fun HttpRequestBuilder.encryptHeaders(vararg args: String) { 15 | args.forEachIndexed { index, s -> 16 | header("$index", s.encrypt()) 17 | } 18 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/bridge/A11yUiAutomatorBridge.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.bridge 6 | 7 | import android.app.UiAutomation 8 | import top.xjunz.tasker.service.a11yAutomatorService 9 | import top.xjunz.tasker.uiautomator.A11yGestureController 10 | import top.xjunz.tasker.uiautomator.A11yInteractionController 11 | import top.xjunz.tasker.uiautomator.CoroutineGestureController 12 | import top.xjunz.tasker.uiautomator.CoroutineInteractionController 13 | 14 | 15 | /** 16 | * @author xjunz 2022/07/23 17 | */ 18 | class A11yUiAutomatorBridge(uiAutomation: UiAutomation) : ContextUiAutomatorBridge(uiAutomation) { 19 | 20 | override val interactionController: CoroutineInteractionController by lazy { 21 | A11yInteractionController(a11yAutomatorService, this) 22 | } 23 | 24 | override val gestureController: CoroutineGestureController by lazy { 25 | A11yGestureController(a11yAutomatorService, this) 26 | } 27 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/bridge/BatteryManagerBridge.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.bridge 6 | 7 | import android.os.BatteryManager 8 | 9 | /** 10 | * @author xjunz 2022/11/10 11 | */ 12 | object BatteryManagerBridge { 13 | 14 | private val batteryManager: BatteryManager by lazy { 15 | ContextBridge.getContext().getSystemService(BatteryManager::class.java) 16 | } 17 | 18 | val isCharging: Boolean get() = batteryManager.isCharging 19 | 20 | val capacity: Int 21 | get() { 22 | return batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY) 23 | } 24 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/bridge/ClipboardManagerBridge.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.bridge 6 | 7 | import android.content.ClipData 8 | import android.content.ClipboardManager 9 | 10 | /** 11 | * @author xjunz 2022/11/16 12 | */ 13 | object ClipboardManagerBridge { 14 | 15 | fun copyToClipboard(text: CharSequence) { 16 | ContextBridge.getContext().getSystemService(ClipboardManager::class.java) 17 | .setPrimaryClip(ClipData.newPlainText(null, text)) 18 | } 19 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/bridge/DisplayManagerBridge.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.bridge 6 | 7 | import android.graphics.Point 8 | import android.util.DisplayMetrics 9 | import android.view.Display 10 | import android.view.WindowManager 11 | 12 | /** 13 | * @author xjunz 2022/10/25 14 | */ 15 | object DisplayManagerBridge { 16 | 17 | private val windowManager by lazy { 18 | ContextBridge.getContext().getSystemService(WindowManager::class.java) 19 | } 20 | 21 | val defaultDisplay: Display 22 | get() { 23 | @Suppress("DEPRECATION") 24 | return windowManager.defaultDisplay 25 | } 26 | 27 | private val point = Point() 28 | 29 | val size: Point 30 | get() { 31 | @Suppress("DEPRECATION") 32 | defaultDisplay.getRealSize(point) 33 | return point 34 | } 35 | 36 | val density: Float by lazy { 37 | val metrics = DisplayMetrics() 38 | @Suppress("DEPRECATION") 39 | defaultDisplay.getRealMetrics(metrics) 40 | metrics.density 41 | } 42 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/bridge/PowerManagerBridge.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.bridge 6 | 7 | import android.annotation.SuppressLint 8 | import android.os.PowerManager 9 | import android.os.PowerManager.WakeLock 10 | 11 | /** 12 | * @author xjunz 2023/09/11 13 | */ 14 | object PowerManagerBridge { 15 | 16 | private val powerManager by lazy { 17 | ContextBridge.getContext().getSystemService(PowerManager::class.java) 18 | } 19 | 20 | @SuppressLint("WakelockTimeout") 21 | @Suppress("DEPRECATION") 22 | fun wakeUpScreen() { 23 | val wakeLock = powerManager.newWakeLock( 24 | PowerManager.ACQUIRE_CAUSES_WAKEUP or PowerManager.SCREEN_DIM_WAKE_LOCK, 25 | "xjunz:AutoTask:WakeUp" 26 | ) 27 | wakeLock.acquire() 28 | wakeLock.release() 29 | } 30 | 31 | fun obtainWakeLock(): WakeLock { 32 | return powerManager.newWakeLock( 33 | PowerManager.PARTIAL_WAKE_LOCK or PowerManager.ON_AFTER_RELEASE, 34 | "xjunz:AutoTask:Service" 35 | ) 36 | } 37 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/bridge/PrivilegedUiAutomatorBridge.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.bridge 6 | 7 | import android.app.UiAutomation 8 | import top.xjunz.tasker.uiautomator.CoroutineGestureController 9 | import top.xjunz.tasker.uiautomator.CoroutineInteractionController 10 | import top.xjunz.tasker.uiautomator.PrivilegedGestureController 11 | import top.xjunz.tasker.uiautomator.PrivilegedInteractionController 12 | 13 | /** 14 | * @author xjunz 2022/09/30 15 | */ 16 | class PrivilegedUiAutomatorBridge(uiAutomation: UiAutomation) : 17 | ContextUiAutomatorBridge(uiAutomation) { 18 | 19 | override val interactionController: CoroutineInteractionController by lazy { 20 | PrivilegedInteractionController(this) 21 | } 22 | 23 | override val gestureController: CoroutineGestureController by lazy { 24 | PrivilegedGestureController(this) 25 | } 26 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/bridge/ThemedWindowContext.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | package top.xjunz.tasker.bridge 5 | 6 | import android.content.Context 7 | import android.os.Binder 8 | import android.view.WindowManagerImpl 9 | import androidx.appcompat.view.ContextThemeWrapper 10 | import top.xjunz.tasker.R 11 | import top.xjunz.tasker.annotation.Privileged 12 | 13 | @Privileged 14 | class ThemedWindowContext(context: Context, private val binder: Binder) : 15 | ContextThemeWrapper(context, R.style.AppTheme) { 16 | 17 | override fun getSystemService(name: String): Any { 18 | if (Context.WINDOW_SERVICE != name) { 19 | return super.getSystemService(name) 20 | } 21 | val impl = super.getSystemService(name) as WindowManagerImpl 22 | impl.setDefaultToken(binder) 23 | return impl 24 | } 25 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/bridge/VibratorBridge.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.bridge 6 | 7 | import android.os.Build 8 | import android.os.VibrationEffect 9 | import android.os.Vibrator 10 | import androidx.annotation.RequiresApi 11 | import top.xjunz.tasker.task.applet.action.Vibrate 12 | 13 | /** 14 | * @author xjunz 2023/10/28 15 | */ 16 | object VibratorBridge { 17 | 18 | private val vibrator by lazy { 19 | ContextBridge.getContext().getSystemService(Vibrator::class.java) 20 | } 21 | 22 | @RequiresApi(Build.VERSION_CODES.O) 23 | fun performVibrate(waveForm: Vibrate.VibrationWaveForm) { 24 | vibrator.vibrate(VibrationEffect.createWaveform(waveForm.durations, waveForm.strengths, -1)) 25 | } 26 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/ktx/BindingAdapters.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.ktx 6 | 7 | import android.text.method.LinkMovementMethod 8 | import android.view.View 9 | import android.widget.TextView 10 | import androidx.appcompat.widget.TooltipCompat 11 | import androidx.core.text.parseAsHtml 12 | import androidx.databinding.BindingAdapter 13 | 14 | /** 15 | * @author xjunz 2022/04/21 16 | */ 17 | @BindingAdapter("html") 18 | fun TextView.setHtml(html: String) { 19 | text = html.parseAsHtml() 20 | } 21 | 22 | @BindingAdapter("android:contentDescription") 23 | fun View.setContentDescriptionAndTooltip(text: CharSequence) { 24 | contentDescription = text 25 | TooltipCompat.setTooltipText(this, contentDescription) 26 | } 27 | 28 | @BindingAdapter("linkable") 29 | fun TextView.setLinkable(linkable: Boolean) { 30 | if (linkable) 31 | movementMethod = LinkMovementMethod.getInstance() 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/ktx/Bitmap.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.ktx 6 | 7 | import android.graphics.Bitmap 8 | import android.graphics.Rect 9 | 10 | /** 11 | * @author xjunz 2022/10/15 12 | */ 13 | 14 | fun Bitmap.clip(bounds: Rect): Bitmap { 15 | return Bitmap.createBitmap(this, bounds.left, bounds.top, bounds.width(), bounds.height()) 16 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/ktx/BottomSheet.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.ktx 6 | 7 | import android.annotation.SuppressLint 8 | import android.view.View 9 | import androidx.coordinatorlayout.widget.CoordinatorLayout 10 | import com.google.android.material.bottomsheet.BottomSheetBehavior 11 | 12 | /** 13 | * @author xjunz 2022/10/03 14 | */ 15 | fun View.requireBottomSheetBehavior(): BottomSheetBehavior<*> { 16 | return (layoutParams as CoordinatorLayout.LayoutParams).behavior as BottomSheetBehavior<*> 17 | } 18 | 19 | @SuppressLint("RestrictedApi", "VisibleForTests") 20 | fun View.disableBottomSheetShapeAnimation(): BottomSheetBehavior<*> { 21 | val behavior = requireBottomSheetBehavior() 22 | behavior.disableShapeAnimations() 23 | return behavior 24 | } 25 | 26 | fun View.getBottomSheetState(): Int { 27 | return requireBottomSheetBehavior().state 28 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/ktx/Color.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.ktx 6 | 7 | import androidx.annotation.FloatRange 8 | import androidx.core.graphics.ColorUtils 9 | 10 | /** 11 | * @author xjunz 2022/12/11 12 | */ 13 | fun Int.alphaModified(@FloatRange(from = 0.0, to = 1.0) alpha: Float): Int { 14 | return ColorUtils.setAlphaComponent(this, (alpha * 0xFF).toInt()) 15 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/ktx/Defer.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.ktx 6 | 7 | import kotlinx.coroutines.Deferred 8 | 9 | /** 10 | * @author xjunz 2022/12/22 11 | */ 12 | inline fun Deferred<*>.invokeOnError(crossinline block: (Throwable) -> Unit) { 13 | invokeOnCompletion { 14 | if (it != null) block(it) 15 | } 16 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/ktx/MaterialShapeDrawable.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.ktx 6 | 7 | import android.content.Context 8 | import androidx.annotation.AttrRes 9 | import com.google.android.material.shape.MaterialShapeDrawable 10 | import com.google.android.material.shape.ShapeAppearanceModel 11 | 12 | /** 13 | * @author xjunz 2022/07/28 14 | */ 15 | 16 | fun Context.createMaterialShapeDrawable( 17 | @AttrRes fillColorRes: Int = com.google.android.material.R.attr.colorSurface, 18 | elevation: Float = 3.dpFloat, cornerSize: Float = 16.dpFloat 19 | ): MaterialShapeDrawable { 20 | return MaterialShapeDrawable.createWithElevationOverlay(this, elevation).apply { 21 | shapeAppearanceModel = ShapeAppearanceModel.builder().setAllCornerSizes(cornerSize).build() 22 | fillColor = fillColorRes.attrColorStateList 23 | } 24 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/ktx/String.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.ktx 6 | 7 | import org.intellij.lang.annotations.Language 8 | 9 | /** 10 | * @author xjunz 2022/11/16 11 | */ 12 | fun String.firstGroupValue(@Language("RegExp") pattern: String): String? { 13 | return Regex(pattern).find(this)?.groupValues?.get(1) 14 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/premium/FieldOrdinal.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.premium 6 | 7 | /** 8 | * @author xjunz 2022/06/24 9 | */ 10 | @Retention(AnnotationRetention.RUNTIME) 11 | annotation class FieldOrdinal(val ordinal: Int) -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/premium/PaymentRequiredException.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.premium 6 | 7 | /** 8 | * @author xjunz 2023/03/01 9 | */ 10 | class PaymentRequiredException : Exception() -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/premium/PremiumContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.premium; 6 | 7 | /** 8 | * @author xjunz 2023/03/01 9 | */ 10 | public class PremiumContext { 11 | 12 | public static final String placeholder = "placeholder"; 13 | 14 | @FieldOrdinal(ordinal = 1) 15 | public String orderId = placeholder; 16 | 17 | @FieldOrdinal(ordinal = 2) 18 | public String createTimestamp = placeholder; 19 | 20 | @FieldOrdinal(ordinal = 20) 21 | public String empty = placeholder; 22 | 23 | @FieldOrdinal(ordinal = 30) 24 | public String delimiter = placeholder; 25 | 26 | @FieldOrdinal(ordinal = 40) 27 | public String screenShotAction; 28 | 29 | @FieldOrdinal(ordinal = 50) 30 | public String checksum; 31 | 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/task/applet/action/PauseFor.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.task.applet.action 6 | 7 | import top.xjunz.tasker.engine.applet.action.SingleArgAction 8 | import top.xjunz.tasker.engine.applet.base.AppletResult 9 | import top.xjunz.tasker.engine.runtime.TaskRuntime 10 | import top.xjunz.tasker.task.applet.value.LongDuration 11 | 12 | /** 13 | * @author xjunz 2023/08/17 14 | */ 15 | class PauseFor : SingleArgAction() { 16 | 17 | override suspend fun doAction(arg: Long?, runtime: TaskRuntime): AppletResult { 18 | val duration = checkNotNull(arg) 19 | runtime.attachingTask.pause(LongDuration.parse(duration).toMilliseconds()) 20 | return AppletResult.EMPTY_SUCCESS 21 | } 22 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/task/applet/anno/AppletOrdinal.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.task.applet.anno 6 | 7 | /** 8 | * |0000 0000|│|0000 0000| 9 | * | :----: |:----: | :----: | 10 | * |id|│|index| 11 | * 12 | * The first 8 bits of [ordinal] is the category id and the last 8 bits of [ordinal] is 13 | * the index in the category. 14 | * 15 | * @author xjunz 2022/09/22 16 | */ 17 | @Retention(AnnotationRetention.RUNTIME) 18 | @Target(AnnotationTarget.FIELD) 19 | annotation class AppletOrdinal(val ordinal: Int) -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/task/applet/flow/ClickUiObjectIfExists.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.task.applet.flow 6 | 7 | import top.xjunz.tasker.engine.runtime.TaskRuntime 8 | import top.xjunz.tasker.uiautomator.CoroutineUiObject 9 | 10 | /** 11 | * @author xjunz 2023/09/13 12 | */ 13 | class ClickUiObjectIfExists : PerformActionIfUiObjectExistsInCurrentWindow() { 14 | 15 | override val isCriterionSpecified: Boolean = false 16 | 17 | override suspend fun performActionIfFound(runtime: TaskRuntime, target: CoroutineUiObject) { 18 | target.click() 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/task/applet/flow/ClickUiObjectWithText.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.task.applet.flow 6 | 7 | import android.view.accessibility.AccessibilityNodeInfo 8 | import top.xjunz.tasker.engine.runtime.TaskRuntime 9 | import top.xjunz.tasker.uiautomator.CoroutineUiObject 10 | 11 | /** 12 | * @author xjunz 2023/09/15 13 | */ 14 | class ClickUiObjectWithText : PerformActionIfUiObjectExistsInCurrentWindow() { 15 | 16 | override val isCriterionSpecified: Boolean = true 17 | 18 | private var specifiedText: String? = null 19 | 20 | override fun onPrepareApply(runtime: TaskRuntime) { 21 | super.onPrepareApply(runtime) 22 | specifiedText = getArgument(0, runtime)?.toString() 23 | } 24 | 25 | override suspend fun performActionIfFound(runtime: TaskRuntime, target: CoroutineUiObject) { 26 | target.click() 27 | } 28 | 29 | override suspend fun matchUiObject(node: AccessibilityNodeInfo, runtime: TaskRuntime): Boolean { 30 | return node.text?.toString() == specifiedText 31 | } 32 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/task/applet/flow/ElseStopship.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.task.applet.flow 6 | 7 | import top.xjunz.tasker.engine.applet.base.Else 8 | import top.xjunz.tasker.engine.runtime.TaskRuntime 9 | 10 | /** 11 | * @author xjunz 2023/09/13 12 | */ 13 | class ElseStopship : Else() { 14 | 15 | override val maxSize: Int = 0 16 | 17 | override val minSize: Int = 0 18 | 19 | override fun onPostApply(runtime: TaskRuntime) { 20 | super.onPostApply(runtime) 21 | runtime.shouldStop = true 22 | } 23 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/task/applet/flow/PhantomFlow.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.task.applet.flow 6 | 7 | import android.annotation.SuppressLint 8 | import top.xjunz.shared.utils.unsupportedOperation 9 | import top.xjunz.tasker.engine.applet.base.Flow 10 | import top.xjunz.tasker.engine.runtime.TaskRuntime 11 | 12 | /** 13 | * A flow which is intended to be merged into its parent flow. This flow only exists in edition time. 14 | * 15 | * @author xjunz 2022/11/10 16 | */ 17 | class PhantomFlow : Flow() { 18 | 19 | override fun onPrepareApply(runtime: TaskRuntime) { 20 | unsupportedOperation("PhantomFlow is not expected to be present in runtime!") 21 | } 22 | 23 | @SuppressLint("MissingSuperCall") 24 | override fun staticCheckMyself(): Int { 25 | unsupportedOperation("PhantomFlow should be merged!") 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/task/applet/flow/TimeFlow.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.task.applet.flow 6 | 7 | import top.xjunz.tasker.engine.applet.base.ScopeFlow 8 | import top.xjunz.tasker.engine.runtime.Event 9 | import top.xjunz.tasker.engine.runtime.TaskRuntime 10 | import top.xjunz.tasker.task.event.PollEventDispatcher 11 | import java.util.Calendar 12 | 13 | /** 14 | * @author xjunz 2022/10/01 15 | */ 16 | class TimeFlow : ScopeFlow() { 17 | 18 | override fun initializeTarget(runtime: TaskRuntime): Calendar { 19 | val calendar = Calendar.getInstance() 20 | val current = runtime.events?.find { it.type == Event.EVENT_ON_TICK } 21 | ?.getExtra(PollEventDispatcher.EXTRA_TICK_TIME_MILLS) 22 | ?: System.currentTimeMillis() 23 | // Prune milliseconds 24 | calendar.timeInMillis = current - current % 1000 25 | return calendar 26 | } 27 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/task/applet/flow/UiObjectMatches.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.task.applet.flow 6 | 7 | import android.view.accessibility.AccessibilityNodeInfo 8 | import top.xjunz.tasker.engine.applet.base.AppletResult 9 | import top.xjunz.tasker.engine.applet.base.ScopeFlow 10 | import top.xjunz.tasker.engine.runtime.TaskRuntime 11 | import top.xjunz.tasker.ktx.ensureRefresh 12 | 13 | /** 14 | * @author xjunz 2023/03/13 15 | */ 16 | class UiObjectMatches : ScopeFlow() { 17 | 18 | override fun initializeTarget(runtime: TaskRuntime): UiObjectTarget { 19 | return UiObjectTarget() 20 | } 21 | 22 | override suspend fun applyFlow(runtime: TaskRuntime): AppletResult { 23 | val referentNode = runtime.getReferenceArgument(this, 0) as AccessibilityNodeInfo 24 | referentNode.ensureRefresh() 25 | runtime.target.source = referentNode 26 | return super.applyFlow(runtime) 27 | } 28 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/task/applet/flow/UiObjectTarget.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.task.applet.flow 6 | 7 | import android.view.accessibility.AccessibilityNodeInfo 8 | import top.xjunz.tasker.bridge.DisplayManagerBridge 9 | 10 | /** 11 | * @author xjunz 2023/03/13 12 | */ 13 | class UiObjectTarget { 14 | 15 | lateinit var source: AccessibilityNodeInfo 16 | 17 | val density: Float by lazy { 18 | DisplayManagerBridge.density 19 | } 20 | 21 | private val realSize by lazy { 22 | DisplayManagerBridge.size 23 | } 24 | 25 | val screenWidthPixels get() = realSize.x 26 | 27 | val screenHeightPixels get() = realSize.y 28 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/task/applet/flow/ref/NotificationReferent.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.task.applet.flow.ref 6 | 7 | import top.xjunz.tasker.engine.runtime.Referent 8 | import top.xjunz.tasker.engine.runtime.TaskRuntime 9 | import top.xjunz.tasker.task.applet.option.registry.EventCriterionRegistry 10 | 11 | /** 12 | * @see [EventCriterionRegistry.notificationReceived] 13 | * 14 | * @author xjunz 2023/02/12 15 | */ 16 | class NotificationReferent(private val componentInfo: ComponentInfoWrapper) : Referent { 17 | 18 | override fun getReferredValue(which: Int, runtime: TaskRuntime): Any? { 19 | return when (which) { 20 | 0 -> this 21 | // Notification content 22 | 1 -> componentInfo.paneTitle 23 | // ComponentInfo which sends the notification 24 | 2 -> componentInfo 25 | 3 -> componentInfo.label 26 | else -> super.getReferredValue(which, runtime) 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/task/applet/flow/ref/UiObjectReferent.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.task.applet.flow.ref 6 | 7 | import android.graphics.Rect 8 | import android.view.accessibility.AccessibilityNodeInfo 9 | import top.xjunz.tasker.engine.runtime.Referent 10 | import top.xjunz.tasker.engine.runtime.TaskRuntime 11 | import top.xjunz.tasker.task.applet.util.IntValueUtil 12 | 13 | /** 14 | * @author xjunz 2023/02/12 15 | */ 16 | class UiObjectReferent(private val node: AccessibilityNodeInfo) : Referent { 17 | 18 | private val centerCoordinate: Int by lazy { 19 | val bounds = Rect() 20 | node.getBoundsInScreen(bounds) 21 | IntValueUtil.composeXY(bounds.centerX(), bounds.centerY()) 22 | } 23 | 24 | override fun getReferredValue(which: Int, runtime: TaskRuntime): Any? { 25 | return when (which) { 26 | 0 -> node 27 | 1 -> node.text?.toString() 28 | 2 -> centerCoordinate 29 | else -> super.getReferredValue(which, runtime) 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/task/applet/option/AppletFactoryUpdateHelper.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.task.applet.option 6 | 7 | /** 8 | * @author xjunz 2023/09/15 9 | */ 10 | object AppletFactoryUpdateHelper { 11 | 12 | fun checkUpdate(registryId: Int, appletId: Int): Int { 13 | return appletId 14 | } 15 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/task/applet/option/registry/ShellCmdActionRegistry.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.task.applet.option.registry 6 | 7 | import top.xjunz.tasker.R 8 | import top.xjunz.tasker.task.applet.action.ShellCmdAction 9 | import top.xjunz.tasker.task.applet.anno.AppletOrdinal 10 | import top.xjunz.tasker.task.applet.value.VariantArgType 11 | 12 | /** 13 | * @author xjunz 2023/04/03 14 | */ 15 | class ShellCmdActionRegistry(id: Int) : AppletOptionRegistry(id) { 16 | 17 | @AppletOrdinal(0x0001) 18 | val executeShellCmd = appletOption(R.string.execute_shell_cmd) { 19 | ShellCmdAction(false) 20 | }.withValueArgument(R.string.shell_cmd) 21 | .shizukuOnly() 22 | .premiumOnly() 23 | 24 | @AppletOrdinal(0x0002) 25 | val executeShFile = appletOption(R.string.execute_sh_file) { 26 | ShellCmdAction(true) 27 | }.withValueArgument(R.string.file_path, VariantArgType.TEXT_FILE_PATH) 28 | .shizukuOnly() 29 | .premiumOnly() 30 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/task/applet/util/IntValueUtil.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.task.applet.util 6 | 7 | import android.graphics.Point 8 | 9 | /** 10 | * @author xjunz 2023/01/08 11 | */ 12 | object IntValueUtil { 13 | 14 | private fun integerArrayOf(vararg ints: Int): Array { 15 | return ints.toTypedArray() 16 | } 17 | 18 | fun parseTime(time: Int): Array { 19 | return integerArrayOf(time ushr 16 and 0xFF, time ushr 8 and 0xFF, time and 0xFF) 20 | } 21 | 22 | fun composeTime(hour: Int, min: Int, sec: Int): Int { 23 | return hour shl 16 or (min shl 8) or sec 24 | } 25 | 26 | fun parseXY(coordinate: Int): Point { 27 | return Point(coordinate ushr 16, coordinate and 0xFFFF) 28 | } 29 | 30 | fun composeXY(x: Int, y: Int): Int { 31 | check(x in 0..0xFFFF) 32 | check(y in 0..0xFFFF) 33 | return x shl 16 or y 34 | } 35 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/task/applet/util/NumberRangeUtil.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.task.applet.util 6 | 7 | import top.xjunz.shared.utils.unsupportedOperation 8 | 9 | /** 10 | * @author xjunz 2022/10/23 11 | */ 12 | internal object NumberRangeUtil { 13 | 14 | fun contains(start: T?, stop: T?, e: T): Boolean { 15 | if (start == null && stop == null) return true 16 | return (start == null || compare(e, start) >= 0) 17 | && (stop == null || compare(e, stop) <= 0) 18 | } 19 | 20 | private fun compare(a: Number, b: Number): Int { 21 | 22 | if (a is Int && b is Int) 23 | return a.compareTo(b) 24 | 25 | if (a is Float && b is Float) 26 | return a.compareTo(b) 27 | 28 | if (a is Long && b is Long) 29 | return a.compareTo(b) 30 | 31 | unsupportedOperation("Unsupported comparison types: ${a::class.java} and ${b::class.java}!") 32 | } 33 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/task/applet/value/LongDuration.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.task.applet.value 6 | 7 | /** 8 | * @author xjunz 2023/09/11 9 | */ 10 | class LongDuration(val day: Int, val hour: Int, val min: Int, val sec: Int) { 11 | 12 | companion object { 13 | 14 | val COMPOSER = BitwiseValueComposer.create( 15 | BitwiseValueComposer.integer(31), 16 | BitwiseValueComposer.integer(59), 17 | BitwiseValueComposer.integer(59), 18 | BitwiseValueComposer.integer(59) 19 | ) 20 | 21 | fun parse(composed: Long): LongDuration { 22 | val parsed = COMPOSER.parse(composed) 23 | return LongDuration( 24 | parsed[0] as Int, 25 | parsed[1] as Int, 26 | parsed[2] as Int, 27 | parsed[3] as Int 28 | ) 29 | } 30 | } 31 | 32 | fun toMilliseconds(): Long { 33 | return day * (1000 * 60 * 60 * 24) + hour * (1000 * 60 * 60) + min * (1000 * 60) + sec * 1000L 34 | } 35 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/task/applet/value/ScrollMetrics.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.task.applet.value 6 | 7 | import androidx.test.uiautomator.Direction 8 | 9 | /** 10 | * @author xjunz 2023/03/13 11 | */ 12 | class ScrollMetrics(val direction: Direction, val speed: Int) { 13 | 14 | companion object { 15 | 16 | val COMPOSER = BitwiseValueComposer.create( 17 | BitwiseValueComposer.integer(3), 18 | BitwiseValueComposer.integer(100) 19 | ) 20 | 21 | fun parse(composed: Long): ScrollMetrics { 22 | val parsed = COMPOSER.parse(composed) 23 | return ScrollMetrics(Direction.ALL_DIRECTIONS[parsed[0] as Int], parsed[1] as Int) 24 | } 25 | } 26 | 27 | val steps: Int 28 | get() { 29 | check(speed in 1..99) { 30 | "Speed must in 1..99" 31 | } 32 | return 100 - speed 33 | } 34 | 35 | val isVertical: Boolean get() = direction == Direction.DOWN || direction == Direction.UP 36 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/task/applet/value/ValueComposer.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.task.applet.value 6 | 7 | /** 8 | * @author xjunz 2023/01/08 9 | */ 10 | abstract class ValueComposer { 11 | 12 | fun compose(vararg components: Component?): Value { 13 | return composeInternal(components) 14 | } 15 | 16 | protected abstract fun composeInternal(components: Array): Value 17 | 18 | abstract fun parse(composed: Value): Array 19 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/task/inspector/InspectorMode.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.task.inspector 6 | 7 | import androidx.annotation.StringRes 8 | import top.xjunz.tasker.R 9 | import top.xjunz.tasker.ktx.str 10 | 11 | /** 12 | * @author xjunz 2022/10/31 13 | */ 14 | enum class InspectorMode(@StringRes labelRes: Int) { 15 | 16 | COMPONENT(R.string.component_info), UI_OBJECT(R.string.ui_object), 17 | COORDS(R.string.coords), GESTURE_RECORDER(R.string.record_gesture), 18 | TASK_ASSISTANT(R.string.task_assistant); 19 | 20 | val label: String = labelRes.str 21 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/ui/base/SavedStateViewModel.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.ui.base 6 | 7 | import androidx.lifecycle.MutableLiveData 8 | import androidx.lifecycle.SavedStateHandle 9 | import androidx.lifecycle.ViewModel 10 | import kotlin.properties.ReadOnlyProperty 11 | import kotlin.reflect.KProperty 12 | 13 | /** 14 | * @author xjunz 2022/10/25 15 | */ 16 | open class SavedStateViewModel(private val states: SavedStateHandle) : ViewModel() { 17 | 18 | fun get(key: String): MutableLiveData { 19 | return states.getLiveData(key) 20 | } 21 | 22 | fun setValue(key: String, value: T?) { 23 | get(key).value = value 24 | } 25 | 26 | class SavedStateProperty : ReadOnlyProperty> { 27 | 28 | override fun getValue(thisRef: SavedStateViewModel, property: KProperty<*>): MutableLiveData { 29 | return thisRef.get(property.name) 30 | } 31 | } 32 | 33 | fun savedLiveData(): SavedStateProperty { 34 | return SavedStateProperty() 35 | } 36 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/ui/demo/Demonstration.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.ui.demo 6 | 7 | import android.content.Context 8 | import android.view.View 9 | 10 | /** 11 | * @author xjunz 2022/12/12 12 | */ 13 | abstract class Demonstration(val context: Context) { 14 | 15 | abstract fun getView(): View 16 | 17 | abstract fun startDemonstration() 18 | 19 | abstract fun stopDemonstration() 20 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/ui/main/ScrollTarget.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.ui.main 6 | 7 | import androidx.recyclerview.widget.RecyclerView 8 | 9 | /** 10 | * @author xjunz 2023/03/05 11 | */ 12 | interface ScrollTarget { 13 | fun getScrollTarget(): RecyclerView? 14 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/util/Icons.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.util 6 | 7 | import android.content.pm.ApplicationInfo 8 | import android.graphics.Bitmap 9 | import android.graphics.ColorMatrix 10 | import android.graphics.ColorMatrixColorFilter 11 | import me.zhanghai.android.appiconloader.AppIconLoader 12 | import top.xjunz.tasker.app 13 | import top.xjunz.tasker.ktx.dp 14 | 15 | /** 16 | * @author xjunz 2021/9/15 17 | */ 18 | object Icons { 19 | 20 | private val iconLoader by lazy { 21 | AppIconLoader(48.dp, true, app) 22 | } 23 | 24 | val myIcon by lazy { 25 | iconLoader.loadIcon(app.applicationInfo) 26 | } 27 | 28 | val desaturatedColorFilter = ColorMatrixColorFilter(ColorMatrix().also { it.setSaturation(0F) }) 29 | 30 | fun loadIcon(requireAppInfo: ApplicationInfo): Bitmap { 31 | return iconLoader.loadIcon(requireAppInfo) 32 | } 33 | } -------------------------------------------------------------------------------- /app/src/main/java/top/xjunz/tasker/util/Motions.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.util 6 | 7 | import android.animation.TimeInterpolator 8 | import android.annotation.SuppressLint 9 | import android.content.Context 10 | import androidx.annotation.AttrRes 11 | import com.google.android.material.R 12 | import com.google.android.material.animation.AnimationUtils 13 | import com.google.android.material.motion.MotionUtils 14 | import top.xjunz.tasker.app 15 | 16 | object Motions { 17 | 18 | @SuppressLint("RestrictedApi") 19 | private fun Context.resolveEasingMotion(@AttrRes motionAttr: Int): TimeInterpolator { 20 | return MotionUtils.resolveThemeInterpolator( 21 | this, motionAttr, AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR 22 | ) 23 | } 24 | 25 | val EASING_EMPHASIZED by lazy { 26 | app.resolveEasingMotion(R.attr.motionEasingEmphasized) 27 | } 28 | } -------------------------------------------------------------------------------- /app/src/main/res/anim/dialog_window_enter_sade.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 12 | 15 | 16 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/anim/dialog_window_enter_slide.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 12 | 15 | 16 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/anim/dialog_window_exit_sade.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 9 | 10 | 13 | 14 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/anim/dialog_window_exit_slide.xml: -------------------------------------------------------------------------------- 1 | 4 | 7 | 8 | 11 | 12 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/anim/mtrl_item_ease_enter.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 9 | 13 | 14 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/color/color_bg_item_enum_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/color/color_control_highlight.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/color/color_control_on_primary.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/color/color_drop_target_stroke_color.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/color/color_primary_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/color/color_status_icon.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/color/color_status_text.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/color/color_status_tint.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/color/color_text_control_highlight.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/color/color_text_control_normal.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/color/color_text_item_enum_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/color/color_text_selectable.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/color/icon_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/baseline_add_circle_outline_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/baseline_backup_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/baseline_chat_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/baseline_group_add_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/baseline_hourglass_empty_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/baseline_info_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/baseline_nights_stay_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/baseline_restart_alt_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_badge.xml: -------------------------------------------------------------------------------- 1 | 4 | 6 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_bottom_sheet_handler.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_dialog.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_drop_target.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 9 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_dummy_target.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_floating_inspector_trash_bin.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_selectable_circle.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11 | 12 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_selectable_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_selectable_outlined_surface.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_selectable_primary_surface.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_selectable_surface.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_selectable_tinted_circle.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_selector_applet_factory.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_solid_circle.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_surface.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_tinted_chip.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_arrow_back_24px.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_add_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_add_link_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_android_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_auto_awesome_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_bug_report_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_chevron_left_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_close_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_expand_less_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_expand_more_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_gamepad_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_grid_off_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_grid_on_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_help_outline_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_keyboard_arrow_down_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_keyboard_arrow_up_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_link_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_more_vert_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_my_location_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_navigate_before_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_navigate_next_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_open_in_new_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_play_arrow_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_schedule_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 14 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_send_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_stop_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_switch_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_task_alt_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_unfold_less_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_unfold_more_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_call_split_24px.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_cancel_24px.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_check_circle_24px.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_chevron_right_24px.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_clear_all_24px.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_delete_forever_24px.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_description_24px.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_do_not_disturb_24px.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_done_24px.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_edit_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_filter_list_24px.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_history_24px.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_hourglass_bottom_24px.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_import_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_line_end_arrow_notch_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_line_start_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_menu_24px.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_outline_hide_image_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_outline_image_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_outline_lock_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_outline_share_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_playlist_add_24px.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_replay_24px.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_save_24px.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_search_24px.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_status_control.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_swap_horiz_24px.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_text_fields_24px.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tips_and_updates_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tune_24px.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_twotone_cancel_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 16 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_twotone_check_circle_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 16 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_twotone_format_list_bulleted_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 12 | 15 | 18 | 21 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_twotone_layers_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_twotone_navigation_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | 14 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_verified_24px.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_widgets_24px.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_applet_cateory.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 9 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_applet_factory.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 7 | 8 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_flow_opt_demo.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_flow_operation_demo.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 9 | 12 | 13 | 20 | 21 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_menu_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 9 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/layout/overlay_bubble_collapsed.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 14 | 15 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/layout/overlay_component.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 9 | 13 | 14 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/overlay_window_bounds_detector.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/menu/applet_batch_operation.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 11 | 14 | 17 | 20 | 23 | 24 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/menu/feedbacks.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/menu/main.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 10 | 13 | 16 | 17 | 20 | 23 | 24 | 25 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/menu/night_modes.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 9 | 12 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/menu/operating_modes.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 11 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/menu/task_bottom_bar.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 11 | 12 | 16 | 17 | 21 | 22 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjunz/AutoTask/50efc671a84425bf1f9f38d42b3238b3a055467c/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjunz/AutoTask/50efc671a84425bf1f9f38d42b3238b3a055467c/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjunz/AutoTask/50efc671a84425bf1f9f38d42b3238b3a055467c/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjunz/AutoTask/50efc671a84425bf1f9f38d42b3238b3a055467c/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjunz/AutoTask/50efc671a84425bf1f9f38d42b3238b3a055467c/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjunz/AutoTask/50efc671a84425bf1f9f38d42b3238b3a055467c/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjunz/AutoTask/50efc671a84425bf1f9f38d42b3238b3a055467c/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjunz/AutoTask/50efc671a84425bf1f9f38d42b3238b3a055467c/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjunz/AutoTask/50efc671a84425bf1f9f38d42b3238b3a055467c/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjunz/AutoTask/50efc671a84425bf1f9f38d42b3238b3a055467c/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/values/check_cases.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 运行测试后,%s 8 | 文本识别 9 | 会提示屏幕中间的文字 10 | 模拟拖放 11 | 会将按钮拖放到目标位置,目标位置的文字改变为按钮的文字 12 | 全局动作 13 | 会执行以下动作:切换到最近任务,返回当前应用,下拉通知栏,关闭通知栏 14 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 8dp 7 | 12dp 8 | 24dp 9 | 24dp 10 | 16dp 11 | 16dp 12 | 48dp 13 | 40dp 14 | -------------------------------------------------------------------------------- /app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | #00C6F3 8 | -------------------------------------------------------------------------------- /app/src/main/res/values/values.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | #4CAF50 8 | -------------------------------------------------------------------------------- /app/src/main/res/xml/automator_service.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/xml/file_paths.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 9 | 12 | -------------------------------------------------------------------------------- /app/src/test/kotlin/top/xjunz/tasker/task/applet/util/IntValueUtilTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.task.applet.util 6 | 7 | import org.junit.Test 8 | 9 | 10 | /** 11 | * @author xjunz 2023/01/22 12 | */ 13 | internal class IntValueUtilTest { 14 | 15 | @Test 16 | fun parseTime() { 17 | } 18 | 19 | @Test 20 | fun composeTime() { 21 | println(IntValueUtil.parseTime(IntValueUtil.composeTime(23,59,59)).joinToString()) 22 | } 23 | 24 | @Test 25 | fun parseCoordinate() { 26 | } 27 | 28 | @Test 29 | fun composeCoordinate() { 30 | } 31 | } -------------------------------------------------------------------------------- /coroutine-ui-automator/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /coroutine-ui-automator/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjunz/AutoTask/50efc671a84425bf1f9f38d42b3238b3a055467c/coroutine-ui-automator/consumer-rules.pro -------------------------------------------------------------------------------- /coroutine-ui-automator/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 -------------------------------------------------------------------------------- /coroutine-ui-automator/src/androidTest/java/top/xjunz/tasker/uiautomator/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package top.xjunz.tasker.uiautomator 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 | assertEquals("top.xjunz.tasker.uiautomator.test", appContext.packageName) 21 | } 22 | } -------------------------------------------------------------------------------- /coroutine-ui-automator/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /coroutine-ui-automator/src/main/java/top/xjunz/tasker/uiautomator/CoroutineGestureController.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.uiautomator 6 | 7 | import androidx.test.uiautomator.PointerGesture 8 | 9 | /** 10 | * @author xjunz 2023/02/15 11 | */ 12 | abstract class CoroutineGestureController internal constructor(val bridge: CoroutineUiAutomatorBridge) { 13 | 14 | abstract suspend fun performSinglePointerGesture(gesture: PointerGesture): Boolean 15 | 16 | } -------------------------------------------------------------------------------- /coroutine-ui-automator/src/test/java/top/xjunz/tasker/uiautomator/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package top.xjunz.tasker.uiautomator 2 | 3 | import org.junit.Assert.assertEquals 4 | import org.junit.Test 5 | 6 | /** 7 | * Example local unit test, which will execute on the development machine (host). 8 | * 9 | * See [testing documentation](http://d.android.com/tools/testing). 10 | */ 11 | class ExampleUnitTest { 12 | @Test 13 | fun addition_isCorrect() { 14 | assertEquals(4, 2 + 2) 15 | } 16 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | ## For more details on how to configure your build environment visit 2 | # http://www.gradle.org/docs/current/userguide/build_environment.html 3 | # 4 | # Specifies the JVM arguments used for the daemon process. 5 | # The setting is particularly useful for tweaking memory settings. 6 | # Default value: -Xmx1024m -XX:MaxPermSize=256m 7 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 8 | # 9 | # When configured, Gradle will run in incubating parallel mode. 10 | # This option should only be used with decoupled projects. More details, visit 11 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 12 | # org.gradle.parallel=true 13 | #Mon Oct 10 07:18:27 CST 2022 14 | android.nonTransitiveRClass=true 15 | kotlin.code.style=official 16 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding\=UTF-8 17 | android.useAndroidX=true 18 | android.enableJetifier=true 19 | android.experimental.legacyTransform.forceNonIncremental=true 20 | android.defaults.buildfeatures.buildconfig=true 21 | android.nonFinalResIds=false 22 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjunz/AutoTask/50efc671a84425bf1f9f38d42b3238b3a055467c/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Sep 19 09:37:15 CST 2022 2 | distributionBase=GRADLE_USER_HOME 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /hidden-apis/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /hidden-apis/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjunz/AutoTask/50efc671a84425bf1f9f38d42b3238b3a055467c/hidden-apis/consumer-rules.pro -------------------------------------------------------------------------------- /hidden-apis/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 -------------------------------------------------------------------------------- /hidden-apis/src/androidTest/java/top/xjunz/hidden_api/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.hidden_api; 6 | 7 | import static org.junit.Assert.assertEquals; 8 | 9 | import android.content.Context; 10 | 11 | import androidx.test.ext.junit.runners.AndroidJUnit4; 12 | import androidx.test.platform.app.InstrumentationRegistry; 13 | 14 | import org.junit.Test; 15 | import org.junit.runner.RunWith; 16 | 17 | /** 18 | * Instrumented test, which will execute on an Android device. 19 | * 20 | * @see Testing documentation 21 | */ 22 | @RunWith(AndroidJUnit4.class) 23 | public class ExampleInstrumentedTest { 24 | @Test 25 | public void useAppContext() { 26 | // Context of the app under test. 27 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 28 | assertEquals("top.xjunz.hidden_api.test", appContext.getPackageName()); 29 | } 30 | } -------------------------------------------------------------------------------- /hidden-apis/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /hidden-apis/src/main/aidl/android/accessibilityservice/IAccessibilityServiceClient.aidl: -------------------------------------------------------------------------------- 1 | // IAccessibilityServiceClient.aidl 2 | package android.accessibilityservice; 3 | 4 | interface IAccessibilityServiceClient { 5 | } 6 | -------------------------------------------------------------------------------- /hidden-apis/src/main/aidl/android/accessibilityservice/IAccessibilityServiceConnection.aidl: -------------------------------------------------------------------------------- 1 | // IAccessibilityServiceConnection.aidl 2 | package android.accessibilityservice; 3 | 4 | // Declare any non-default types here with import statements 5 | 6 | interface IAccessibilityServiceConnection { 7 | } -------------------------------------------------------------------------------- /hidden-apis/src/main/java/android/app/ActivityManagerNative.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package android.app; 6 | 7 | import android.os.IBinder; 8 | 9 | /** 10 | * @author xjunz 2022/07/11 11 | */ 12 | public class ActivityManagerNative { 13 | 14 | public static IActivityManager asInterface(IBinder obj) { 15 | throw new RuntimeException("Stub!"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /hidden-apis/src/main/java/android/app/ActivityThread.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package android.app; 6 | 7 | /** 8 | * @author xjunz 2023/01/03 9 | */ 10 | public class ActivityThread { 11 | 12 | public static ActivityThread currentActivityThread() { 13 | throw new RuntimeException("Stub!"); 14 | } 15 | 16 | public ContextImpl getSystemContext() { 17 | throw new RuntimeException("Stub!"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /hidden-apis/src/main/java/android/app/ContextImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package android.app; 6 | 7 | import android.content.Context; 8 | 9 | /** 10 | * @author xjunz 2023/01/07 11 | */ 12 | public abstract class ContextImpl extends Context { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /hidden-apis/src/main/java/android/app/UiAutomationConnection.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package android.app; 6 | 7 | /** 8 | * @author xjunz 2021/6/23 0:52 9 | */ 10 | public class UiAutomationConnection extends IUiAutomationConnection.Default { 11 | public UiAutomationConnection() { 12 | throw new RuntimeException("Stub!"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /hidden-apis/src/main/java/android/app/UiAutomationHidden.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package android.app; 6 | 7 | import android.os.Looper; 8 | import android.os.ParcelFileDescriptor; 9 | 10 | import dev.rikka.tools.refine.RefineAs; 11 | 12 | /** 13 | * @author xjunz 2021/6/23 0:48 14 | */ 15 | @SuppressWarnings("unused") 16 | @RefineAs(UiAutomation.class) 17 | public class UiAutomationHidden { 18 | 19 | public UiAutomationHidden(Looper looper, IUiAutomationConnection connection) { 20 | throw new RuntimeException("Stub!"); 21 | } 22 | 23 | public void connect() { 24 | throw new RuntimeException("Stub!"); 25 | } 26 | 27 | public void connect(int flag) { 28 | throw new RuntimeException("Stub!"); 29 | } 30 | 31 | public void disconnect() { 32 | throw new RuntimeException("Stub!"); 33 | } 34 | 35 | public ParcelFileDescriptor[] executeShellCommandRwe(String command) { 36 | throw new RuntimeException("Stub!"); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /hidden-apis/src/main/java/android/content/ContextHidden.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package android.content; 6 | 7 | import android.os.UserHandle; 8 | 9 | import dev.rikka.tools.refine.RefineAs; 10 | 11 | /** 12 | * @author xjunz 2023/01/03 13 | */ 14 | @RefineAs(Context.class) 15 | public class ContextHidden { 16 | 17 | public Context createPackageContextAsUser(String packageName, int flags, UserHandle user) { 18 | throw new RuntimeException("Stub!"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /hidden-apis/src/main/java/android/content/IClipboard.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package android.content; 6 | 7 | /** 8 | * @author xjunz 2022/11/16 9 | */ 10 | public interface IClipboard { 11 | 12 | void setPrimaryClip(android.content.ClipData clip, java.lang.String callingPackage, int userId); 13 | 14 | abstract class Stub { 15 | 16 | public static android.content.IClipboard asInterface(android.os.IBinder obj) { 17 | throw new RuntimeException("Stub!"); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /hidden-apis/src/main/java/android/content/pm/IPackageManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package android.content.pm; 6 | 7 | import android.content.ComponentName; 8 | import android.os.IBinder; 9 | import android.os.IInterface; 10 | 11 | import java.util.List; 12 | 13 | /** 14 | * @author xjunz 2021/7/8 15 | */ 16 | public interface IPackageManager extends IInterface { 17 | ComponentName getHomeActivities(List outHomeCandidates); 18 | 19 | /** 20 | * As per {@link android.content.pm.PackageManager#setComponentEnabledSetting}. 21 | */ 22 | void setComponentEnabledSetting(ComponentName componentName, 23 | int newState, int flags, int userId); 24 | 25 | ApplicationInfo getApplicationInfo(String packageName, long flags, int userId); 26 | 27 | PackageInfo getPackageInfo(String packageName, long flags, int userId); 28 | 29 | abstract class Stub { 30 | 31 | public static IPackageManager asInterface(IBinder obj) { 32 | throw new RuntimeException("Stub!"); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /hidden-apis/src/main/java/android/hardware/input/IInputManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package android.hardware.input; 6 | 7 | import android.os.IBinder; 8 | import android.view.InputEvent; 9 | 10 | /** 11 | * @author xjunz 2021/6/22 12 | */ 13 | @SuppressWarnings("unused") 14 | public interface IInputManager { 15 | 16 | boolean injectInputEvent(InputEvent event, int mode); 17 | 18 | abstract class Stub{ 19 | 20 | public static IInputManager asInterface(IBinder obj) { 21 | throw new RuntimeException("Stub!"); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /hidden-apis/src/main/java/android/os/BatteryManagerHidden.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package android.os; 6 | 7 | import dev.rikka.tools.refine.RefineAs; 8 | 9 | /** 10 | * @author xjunz 2022/11/10 11 | */ 12 | @RefineAs(BatteryManagerHidden.class) 13 | public class BatteryManagerHidden { 14 | 15 | public BatteryManagerHidden() { 16 | throw new RuntimeException("Stub!"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /hidden-apis/src/main/java/android/os/IBinderHidden.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package android.os; 6 | 7 | import dev.rikka.tools.refine.RefineAs; 8 | 9 | /** 10 | * @author xjunz 2022/12/24 11 | */ 12 | @RefineAs(IBinder.class) 13 | public interface IBinderHidden { 14 | int SHELL_COMMAND_TRANSACTION = ('_'<<24)|('C'<<16)|('M'<<8)|'D'; 15 | } 16 | -------------------------------------------------------------------------------- /hidden-apis/src/main/java/android/os/UserHandleHidden.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package android.os; 6 | 7 | import dev.rikka.tools.refine.RefineAs; 8 | 9 | /** 10 | * @author xjunz 2023/01/03 11 | */ 12 | @RefineAs(UserHandle.class) 13 | public class UserHandleHidden { 14 | 15 | public static UserHandle of(int uid) { 16 | throw new RuntimeException("Stub!"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /hidden-apis/src/main/java/android/view/WindowManagerImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package android.view; 6 | 7 | import android.os.IBinder; 8 | 9 | /** 10 | * @author xjunz 2023/01/03 11 | */ 12 | public abstract class WindowManagerImpl implements WindowManager { 13 | 14 | public void setDefaultToken(IBinder binder) { 15 | throw new RuntimeException("Stub!"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | google() 5 | mavenCentral() 6 | } 7 | } 8 | dependencyResolutionManagement { 9 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 10 | repositories { 11 | google() 12 | mavenCentral() 13 | } 14 | } 15 | rootProject.name = "自动任务" 16 | include ':app' 17 | include ':hidden-apis' 18 | include ':ui-automator' 19 | include ':tasker-engine' 20 | include ':shared-library' 21 | include ':coroutine-ui-automator' 22 | include ':ssl' 23 | -------------------------------------------------------------------------------- /shared-library/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /shared-library/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjunz/AutoTask/50efc671a84425bf1f9f38d42b3238b3a055467c/shared-library/consumer-rules.pro -------------------------------------------------------------------------------- /shared-library/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 -------------------------------------------------------------------------------- /shared-library/src/androidTest/java/top/xjunz/shared/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.shared 6 | 7 | import androidx.test.ext.junit.runners.AndroidJUnit4 8 | import androidx.test.platform.app.InstrumentationRegistry 9 | import org.junit.Assert.assertEquals 10 | import org.junit.Test 11 | import org.junit.runner.RunWith 12 | 13 | /** 14 | * Instrumented test, which will execute on an Android device. 15 | * 16 | * See [testing documentation](http://d.android.com/tools/testing). 17 | */ 18 | @RunWith(AndroidJUnit4::class) 19 | class ExampleInstrumentedTest { 20 | @Test 21 | fun useAppContext() { 22 | // Context of the app under test. 23 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 24 | assertEquals("top.xjunz.shared.test", appContext.packageName) 25 | } 26 | } -------------------------------------------------------------------------------- /shared-library/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /shared-library/src/main/java/top/xjunz/shared/ktx/Any.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.shared.ktx 6 | 7 | /** 8 | * @author xjunz 2022/07/14 9 | */ 10 | 11 | @Throws(ClassCastException::class) 12 | @Suppress("UNCHECKED_CAST") 13 | fun Any.casted(): T { 14 | return this as T 15 | } -------------------------------------------------------------------------------- /shared-library/src/main/java/top/xjunz/shared/ktx/Collections.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.shared.ktx 6 | 7 | import androidx.collection.ArrayMap 8 | 9 | /** 10 | * @author xjunz 2023/10/11 11 | */ 12 | fun arrayMapOf(vararg entries: Pair): ArrayMap { 13 | val map = ArrayMap(entries.size) 14 | map.putAll(entries) 15 | return map 16 | } 17 | 18 | fun MutableList.insert(position: Int, value: V) { 19 | if (size == 0) { 20 | add(value) 21 | } else { 22 | add(position, value) 23 | } 24 | } -------------------------------------------------------------------------------- /shared-library/src/main/java/top/xjunz/shared/trace/Logger.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.shared.trace 6 | 7 | import android.util.Log 8 | import top.xjunz.shared.BuildConfig 9 | 10 | /** 11 | * @author xjunz 2022/07/14 12 | */ 13 | 14 | private const val DEF_LOGCAT_TAG = "AutomatorTrace" 15 | 16 | fun logcat(any: Any?, priority: Int = Log.INFO, tag: String = DEF_LOGCAT_TAG) { 17 | Log.println(priority, tag, any.toString()) 18 | } 19 | 20 | fun debugLogcat(any: Any?, tag: String = DEF_LOGCAT_TAG) { 21 | if (BuildConfig.DEBUG) { 22 | Log.println(Log.DEBUG, tag, any.toString()) 23 | } 24 | } 25 | 26 | fun Throwable.logcatStackTrace() { 27 | Log.e(DEF_LOGCAT_TAG, Log.getStackTraceString(this)) 28 | } 29 | 30 | fun V.logit(priority: Int = Log.INFO, tag: String = DEF_LOGCAT_TAG): V { 31 | logcat(this, priority, tag) 32 | return this 33 | } -------------------------------------------------------------------------------- /shared-library/src/main/java/top/xjunz/shared/utils/Exceptions.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.shared.utils 6 | 7 | /** 8 | * @author xjunz 2022/07/21 9 | */ 10 | fun unsupportedOperation(msg: String? = null): Nothing { 11 | throw UnsupportedOperationException(msg ?: "Not supported") 12 | } 13 | 14 | fun runtimeException(msg: String): Nothing { 15 | throw RuntimeException(msg) 16 | } 17 | 18 | fun Throwable.rethrowAsRuntimeException(): Nothing { 19 | throw RuntimeException(this) 20 | } 21 | 22 | fun Throwable.rethrowInRemoteProcess(): Nothing { 23 | val throwable = IllegalArgumentException(this) 24 | throwable.addSuppressed(this) 25 | throw throwable 26 | } 27 | 28 | fun illegalArgument(name: String, value: Any): Nothing { 29 | throw IllegalArgumentException("Unrecognized $name: $value!") 30 | } 31 | 32 | fun illegalArgument(msg: String? = null): Nothing { 33 | throw IllegalArgumentException(msg) 34 | } 35 | -------------------------------------------------------------------------------- /shared-library/src/main/java/top/xjunz/shared/utils/OsUtil.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.shared.utils 6 | 7 | import android.system.Os 8 | 9 | 10 | /** 11 | * @author xjunz 2023/01/03 12 | */ 13 | object OsUtil { 14 | 15 | val uid: Int 16 | 17 | private val aid: Int 18 | 19 | inline val isInShellProcess get() = uid == 2000 20 | 21 | inline val isInRootProcess get() = uid == 0 22 | 23 | init { 24 | val i = Os.getuid() 25 | uid = i 26 | aid = i / 100_000 27 | } 28 | } -------------------------------------------------------------------------------- /shared-library/src/test/java/top/xjunz/shared/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.shared 6 | 7 | import org.junit.Assert.assertEquals 8 | import org.junit.Test 9 | 10 | /** 11 | * Example local unit test, which will execute on the development machine (host). 12 | * 13 | * See [testing documentation](http://d.android.com/tools/testing). 14 | */ 15 | class ExampleUnitTest { 16 | @Test 17 | fun addition_isCorrect() { 18 | assertEquals(4, 2 + 2) 19 | } 20 | } -------------------------------------------------------------------------------- /ssl/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /ssl/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjunz/AutoTask/50efc671a84425bf1f9f38d42b3238b3a055467c/ssl/consumer-rules.pro -------------------------------------------------------------------------------- /ssl/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 -------------------------------------------------------------------------------- /ssl/src/androidTest/java/top/xjunz/tasker/ssl/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package top.xjunz.tasker.ssl 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 | assertEquals("top.xjunz.tasker.ssl.test", appContext.packageName) 21 | } 22 | } -------------------------------------------------------------------------------- /ssl/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ssl/src/main/cpp/android_log.h: -------------------------------------------------------------------------------- 1 | #ifndef ANDROID_LOG_H 2 | #define ANDROID_LOG_H 3 | 4 | #include 5 | 6 | #define LOG_TAG "XTask" 7 | #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) 8 | #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) 9 | #define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__) 10 | #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) 11 | 12 | #endif //ANDROID_LOG_H 13 | -------------------------------------------------------------------------------- /ssl/src/main/java/x/f.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package x; 6 | 7 | /** 8 | * @author xjunz 2023/03/01 9 | */ 10 | public class f /* Security */ { 11 | 12 | static { 13 | System.loadLibrary("ssl"); 14 | } 15 | 16 | public static native String alpha(byte[] bytes); // encrypt 17 | 18 | public static native byte[] delta(String str); // decrypt 19 | } 20 | -------------------------------------------------------------------------------- /ssl/src/test/java/top/xjunz/tasker/ssl/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package top.xjunz.tasker.ssl 2 | 3 | import org.junit.Assert.assertEquals 4 | import org.junit.Test 5 | 6 | /** 7 | * Example local unit test, which will execute on the development machine (host). 8 | * 9 | * See [testing documentation](http://d.android.com/tools/testing). 10 | */ 11 | class ExampleUnitTest { 12 | @Test 13 | fun addition_isCorrect() { 14 | assertEquals(4, 2 + 2) 15 | } 16 | } -------------------------------------------------------------------------------- /tasker-engine/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /tasker-engine/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjunz/AutoTask/50efc671a84425bf1f9f38d42b3238b3a055467c/tasker-engine/consumer-rules.pro -------------------------------------------------------------------------------- /tasker-engine/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 -------------------------------------------------------------------------------- /tasker-engine/src/androidTest/java/top/xjunz/tasker/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker 6 | 7 | import androidx.test.ext.junit.runners.AndroidJUnit4 8 | import androidx.test.platform.app.InstrumentationRegistry 9 | import org.junit.Assert.assertEquals 10 | import org.junit.Test 11 | import org.junit.runner.RunWith 12 | 13 | /** 14 | * Instrumented test, which will execute on an Android device. 15 | * 16 | * See [testing documentation](http://d.android.com/tools/testing). 17 | */ 18 | @RunWith(AndroidJUnit4::class) 19 | class ExampleInstrumentedTest { 20 | @Test 21 | fun useAppContext() { 22 | // Context of the app under test. 23 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 24 | assertEquals("top.xjunz.tasker.test", appContext.packageName) 25 | } 26 | } -------------------------------------------------------------------------------- /tasker-engine/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /tasker-engine/src/main/aidl/top/xjunz/tasker/engine/dto/XTaskDTO.aidl: -------------------------------------------------------------------------------- 1 | // XTaskDTO.aidl 2 | package top.xjunz.tasker.engine.dto; 3 | 4 | // Declare any non-default types here with import statements 5 | 6 | parcelable XTaskDTO; -------------------------------------------------------------------------------- /tasker-engine/src/main/aidl/top/xjunz/tasker/engine/task/TaskSnapshot.aidl: -------------------------------------------------------------------------------- 1 | // TaskSnapshot.aidl 2 | package top.xjunz.tasker.engine.task; 3 | 4 | // Declare any non-default types here with import statements 5 | 6 | parcelable TaskSnapshot; -------------------------------------------------------------------------------- /tasker-engine/src/main/java/top/xjunz/tasker/engine/applet/action/Action.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.engine.applet.action 6 | 7 | import top.xjunz.tasker.engine.applet.base.Applet 8 | 9 | /** 10 | * @author xjunz 2023/09/24 11 | */ 12 | abstract class Action : Applet() { 13 | 14 | final override val supportsAnywayRelation: Boolean = true 15 | 16 | } 17 | -------------------------------------------------------------------------------- /tasker-engine/src/main/java/top/xjunz/tasker/engine/applet/action/ArgumentAction.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.engine.applet.action 6 | 7 | import top.xjunz.tasker.engine.applet.base.AppletResult 8 | import top.xjunz.tasker.engine.runtime.TaskRuntime 9 | 10 | /** 11 | * @author xjunz 2023/09/26 12 | */ 13 | abstract class ArgumentAction : Action() { 14 | 15 | override suspend fun apply(runtime: TaskRuntime): AppletResult { 16 | val args = Array(values.size + references.size) { 17 | getArgument(it, runtime) 18 | } 19 | return doAction(args, runtime) 20 | } 21 | 22 | abstract suspend fun doAction(args: Array, runtime: TaskRuntime): AppletResult 23 | } -------------------------------------------------------------------------------- /tasker-engine/src/main/java/top/xjunz/tasker/engine/applet/action/Break.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.engine.applet.action 6 | 7 | import top.xjunz.tasker.engine.applet.base.AppletResult 8 | import top.xjunz.tasker.engine.runtime.TaskRuntime 9 | 10 | /** 11 | * @author xjunz 2023/01/15 12 | */ 13 | class Break : ArgumentAction() { 14 | 15 | override suspend fun doAction(args: Array, runtime: TaskRuntime): AppletResult { 16 | runtime.currentLoop?.shouldBreak = true 17 | return AppletResult.EMPTY_SUCCESS 18 | } 19 | } -------------------------------------------------------------------------------- /tasker-engine/src/main/java/top/xjunz/tasker/engine/applet/action/Continue.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.engine.applet.action 6 | 7 | import top.xjunz.tasker.engine.applet.base.AppletResult 8 | import top.xjunz.tasker.engine.runtime.TaskRuntime 9 | 10 | /** 11 | * @author xjunz 2023/03/16 12 | */ 13 | class Continue : ArgumentAction() { 14 | 15 | override suspend fun doAction(args: Array, runtime: TaskRuntime): AppletResult { 16 | runtime.currentLoop?.shouldContinue = true 17 | return AppletResult.EMPTY_SUCCESS 18 | } 19 | } -------------------------------------------------------------------------------- /tasker-engine/src/main/java/top/xjunz/tasker/engine/applet/action/Processor.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.engine.applet.action 6 | 7 | import top.xjunz.tasker.engine.applet.base.AppletResult 8 | import top.xjunz.tasker.engine.runtime.TaskRuntime 9 | 10 | /** 11 | * @author xjunz 2022/11/21 12 | */ 13 | abstract class Processor : ArgumentAction() { 14 | 15 | abstract suspend fun process(args: Array, runtime: TaskRuntime): Result? 16 | 17 | final override suspend fun doAction(args: Array, runtime: TaskRuntime): AppletResult { 18 | val ret = process(args, runtime) 19 | return if (ret != null) AppletResult.succeeded(ret) else AppletResult.EMPTY_FAILURE 20 | } 21 | 22 | } 23 | 24 | fun createProcessor(block: suspend (arg:Array,runtime: TaskRuntime) -> Result?): Processor { 25 | return object : Processor() { 26 | override suspend fun process(args: Array, runtime: TaskRuntime): Result? { 27 | return block(args, runtime) 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /tasker-engine/src/main/java/top/xjunz/tasker/engine/applet/base/Anyway.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.engine.applet.base 6 | 7 | import top.xjunz.tasker.engine.runtime.TaskRuntime 8 | 9 | /** 10 | * @author xjunz 2023/03/15 11 | */ 12 | class Anyway : Do() { 13 | 14 | override var relation: Int = REL_ANYWAY 15 | set(value) { 16 | check(value == REL_ANYWAY) 17 | field = value 18 | } 19 | 20 | override fun shouldBeSkipped(runtime: TaskRuntime): Boolean { 21 | return runtime.ifSuccessful == null 22 | } 23 | } -------------------------------------------------------------------------------- /tasker-engine/src/main/java/top/xjunz/tasker/engine/applet/base/ContainerFlow.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.engine.applet.base 6 | 7 | /** 8 | * @author xjunz 2022/12/14 9 | */ 10 | class ContainerFlow : Flow() { 11 | 12 | override var maxSize: Int = MAX_FLOW_CHILD_COUNT 13 | 14 | override var minSize: Int = 1 15 | 16 | override val supportsAnywayRelation: Boolean 17 | get() { 18 | var p = parent 19 | while (parent != null) { 20 | if (parent is Do) { 21 | return true 22 | } else if (parent is If) { 23 | return false 24 | } 25 | p = p?.parent 26 | } 27 | return false 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /tasker-engine/src/main/java/top/xjunz/tasker/engine/applet/base/ControlFlow.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.engine.applet.base 6 | 7 | /** 8 | * @author xjunz 2022/11/04 9 | */ 10 | abstract class ControlFlow : Flow() { 11 | 12 | override var relation: Int = REL_ANYWAY 13 | set(value) { 14 | check(value == REL_ANYWAY) 15 | field = REL_ANYWAY 16 | } 17 | 18 | final override var isInvertible: Boolean = false 19 | } -------------------------------------------------------------------------------- /tasker-engine/src/main/java/top/xjunz/tasker/engine/applet/base/Do.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.engine.applet.base 6 | 7 | import top.xjunz.tasker.engine.runtime.TaskRuntime 8 | 9 | /** 10 | * @author xjunz 2022/11/03 11 | */ 12 | open class Do : ControlFlow() { 13 | 14 | override var relation: Int = REL_AND 15 | 16 | override fun shouldBeSkipped(runtime: TaskRuntime): Boolean { 17 | return runtime.ifSuccessful != true 18 | } 19 | } -------------------------------------------------------------------------------- /tasker-engine/src/main/java/top/xjunz/tasker/engine/applet/base/DslFlow.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.engine.applet.base 6 | 7 | import top.xjunz.tasker.engine.runtime.TaskRuntime 8 | 9 | /** 10 | * @author xjunz 2022/11/01 11 | */ 12 | internal class DslFlow(private val initialTarget: Any? = null) : RootFlow() { 13 | 14 | override fun onPrepareApply(runtime: TaskRuntime) { 15 | if (initialTarget != null) 16 | runtime.setTarget(initialTarget) 17 | } 18 | } -------------------------------------------------------------------------------- /tasker-engine/src/main/java/top/xjunz/tasker/engine/applet/base/Else.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.engine.applet.base 6 | 7 | import top.xjunz.tasker.engine.runtime.TaskRuntime 8 | 9 | /** 10 | * @author xjunz 2022/11/03 11 | */ 12 | open class Else : Do() { 13 | 14 | // Once the previous result is success, do not execute this flow 15 | override var relation: Int = REL_OR 16 | 17 | /** 18 | * If its previous peer is skipped, do not execute it self. 19 | */ 20 | override fun shouldBeSkipped(runtime: TaskRuntime): Boolean { 21 | return runtime.ifSuccessful != false 22 | } 23 | 24 | override fun onPostApply(runtime: TaskRuntime) { 25 | super.onPostApply(runtime) 26 | runtime.isSuccessful = runtime.ifSuccessful == true 27 | } 28 | } -------------------------------------------------------------------------------- /tasker-engine/src/main/java/top/xjunz/tasker/engine/applet/base/ElseIf.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.engine.applet.base 6 | 7 | import top.xjunz.shared.utils.unsupportedOperation 8 | import top.xjunz.tasker.engine.runtime.TaskRuntime 9 | 10 | /** 11 | * @author xjunz 2022/11/03 12 | */ 13 | class ElseIf : If() { 14 | 15 | override var relation: Int = REL_OR 16 | set(value) { 17 | if (value != REL_OR) unsupportedOperation("ElseIf flow must not have its [isAnd] field true!") 18 | field = value 19 | } 20 | 21 | override fun staticCheckMyself(): Int { 22 | if (requireParent().getOrNull(index - 1) !is Do) { 23 | return StaticError.ERR_ELSEIF_NOT_FOLLOWING_DO 24 | } 25 | return super.staticCheckMyself() 26 | } 27 | 28 | /** 29 | * If its previous peer is skipped, do not execute it self. 30 | */ 31 | override fun shouldBeSkipped(runtime: TaskRuntime): Boolean { 32 | return runtime.ifSuccessful != false 33 | } 34 | } -------------------------------------------------------------------------------- /tasker-engine/src/main/java/top/xjunz/tasker/engine/applet/base/If.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.engine.applet.base 6 | 7 | import top.xjunz.tasker.engine.runtime.TaskRuntime 8 | 9 | /** 10 | * @author xjunz 2022/08/11 11 | */ 12 | open class If : ControlFlow() { 13 | 14 | override fun staticCheckMyself(): Int { 15 | if (requireParent().getOrNull(index + 1)?.relation == REL_ANYWAY) { 16 | return StaticError.ERR_IF_NOT_FOLLOWED_BY_DO 17 | } 18 | return super.staticCheckMyself() 19 | } 20 | 21 | override fun onSkipped(runtime: TaskRuntime) { 22 | super.onSkipped(runtime) 23 | runtime.ifSuccessful = null 24 | } 25 | 26 | override fun onPostApply(runtime: TaskRuntime) { 27 | super.onPostApply(runtime) 28 | runtime.ifSuccessful = runtime.isSuccessful 29 | } 30 | } -------------------------------------------------------------------------------- /tasker-engine/src/main/java/top/xjunz/tasker/engine/applet/base/Loop.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.engine.applet.base 6 | 7 | import top.xjunz.tasker.engine.runtime.TaskRuntime 8 | 9 | /** 10 | * @author xjunz 2023/03/16 11 | */ 12 | abstract class Loop : Flow() { 13 | 14 | override val supportsAnywayRelation: Boolean = true 15 | 16 | var shouldBreak = false 17 | 18 | var shouldContinue = false 19 | 20 | protected var currentCount: Int = 0 21 | 22 | override fun onPrepareApply(runtime: TaskRuntime) { 23 | super.onPrepareApply(runtime) 24 | currentCount = 0 25 | runtime.currentLoop = this 26 | } 27 | 28 | override fun onPostApply(runtime: TaskRuntime) { 29 | super.onPostApply(runtime) 30 | runtime.currentLoop = null 31 | shouldBreak = false 32 | } 33 | 34 | override suspend fun applyFlow(runtime: TaskRuntime): AppletResult { 35 | val result = super.applyFlow(runtime) 36 | shouldContinue = false 37 | return result 38 | } 39 | } -------------------------------------------------------------------------------- /tasker-engine/src/main/java/top/xjunz/tasker/engine/applet/base/Then.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.engine.applet.base 6 | 7 | /** 8 | * [Do] with another name which does not following an [If]. 9 | * 10 | * @author xjunz 2023/09/13 11 | */ 12 | class Then : Do() -------------------------------------------------------------------------------- /tasker-engine/src/main/java/top/xjunz/tasker/engine/applet/base/When.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.engine.applet.base 6 | 7 | import top.xjunz.tasker.engine.runtime.TaskRuntime 8 | 9 | /** 10 | * @author xjunz 2022/08/11 11 | */ 12 | open class When : ControlFlow() { 13 | 14 | override val minSize: Int = 1 15 | 16 | override val requiredIndex: Int = 1 17 | 18 | override fun staticCheckMyself(): Int { 19 | if (requireParent().getOrNull(index + 1) == null) { 20 | return StaticError.ERR_WHEN_NO_FELLOW 21 | } 22 | return super.staticCheckMyself() 23 | } 24 | 25 | override fun onPostApply(runtime: TaskRuntime) { 26 | super.onPostApply(runtime) 27 | runtime.ifSuccessful = runtime.isSuccessful 28 | if (!runtime.isSuccessful) { 29 | runtime.shouldStop = true 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /tasker-engine/src/main/java/top/xjunz/tasker/engine/applet/criterion/DslCriterion.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.engine.applet.criterion 6 | 7 | import top.xjunz.tasker.engine.applet.base.AppletResult 8 | 9 | /** 10 | * @author xjunz 2022/08/14 11 | */ 12 | internal class DslCriterion : Criterion() { 13 | 14 | lateinit var matcher: ((T, V) -> Boolean) 15 | 16 | override fun matchTarget(target: T, value: V): AppletResult { 17 | return AppletResult.resultOf(target) { 18 | matcher(it, value) 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /tasker-engine/src/main/java/top/xjunz/tasker/engine/applet/factory/AppletFactory.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.engine.applet.factory 6 | 7 | import top.xjunz.tasker.engine.applet.base.Applet 8 | 9 | /** 10 | * @author xjunz 2022/10/28 11 | */ 12 | interface AppletFactory { 13 | 14 | fun createAppletById(id: Int, compatMode: Boolean): Applet 15 | } -------------------------------------------------------------------------------- /tasker-engine/src/main/java/top/xjunz/tasker/engine/dto/AppletChecksum.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.engine.dto 6 | 7 | import top.xjunz.tasker.engine.task.XTask 8 | import java.util.zip.CRC32 9 | 10 | /** 11 | * @author xjunz 2022/12/22 12 | */ 13 | object AppletChecksum { 14 | 15 | fun calculateChecksum(appletDto: AppletDTO, metadata: XTask.Metadata): Long { 16 | val crc32 = CRC32() 17 | appletDto.calculateChecksum(crc32, metadata.version < 16) 18 | crc32.update(metadata.title.toByteArray()) 19 | metadata.description?.let { 20 | crc32.update(it.toByteArray()) 21 | } 22 | crc32.update(metadata.taskType) 23 | return crc32.value 24 | } 25 | 26 | fun XTaskDTO.calculateChecksum(): Long { 27 | return calculateChecksum(flow, metadata) 28 | } 29 | } -------------------------------------------------------------------------------- /tasker-engine/src/main/java/top/xjunz/tasker/engine/runtime/Referent.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.engine.runtime 6 | 7 | import top.xjunz.tasker.engine.applet.base.AppletResult 8 | 9 | /** 10 | * @author xjunz 2023/02/12 11 | */ 12 | interface Referent { 13 | 14 | fun getReferredValue(which: Int, runtime: TaskRuntime): Any? { 15 | throw NullPointerException("Field $which is not found!") 16 | } 17 | 18 | fun asResult(): AppletResult { 19 | return AppletResult.succeeded(this) 20 | } 21 | } -------------------------------------------------------------------------------- /tasker-engine/src/main/java/top/xjunz/tasker/engine/task/EventDispatcher.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.engine.task 6 | 7 | import androidx.collection.ArraySet 8 | import top.xjunz.shared.ktx.casted 9 | import top.xjunz.tasker.engine.runtime.Event 10 | 11 | /** 12 | * @author xjunz 2022/12/04 13 | */ 14 | abstract class EventDispatcher { 15 | 16 | private val callbacks = ArraySet() 17 | 18 | abstract fun destroy() 19 | 20 | abstract fun onRegistered() 21 | 22 | open fun addCallback(callback: Callback) { 23 | callbacks.add(callback) 24 | } 25 | 26 | open fun removeCallback(callback: Callback) { 27 | callbacks.remove(callback) 28 | } 29 | 30 | fun dispatchEvents(vararg events: Event) { 31 | callbacks.forEach { 32 | it.onEvents(events.casted()) 33 | } 34 | } 35 | 36 | fun interface Callback { 37 | 38 | fun onEvents(events: Array) 39 | 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /tasker-engine/src/main/java/top/xjunz/tasker/engine/task/TaskScheduler.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.engine.task 6 | 7 | import kotlinx.coroutines.CoroutineScope 8 | import kotlinx.coroutines.cancel 9 | 10 | /** 11 | * @author xjunz 2022/12/04 12 | */ 13 | abstract class TaskScheduler : CoroutineScope { 14 | 15 | protected abstract val taskType: Int 16 | 17 | var isSuppressed: Boolean = false 18 | set(value) { 19 | field = value 20 | if (value) { 21 | suppressAll() 22 | } 23 | } 24 | 25 | protected abstract fun scheduleTasks( 26 | tasks: List, arg: Arg, listener: XTask.TaskStateListener? = null 27 | ) 28 | 29 | abstract fun suppressAll() 30 | 31 | /** 32 | * After shutdown, do not use this object anymore. 33 | */ 34 | open fun shutdown() { 35 | cancel() 36 | } 37 | } -------------------------------------------------------------------------------- /tasker-engine/src/test/java/top/xjunz/tasker/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker 6 | 7 | import org.junit.Assert.assertEquals 8 | import org.junit.Test 9 | 10 | /** 11 | * Example local unit test, which will execute on the development machine (host). 12 | * 13 | * See [testing documentation](http://d.android.com/tools/testing). 14 | */ 15 | class ExampleUnitTest { 16 | @Test 17 | fun addition_isCorrect() { 18 | assertEquals(4, 2 + 2) 19 | } 20 | 21 | @Test 22 | fun testCastNullable() { 23 | val a: Any? = null 24 | println(a as Int?) 25 | println(a as? Int) 26 | } 27 | } -------------------------------------------------------------------------------- /tasker-engine/src/test/java/top/xjunz/tasker/engine/dto/AppletDTOTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 xjunz. All rights reserved. 3 | */ 4 | 5 | package top.xjunz.tasker.engine.dto 6 | 7 | import org.junit.Test 8 | 9 | /** 10 | * @author xjunz 2022/10/28 11 | */ 12 | internal class AppletDTOTest { 13 | 14 | @Test 15 | fun testFlowApply() { 16 | } 17 | } -------------------------------------------------------------------------------- /ui-automator/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /ui-automator/README.md: -------------------------------------------------------------------------------- 1 | # Modifications of the androidx-uiautomator library 2 | 3 | > We've borrowed and modified the source codes of ***'androidx.test.uiautomator:uiautomator:2.2.0'*** to implement certain requirements. We are doing our best to minify the modifications in order to reduce the cost of later maintance. 4 | > 5 | > Here shows how we've modified the source codes. 6 | 7 | ## Deleted files 8 | 9 | `androidx/test/uiautomator/UiAutomatorInstrumentationTestRunner.java` 10 | 11 | `androidx/test/uiautomator/UiAutomatorTestCase.java` 12 | 13 | -------------------------------------------------------------------------------- /ui-automator/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.library' 3 | id 'kotlin-android' 4 | } 5 | 6 | android { 7 | compileSdk compile_sdk_version 8 | 9 | defaultConfig { 10 | minSdk min_sdk_version 11 | targetSdk target_sdk_version 12 | 13 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 14 | consumerProguardFiles "consumer-rules.pro" 15 | } 16 | 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | compileOptions { 24 | sourceCompatibility JavaVersion.VERSION_1_8 25 | targetCompatibility JavaVersion.VERSION_1_8 26 | } 27 | namespace 'androidx.test.uiautomator' 28 | } 29 | 30 | dependencies { 31 | androidTestImplementation 'androidx.test.ext:junit:1.1.5' 32 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' 33 | } -------------------------------------------------------------------------------- /ui-automator/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjunz/AutoTask/50efc671a84425bf1f9f38d42b3238b3a055467c/ui-automator/consumer-rules.pro -------------------------------------------------------------------------------- /ui-automator/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 -------------------------------------------------------------------------------- /ui-automator/src/androidTest/java/androidx/test/uiautomator/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package androidx.test.uiautomator; 6 | 7 | import static org.junit.Assert.assertEquals; 8 | 9 | import android.content.Context; 10 | 11 | import androidx.test.ext.junit.runners.AndroidJUnit4; 12 | import androidx.test.platform.app.InstrumentationRegistry; 13 | 14 | import org.junit.Test; 15 | import org.junit.runner.RunWith; 16 | 17 | /** 18 | * Instrumented test, which will execute on an Android device. 19 | * 20 | * @see Testing documentation 21 | */ 22 | @RunWith(AndroidJUnit4.class) 23 | public class ExampleInstrumentedTest { 24 | @Test 25 | public void useAppContext() { 26 | // Context of the app under test. 27 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 28 | assertEquals("androidx.test.uiautomator.test", appContext.getPackageName()); 29 | } 30 | } -------------------------------------------------------------------------------- /ui-automator/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ui-automator/src/main/java/androidx/test/uiautomator/Condition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package androidx.test.uiautomator; 6 | 7 | /** Abstract class which represents a condition to be satisfied. */ 8 | abstract class Condition { 9 | 10 | /** 11 | * Applies the given arguments against this condition. Returns a non-null, non-false result if 12 | * the condition is satisfied. 13 | */ 14 | abstract R apply(T args); 15 | } 16 | -------------------------------------------------------------------------------- /ui-automator/src/main/java/androidx/test/uiautomator/Direction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package androidx.test.uiautomator; 6 | 7 | /** 8 | * An enumeration used to specify the primary direction of certain gestures. 9 | */ 10 | public enum Direction { 11 | LEFT, RIGHT, UP, DOWN; 12 | 13 | private Direction mOpposite; 14 | 15 | static { 16 | LEFT.mOpposite = RIGHT; 17 | RIGHT.mOpposite = LEFT; 18 | UP.mOpposite = DOWN; 19 | DOWN.mOpposite = UP; 20 | } 21 | 22 | public static final Direction[] ALL_DIRECTIONS = { 23 | Direction.LEFT, Direction.UP, Direction.RIGHT, Direction.DOWN}; 24 | 25 | /** 26 | * Returns the reverse of the given direction. 27 | */ 28 | public static Direction reverse(Direction direction) { 29 | return direction.mOpposite; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ui-automator/src/main/java/androidx/test/uiautomator/EventCondition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package androidx.test.uiautomator; 6 | 7 | import android.view.accessibility.AccessibilityEvent; 8 | 9 | /** 10 | * An {@link EventCondition} is a condition which depends on an event or series of events having 11 | * occurred. 12 | */ 13 | public abstract class EventCondition extends Condition { 14 | abstract Boolean apply(AccessibilityEvent event); 15 | 16 | abstract R getResult(); 17 | } 18 | -------------------------------------------------------------------------------- /ui-automator/src/main/java/androidx/test/uiautomator/IAutomationSupport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package androidx.test.uiautomator; 6 | 7 | import android.os.Bundle; 8 | 9 | /** 10 | * Provides auxiliary support for running test cases 11 | * 12 | * @since API Level 16 13 | */ 14 | public interface IAutomationSupport { 15 | 16 | /** 17 | * Allows the running test cases to send out interim status 18 | * 19 | * @param resultCode 20 | * @param status status report, consisting of key value pairs 21 | * @since API Level 16 22 | */ 23 | public void sendStatus(int resultCode, Bundle status); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /ui-automator/src/main/java/androidx/test/uiautomator/InstrumentationAutomationSupport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package androidx.test.uiautomator; 6 | 7 | import android.app.Instrumentation; 8 | import android.os.Bundle; 9 | 10 | /** 11 | * A wrapper around {@link Instrumentation} to provide sendStatus function 12 | * 13 | * Provided for backwards compatibility purpose. New code should use 14 | * {@link Instrumentation#sendStatus(int, Bundle)} instead. 15 | * 16 | */ 17 | class InstrumentationAutomationSupport implements IAutomationSupport { 18 | 19 | private Instrumentation mInstrumentation; 20 | 21 | InstrumentationAutomationSupport(Instrumentation instrumentation) { 22 | mInstrumentation = instrumentation; 23 | } 24 | 25 | @Override 26 | public void sendStatus(int resultCode, Bundle status) { 27 | mInstrumentation.sendStatus(resultCode, status); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ui-automator/src/main/java/androidx/test/uiautomator/SearchCondition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package androidx.test.uiautomator; 6 | 7 | /** A {@link SearchCondition} is a condition that is satisfied by searching for UI elements. */ 8 | public abstract class SearchCondition extends Condition { 9 | } 10 | -------------------------------------------------------------------------------- /ui-automator/src/main/java/androidx/test/uiautomator/Searchable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package androidx.test.uiautomator; 6 | 7 | import java.util.List; 8 | 9 | /** The Searchable interface represents an object that can be searched for matching UI elements. */ 10 | interface Searchable { 11 | 12 | /** Returns whether there is a match for the given {@code selector} criteria. */ 13 | public boolean hasObject(BySelector selector); 14 | 15 | /** Returns the first object to match the {@code selector} criteria. */ 16 | public UiObject2 findObject(BySelector selector); 17 | 18 | /** Returns all objects that match the {@code selector} criteria. */ 19 | public List findObjects(BySelector selector); 20 | } 21 | -------------------------------------------------------------------------------- /ui-automator/src/main/java/androidx/test/uiautomator/StaleObjectException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package androidx.test.uiautomator; 6 | 7 | /** 8 | * A {@link StaleObjectException} exception is thrown when a {@link UiObject2} is used after the 9 | * underlying {@link android.view.View} has been destroyed. In this case, it is necessary to call 10 | * {@link UiDevice#findObject(BySelector)} to obtain a new {@link UiObject2} instance. 11 | */ 12 | public class StaleObjectException extends RuntimeException { 13 | } 14 | -------------------------------------------------------------------------------- /ui-automator/src/main/java/androidx/test/uiautomator/UiObject2Condition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package androidx.test.uiautomator; 6 | 7 | /** 8 | * A {@link UiObject2Condition} is a condition which is satisfied when a {@link UiObject2} is in a 9 | * particular state. 10 | */ 11 | public abstract class UiObject2Condition extends Condition { 12 | } 13 | -------------------------------------------------------------------------------- /ui-automator/src/main/java/androidx/test/uiautomator/UiObjectNotFoundException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package androidx.test.uiautomator; 6 | 7 | /** 8 | * Generated in test runs when a {@link UiSelector} selector could not be matched 9 | * to any UI element displayed. 10 | * @since API Level 16 11 | */ 12 | public class UiObjectNotFoundException extends Exception { 13 | 14 | private static final long serialVersionUID = 1L; 15 | 16 | /** 17 | * @since API Level 16 18 | **/ 19 | public UiObjectNotFoundException(String msg) { 20 | super(msg); 21 | } 22 | 23 | /** 24 | * @since API Level 16 25 | **/ 26 | public UiObjectNotFoundException(String detailMessage, Throwable throwable) { 27 | super(detailMessage, throwable); 28 | } 29 | 30 | /** 31 | * @since API Level 16 32 | **/ 33 | public UiObjectNotFoundException(Throwable throwable) { 34 | super(throwable); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ui-automator/src/test/java/androidx/test/uiautomator/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 xjunz. All rights reserved. 3 | */ 4 | 5 | package androidx.test.uiautomator; 6 | 7 | import static org.junit.Assert.assertEquals; 8 | 9 | import org.junit.Test; 10 | 11 | /** 12 | * Example local unit test, which will execute on the development machine (host). 13 | * 14 | * @see Testing documentation 15 | */ 16 | public class ExampleUnitTest { 17 | @Test 18 | public void addition_isCorrect() { 19 | assertEquals(4, 2 + 2); 20 | } 21 | } --------------------------------------------------------------------------------