├── .gitignore ├── .idea ├── assetWizardSettings.xml ├── codeStyles │ └── Project.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── vcs.xml └── workspace.xml.template ├── .project ├── .settings └── org.eclipse.buildship.core.prefs ├── README.md ├── additional_files └── frameworks │ └── base │ └── packages │ └── SystemUI │ └── res │ └── drawable │ ├── ltweaks_nav_dpad_left.xml │ └── ltweaks_nav_dpad_right.xml ├── api ├── .classpath ├── .gitignore ├── .project ├── .settings │ ├── org.eclipse.buildship.core.prefs │ └── org.eclipse.jdt.core.prefs ├── build.gradle ├── libs │ └── android.jar └── src │ └── main │ └── java │ ├── android │ ├── app │ │ └── ActivityThread.java │ ├── content │ │ └── pm │ │ │ └── PackageParser.java │ ├── os │ │ ├── ServiceManager.java │ │ └── SystemProperties.java │ └── webkit │ │ └── WebViewProviderInfo.java │ ├── com │ └── android │ │ └── internal │ │ ├── net │ │ └── VpnConfig.java │ │ ├── telephony │ │ ├── Phone.java │ │ └── PhoneFactory.java │ │ └── view │ │ └── menu │ │ └── MenuBuilder.java │ ├── dalvik │ └── system │ │ └── VMRuntime.java │ └── li │ └── lingfeng │ └── ltsystem │ ├── ILTweaks.java │ ├── ILTweaksBridge.java │ ├── ILTweaksMethods.java │ ├── LTHelper.java │ ├── LTweaksBridge.java │ └── LTweaksImpl.java ├── app ├── .classpath ├── .gitignore ├── .project ├── .settings │ └── org.eclipse.buildship.core.prefs ├── build.gradle ├── libs │ └── indeterminate-checkbox.aar ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── li │ │ └── lingfeng │ │ └── ltsystem │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── aidl │ │ └── li │ │ │ └── lingfeng │ │ │ └── ltsystem │ │ │ ├── ILTPref.aidl │ │ │ └── ILTPrefListener.aidl │ ├── assets │ │ └── overture │ │ │ ├── china_ip_list.txt │ │ │ ├── domain_alternative │ │ │ ├── domain_primary │ │ │ ├── overture │ │ │ ├── overture.conf │ │ │ └── version.txt │ ├── java │ │ ├── com │ │ │ └── github │ │ │ │ └── mikephil │ │ │ │ └── charting │ │ │ │ ├── animation │ │ │ │ ├── ChartAnimator.java │ │ │ │ ├── Easing.java │ │ │ │ └── EasingFunction.java │ │ │ │ ├── buffer │ │ │ │ ├── AbstractBuffer.java │ │ │ │ ├── BarBuffer.java │ │ │ │ └── HorizontalBarBuffer.java │ │ │ │ ├── charts │ │ │ │ ├── BarChart.java │ │ │ │ ├── BarLineChartBase.java │ │ │ │ ├── BubbleChart.java │ │ │ │ ├── CandleStickChart.java │ │ │ │ ├── Chart.java │ │ │ │ ├── CombinedChart.java │ │ │ │ ├── HorizontalBarChart.java │ │ │ │ ├── LineChart.java │ │ │ │ ├── PieChart.java │ │ │ │ ├── PieRadarChartBase.java │ │ │ │ ├── RadarChart.java │ │ │ │ └── ScatterChart.java │ │ │ │ ├── components │ │ │ │ ├── AxisBase.java │ │ │ │ ├── ComponentBase.java │ │ │ │ ├── Description.java │ │ │ │ ├── IMarker.java │ │ │ │ ├── Legend.java │ │ │ │ ├── LegendEntry.java │ │ │ │ ├── LimitLine.java │ │ │ │ ├── MarkerImage.java │ │ │ │ ├── MarkerView.java │ │ │ │ ├── XAxis.java │ │ │ │ └── YAxis.java │ │ │ │ ├── data │ │ │ │ ├── BarData.java │ │ │ │ ├── BarDataSet.java │ │ │ │ ├── BarEntry.java │ │ │ │ ├── BarLineScatterCandleBubbleData.java │ │ │ │ ├── BarLineScatterCandleBubbleDataSet.java │ │ │ │ ├── BaseDataSet.java │ │ │ │ ├── BaseEntry.java │ │ │ │ ├── BubbleData.java │ │ │ │ ├── BubbleDataSet.java │ │ │ │ ├── BubbleEntry.java │ │ │ │ ├── CandleData.java │ │ │ │ ├── CandleDataSet.java │ │ │ │ ├── CandleEntry.java │ │ │ │ ├── ChartData.java │ │ │ │ ├── CombinedData.java │ │ │ │ ├── DataSet.java │ │ │ │ ├── Entry.java │ │ │ │ ├── LineData.java │ │ │ │ ├── LineDataSet.java │ │ │ │ ├── LineRadarDataSet.java │ │ │ │ ├── LineScatterCandleRadarDataSet.java │ │ │ │ ├── PieData.java │ │ │ │ ├── PieDataSet.java │ │ │ │ ├── PieEntry.java │ │ │ │ ├── RadarData.java │ │ │ │ ├── RadarDataSet.java │ │ │ │ ├── RadarEntry.java │ │ │ │ ├── ScatterData.java │ │ │ │ ├── ScatterDataSet.java │ │ │ │ └── filter │ │ │ │ │ └── Approximator.java │ │ │ │ ├── exception │ │ │ │ └── DrawingDataSetNotCreatedException.java │ │ │ │ ├── formatter │ │ │ │ ├── ColorFormatter.java │ │ │ │ ├── DefaultAxisValueFormatter.java │ │ │ │ ├── DefaultFillFormatter.java │ │ │ │ ├── DefaultValueFormatter.java │ │ │ │ ├── IAxisValueFormatter.java │ │ │ │ ├── IFillFormatter.java │ │ │ │ ├── IValueFormatter.java │ │ │ │ ├── IndexAxisValueFormatter.java │ │ │ │ ├── LargeValueFormatter.java │ │ │ │ ├── PercentFormatter.java │ │ │ │ └── StackedValueFormatter.java │ │ │ │ ├── highlight │ │ │ │ ├── BarHighlighter.java │ │ │ │ ├── ChartHighlighter.java │ │ │ │ ├── CombinedHighlighter.java │ │ │ │ ├── Highlight.java │ │ │ │ ├── HorizontalBarHighlighter.java │ │ │ │ ├── IHighlighter.java │ │ │ │ ├── PieHighlighter.java │ │ │ │ ├── PieRadarHighlighter.java │ │ │ │ ├── RadarHighlighter.java │ │ │ │ └── Range.java │ │ │ │ ├── interfaces │ │ │ │ ├── dataprovider │ │ │ │ │ ├── BarDataProvider.java │ │ │ │ │ ├── BarLineScatterCandleBubbleDataProvider.java │ │ │ │ │ ├── BubbleDataProvider.java │ │ │ │ │ ├── CandleDataProvider.java │ │ │ │ │ ├── ChartInterface.java │ │ │ │ │ ├── CombinedDataProvider.java │ │ │ │ │ ├── LineDataProvider.java │ │ │ │ │ └── ScatterDataProvider.java │ │ │ │ └── datasets │ │ │ │ │ ├── IBarDataSet.java │ │ │ │ │ ├── IBarLineScatterCandleBubbleDataSet.java │ │ │ │ │ ├── IBubbleDataSet.java │ │ │ │ │ ├── ICandleDataSet.java │ │ │ │ │ ├── IDataSet.java │ │ │ │ │ ├── ILineDataSet.java │ │ │ │ │ ├── ILineRadarDataSet.java │ │ │ │ │ ├── ILineScatterCandleRadarDataSet.java │ │ │ │ │ ├── IPieDataSet.java │ │ │ │ │ ├── IRadarDataSet.java │ │ │ │ │ └── IScatterDataSet.java │ │ │ │ ├── jobs │ │ │ │ ├── AnimatedMoveViewJob.java │ │ │ │ ├── AnimatedViewPortJob.java │ │ │ │ ├── AnimatedZoomJob.java │ │ │ │ ├── MoveViewJob.java │ │ │ │ ├── ViewPortJob.java │ │ │ │ └── ZoomJob.java │ │ │ │ ├── listener │ │ │ │ ├── BarLineChartTouchListener.java │ │ │ │ ├── ChartTouchListener.java │ │ │ │ ├── OnChartGestureListener.java │ │ │ │ ├── OnChartValueSelectedListener.java │ │ │ │ ├── OnDrawLineChartTouchListener.java │ │ │ │ ├── OnDrawListener.java │ │ │ │ └── PieRadarChartTouchListener.java │ │ │ │ ├── matrix │ │ │ │ └── Vector3.java │ │ │ │ ├── renderer │ │ │ │ ├── AxisRenderer.java │ │ │ │ ├── BarChartRenderer.java │ │ │ │ ├── BarLineScatterCandleBubbleRenderer.java │ │ │ │ ├── BubbleChartRenderer.java │ │ │ │ ├── CandleStickChartRenderer.java │ │ │ │ ├── CombinedChartRenderer.java │ │ │ │ ├── DataRenderer.java │ │ │ │ ├── HorizontalBarChartRenderer.java │ │ │ │ ├── LegendRenderer.java │ │ │ │ ├── LineChartRenderer.java │ │ │ │ ├── LineRadarRenderer.java │ │ │ │ ├── LineScatterCandleRadarRenderer.java │ │ │ │ ├── PieChartRenderer.java │ │ │ │ ├── RadarChartRenderer.java │ │ │ │ ├── Renderer.java │ │ │ │ ├── ScatterChartRenderer.java │ │ │ │ ├── XAxisRenderer.java │ │ │ │ ├── XAxisRendererHorizontalBarChart.java │ │ │ │ ├── XAxisRendererRadarChart.java │ │ │ │ ├── YAxisRenderer.java │ │ │ │ ├── YAxisRendererHorizontalBarChart.java │ │ │ │ ├── YAxisRendererRadarChart.java │ │ │ │ └── scatter │ │ │ │ │ ├── ChevronDownShapeRenderer.java │ │ │ │ │ ├── ChevronUpShapeRenderer.java │ │ │ │ │ ├── CircleShapeRenderer.java │ │ │ │ │ ├── CrossShapeRenderer.java │ │ │ │ │ ├── IShapeRenderer.java │ │ │ │ │ ├── SquareShapeRenderer.java │ │ │ │ │ ├── TriangleShapeRenderer.java │ │ │ │ │ └── XShapeRenderer.java │ │ │ │ └── utils │ │ │ │ ├── ColorTemplate.java │ │ │ │ ├── EntryXComparator.java │ │ │ │ ├── FSize.java │ │ │ │ ├── FileUtils.java │ │ │ │ ├── HorizontalViewPortHandler.java │ │ │ │ ├── MPPointD.java │ │ │ │ ├── MPPointF.java │ │ │ │ ├── ObjectPool.java │ │ │ │ ├── Transformer.java │ │ │ │ ├── TransformerHorizontalBarChart.java │ │ │ │ ├── Utils.java │ │ │ │ └── ViewPortHandler.java │ │ └── li │ │ │ └── lingfeng │ │ │ └── ltsystem │ │ │ ├── LTPref.java │ │ │ ├── LTPrefService.java │ │ │ ├── LoadAlways.java │ │ │ ├── LoaderBase.java │ │ │ ├── MainActivity.java │ │ │ ├── activities │ │ │ ├── BilibiliActivity.java │ │ │ ├── ChromeIncognitoActivity.java │ │ │ ├── GoMarketActivity.java │ │ │ ├── ImageSearchActivity.java │ │ │ ├── ImageShareRedirectActivity.java │ │ │ ├── JDActivity.java │ │ │ ├── JDHistoryLayout.java │ │ │ ├── ListCheckActivity.java │ │ │ ├── LoadingDialog.java │ │ │ ├── PriceHistoryGrabber.java │ │ │ ├── ProcessTextActivity.java │ │ │ ├── QrCodeActivity.java │ │ │ ├── SelectableTextActivity.java │ │ │ ├── TileActivity.java │ │ │ └── WeChatBrowserActivity.java │ │ │ ├── fragments │ │ │ ├── BasePrefFragment.java │ │ │ ├── CommunicationPrefFragment.java │ │ │ ├── EntertainmentPrefFragment.java │ │ │ ├── GooglePrefFragment.java │ │ │ ├── ShoppingPrefFragment.java │ │ │ ├── SystemPrefFragment.java │ │ │ ├── base │ │ │ │ ├── Extra.java │ │ │ │ └── TimePickerPreference.java │ │ │ └── sub │ │ │ │ └── system │ │ │ │ ├── AppListProvider.java │ │ │ │ ├── ShareFilterDataProvider.java │ │ │ │ └── TextActionDataProvider.java │ │ │ ├── prefs │ │ │ ├── ActivityRequestCode.java │ │ │ ├── ClassNames.java │ │ │ ├── IntentActions.java │ │ │ ├── NotificationId.java │ │ │ ├── PackageNames.java │ │ │ ├── PreferenceStore.java │ │ │ └── Prefs.java │ │ │ ├── services │ │ │ ├── AdbWireless.java │ │ │ ├── BootReceiver.java │ │ │ ├── BrightnessTile.java │ │ │ ├── CellLocationService.java │ │ │ ├── CopyToShareService.java │ │ │ ├── RemoteLog.java │ │ │ ├── RemoteShell.java │ │ │ ├── ResourceProvider.java │ │ │ ├── Switch4G3G.java │ │ │ └── base │ │ │ │ └── ForegroundService.java │ │ │ ├── tweaks │ │ │ ├── TweakBase.java │ │ │ ├── TweakMoveTaskToBack.java │ │ │ ├── communication │ │ │ │ ├── QQChatBackground.java │ │ │ │ ├── QQExternalBrowser.java │ │ │ │ ├── QQShareImage.java │ │ │ │ ├── TTRssArticleOpenInBrowserMenu.java │ │ │ │ ├── TTRssDarkenStartingWindow.java │ │ │ │ ├── TTRssDisableArticlePager.java │ │ │ │ ├── TTRssRefreshMenu.java │ │ │ │ ├── TTRssToolbarNoHide.java │ │ │ │ ├── TelegramDarkenStartingWindow.java │ │ │ │ ├── TelegramDarkenVideoBackground.java │ │ │ │ ├── TelegramEditTextNoFocusFirst.java │ │ │ │ ├── TelegramHideSticker.java │ │ │ │ ├── TelegramMessageFilter.java │ │ │ │ ├── TelegramOpenUrlWithoutConfirmation.java │ │ │ │ ├── TelegramRemoveFloatingButton.java │ │ │ │ ├── TelegramSeekbarHideDelay.java │ │ │ │ ├── TelegramSwipeSeekVideo.java │ │ │ │ ├── WeChatBrowser.java │ │ │ │ ├── WeChatClassicTheme.java │ │ │ │ ├── WeChatExpandSubscribedList.java │ │ │ │ ├── WeChatExternalBrowser.java │ │ │ │ ├── WeChatFingerprint.java │ │ │ │ ├── WeChatIncomingRingtone.java │ │ │ │ ├── WeChatMapDaytimeMode.java │ │ │ │ ├── WeChatMuteAnnoyingNotification.java │ │ │ │ ├── WeChatRemoveBottomBar.java │ │ │ │ ├── WeChatScanQr.java │ │ │ │ ├── WeChatShareImage.java │ │ │ │ └── WeiboShareMoveTaskToBack.java │ │ │ ├── entertainment │ │ │ │ ├── BilibiliBestQuality.java │ │ │ │ ├── BilibiliCover.java │ │ │ │ ├── BilibiliDanmakuOff.java │ │ │ │ ├── BilibiliDisableSplash.java │ │ │ │ ├── BilibiliDisableTeenModeHint.java │ │ │ │ ├── BilibiliExpandDesc.java │ │ │ │ ├── BilibiliHideFollow.java │ │ │ │ ├── BilibiliKeepBrightness.java │ │ │ │ ├── BilibiliMoveTaskToBack.java │ │ │ │ ├── BilibiliRemoveBottomBar.java │ │ │ │ ├── BilibiliRemoveUpperAd.java │ │ │ │ ├── ComicScreenExternalStorage.java │ │ │ │ ├── ComicScreenNoZipCache.java │ │ │ │ ├── DoubanAds.java │ │ │ │ ├── DoubanMoveTaskToBack.java │ │ │ │ ├── DoubanRemoveBottomBar.java │ │ │ │ ├── DoubanSearch.java │ │ │ │ ├── MXPlayerDanmaku.java │ │ │ │ ├── MXPlayerExternalStorage.java │ │ │ │ ├── PicaComicAds.java │ │ │ │ ├── SteamBase.java │ │ │ │ ├── SteamChinese.java │ │ │ │ ├── SteamDatabase.java │ │ │ │ ├── SteamGoReviews.java │ │ │ │ ├── SteamGoTop.java │ │ │ │ ├── SteamShare.java │ │ │ │ └── TachiyomiDarkenStartingWindow.java │ │ │ ├── google │ │ │ │ ├── ChromeArchiveIs.java │ │ │ │ ├── ChromeBase.java │ │ │ │ ├── ChromeCache.java │ │ │ │ ├── ChromeGoTopOrBottom.java │ │ │ │ ├── ChromeIPInfo.java │ │ │ │ ├── ChromeIncognitoSearch.java │ │ │ │ ├── ChromeOpenWith.java │ │ │ │ ├── ChromeWayback.java │ │ │ │ ├── GoogleMapChinese.java │ │ │ │ ├── GoogleOverlaySearchToBrowser.java │ │ │ │ ├── GooglePhotosHideSuggestiion.java │ │ │ │ ├── GooglePhotosRemoveBottomBar.java │ │ │ │ ├── GooglePhotosShareFix.java │ │ │ │ ├── GooglePlayServicesDismissSystemUpdate.java │ │ │ │ ├── YoutubeDarkenStartingWindow.java │ │ │ │ └── YoutubeRemoveBottomBar.java │ │ │ ├── shopping │ │ │ │ ├── AlipayFingerprint.java │ │ │ │ ├── EleAddressMap.java │ │ │ │ ├── EleRouteShareLink.java │ │ │ │ ├── JDAds.java │ │ │ │ ├── JDBasicShare.java │ │ │ │ ├── JDHistory.java │ │ │ │ ├── JDMiniProgramCopyShareLink.java │ │ │ │ ├── JDMoveTaskToBack.java │ │ │ │ ├── SMZDMSkipSplash.java │ │ │ │ ├── TaobaoAds.java │ │ │ │ └── TaobaoMoveTaskToBack.java │ │ │ └── system │ │ │ │ ├── AppInfo.java │ │ │ │ ├── AppInfoGoAppData.java │ │ │ │ ├── AppInfoGoMarket.java │ │ │ │ ├── AppInfoPackageName.java │ │ │ │ ├── AppListBlock.java │ │ │ │ ├── ChromeWebViewProvider.java │ │ │ │ ├── CopyToShare.java │ │ │ │ ├── Debuggable.java │ │ │ │ ├── DenyAccessPhoneNumber.java │ │ │ │ ├── DirectShareDisable.java │ │ │ │ ├── Doze.java │ │ │ │ ├── DozeOnTheGo.java │ │ │ │ ├── ForceGPURendering.java │ │ │ │ ├── HSPAPSignal.java │ │ │ │ ├── HiddenApiNoExemptions.java │ │ │ │ ├── InputCursorNavControl.java │ │ │ │ ├── LightAmberInDaylight.java │ │ │ │ ├── MiXplorerHighlightVisitedFiles.java │ │ │ │ ├── MiXplorerIgnoreCPUUsageKill.java │ │ │ │ ├── NormalizeTranslateFloatingMenu.java │ │ │ │ ├── NovaLauncherSearchGoChrome.java │ │ │ │ ├── OriginalSelectionActionMode.java │ │ │ │ ├── PreventProcess.java │ │ │ │ ├── QuickEditDarkenStartingWindow.java │ │ │ │ ├── RecentTaskSwipeToKill.java │ │ │ │ ├── SettingsExpandAll.java │ │ │ │ ├── SettingsSuggestionDisable.java │ │ │ │ ├── ShadowsocksDdnsUpdate.java │ │ │ │ ├── ShadowsocksHideVPNInfo.java │ │ │ │ ├── ShadowsocksLinuxKernelRoute.java │ │ │ │ ├── ShadowsocksNetworkValidate.java │ │ │ │ ├── ShadowsocksPrimaryDns.java │ │ │ │ ├── ShadowsocksTransproxy.java │ │ │ │ ├── ShadowsocksUpgradeOverture.java │ │ │ │ ├── ShareFilter.java │ │ │ │ ├── SolidExplorerDarkenStartingWindow.java │ │ │ │ ├── SolidExplorerHighlightVisitedFile.java │ │ │ │ ├── SolidExplorerReplaceStreamingUrl.java │ │ │ │ ├── Switch4G3G.java │ │ │ │ ├── TextActions.java │ │ │ │ ├── TextLongPressToCopy.java │ │ │ │ ├── TextScannerNoCamera.java │ │ │ │ ├── ToastBlock.java │ │ │ │ ├── VolumeButtonOnBrightness.java │ │ │ │ └── WebSearchGoBrowser.java │ │ │ └── utils │ │ │ ├── AESUtils.java │ │ │ ├── Callback.java │ │ │ ├── CircleImageView.java │ │ │ ├── ComponentUtils.java │ │ │ ├── ContextUtils.java │ │ │ ├── IOUtils.java │ │ │ ├── ListMultiChoiceDialog.java │ │ │ ├── Logger.java │ │ │ ├── PackageUtils.java │ │ │ ├── PermissionUtils.java │ │ │ ├── ReflectUtils.java │ │ │ ├── ShareUtils.java │ │ │ ├── Shell.java │ │ │ ├── ShoppingUtils.java │ │ │ ├── SimpleDrawer.java │ │ │ ├── SimpleSnackbar.java │ │ │ ├── Triple.java │ │ │ ├── Utils.java │ │ │ ├── ViewUtils.java │ │ │ └── ZXingUtils.java │ └── res │ │ ├── drawable │ │ ├── ic_3g.xml │ │ ├── ic_4g.xml │ │ ├── ic_add.xml │ │ ├── ic_coin.xml │ │ ├── ic_communication.xml │ │ ├── ic_computer.xml │ │ ├── ic_edit.xml │ │ ├── ic_entertainment.xml │ │ ├── ic_google.xml │ │ ├── ic_incognito.xml │ │ ├── ic_info.xml │ │ ├── ic_qs_brightness_auto_off_alpha.png │ │ ├── ic_qs_signal_hp.xml │ │ ├── ic_quick_settings_adb_wireless_off.xml │ │ ├── ic_quick_settings_adb_wireless_on.xml │ │ ├── ic_search.xml │ │ ├── ic_select_all.xml │ │ ├── ic_shopping.xml │ │ ├── ic_tools.xml │ │ ├── ic_wifi.xml │ │ ├── jd_history_fade_red.xml │ │ ├── jd_history_marker_border.xml │ │ ├── stat_sys_data_fully_connected_hp.xml │ │ └── youdao_dict.png │ │ ├── layout │ │ ├── activity_image_search.xml │ │ ├── activity_jd_history.xml │ │ ├── activity_list_check.xml │ │ ├── activity_qrcode.xml │ │ ├── activity_text_selectable.xml │ │ ├── fragment_list_check.xml │ │ ├── jd_history_marker_view.xml │ │ ├── list_check.xml │ │ └── list_multi_choice.xml │ │ ├── menu │ │ └── menu_main.xml │ │ ├── mipmap-xxxhdpi │ │ ├── ic_go_market.png │ │ ├── ic_image_search.png │ │ ├── ic_launcher.png │ │ ├── ic_launcher_round.png │ │ ├── ic_price_history.png │ │ ├── ic_qrcode_scan.png │ │ └── ic_selectable_text.png │ │ ├── values │ │ ├── arrays.xml │ │ ├── colors.xml │ │ ├── pref_keys.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ └── xml │ │ ├── network_security_config.xml │ │ ├── pref_communication.xml │ │ ├── pref_entertainment.xml │ │ ├── pref_google.xml │ │ ├── pref_headers.xml │ │ ├── pref_shopping.xml │ │ └── pref_system.xml │ └── test │ └── java │ └── li │ └── lingfeng │ └── ltsystem │ └── ExampleUnitTest.java ├── build.gradle ├── common ├── .gitignore ├── build.gradle └── src │ └── main │ └── java │ └── li │ └── lingfeng │ └── ltsystem │ └── common │ ├── Config.java.template │ ├── Logger.java │ └── Utils.java ├── compiler ├── .classpath ├── .gitignore ├── .project ├── .settings │ └── org.eclipse.buildship.core.prefs ├── build.gradle └── src │ └── main │ └── java │ └── li │ └── lingfeng │ └── ltsystem │ └── compiler │ └── Processor.java ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── lib ├── .classpath ├── .gitignore ├── .project ├── .settings │ ├── org.eclipse.buildship.core.prefs │ └── org.eclipse.jdt.core.prefs ├── build.gradle └── src │ └── main │ └── java │ └── li │ └── lingfeng │ └── ltsystem │ └── lib │ ├── MethodsLoad.java │ ├── PreferenceChange.java │ ├── PreferenceClick.java │ ├── PreferenceLoad.java │ └── PreferenceLongClick.java ├── magisk-module-app-template ├── META-INF │ └── com │ │ └── google │ │ └── android │ │ ├── update-binary │ │ └── updater-script ├── customize.sh ├── module.prop ├── post-fs-data.sh ├── sepolicy.rule ├── service.sh ├── system.prop └── system │ └── priv-app │ └── LTweaks │ └── LTweaks.apk ├── magisk-module-template ├── META-INF │ └── com │ │ └── google │ │ └── android │ │ ├── update-binary │ │ └── updater-script ├── customize.sh ├── module.prop ├── post-fs-data.sh ├── service.sh ├── system.prop └── system │ └── placeholder ├── magisk ├── .gitignore ├── build.gradle └── src │ └── main │ └── java │ └── li │ └── lingfeng │ └── ltsystem │ └── magisk │ ├── Magisk.java │ └── MagiskApp.java ├── patcher ├── .gitignore ├── build.gradle └── src │ └── main │ └── java │ └── li │ └── lingfeng │ └── ltsystem │ └── patcher │ ├── ClassUtils.java │ └── Patcher.java ├── revert_changes.sh └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches/ 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | .DS_Store 9 | /build 10 | /captures 11 | .externalNativeBuild 12 | system_keystore/ 13 | magisk-module/ 14 | common/src/main/java/li/lingfeng/ltsystem/common/Config.java 15 | app/release/ 16 | magisk-ltsystem-*.zip 17 | magisk-module-app/ 18 | .idea/jarRepositories.xml 19 | .idea/compiler.xml 20 | -------------------------------------------------------------------------------- /.idea/assetWizardSettings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 25 | 26 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | LTweaksSystem 4 | Project LTweaksSystem created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.buildship.core.gradleprojectbuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.buildship.core.gradleprojectnature 16 | 17 | 18 | -------------------------------------------------------------------------------- /.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | auto.sync=false 2 | build.scans.enabled=false 3 | connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER) 4 | connection.project.dir= 5 | eclipse.preferences.version=1 6 | gradle.user.home= 7 | offline.mode=false 8 | override.workspace.settings=true 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # L Tweaks System 2 | 3 | Due to not satisfied the performance and stability of Xposed, I created this project to implement functions in [L Tweaks](https://github.com/bluesky139/LTweaks). 4 | 5 | This is an advanced implementation on [L Tweaks](https://github.com/bluesky139/LTweaks), you need compile with Android Open Source Project. 6 | 7 | ## Build steps 8 | 9 | * Download AOSP from official or thirdparty, build out system image and flash it to your device, install Magisk and make sure it runs well. 10 | 11 | * Open this project in Android Studio, copy and rename [Config.java.template](https://github.com/bluesky139/LTweaksSystem/blob/master/common/src/main/java/li/lingfeng/ltsystem/common/Config.java.template) to `Config.java`, configure Android system source path and device code name in it. 12 | 13 | * Run `Patcher` project, it will patch AOSP. (You need revert all changes if you have run this patcher before, just revert `/frameworks/base`, `/libcore`, `/frameworks/opt/telephony`, `/packages/apps/Settings`) 14 | 15 | * Build AOSP again. 16 | 17 | * Flash new system image, or run `Magisk` project, it will build out magisk module for modified system frameworks, install it on your device. 18 | 19 | * Use [keytool-importkeypair](https://github.com/getfatday/keytool-importkeypair) to convert your system signature to Android keystore format, create `system_keystore` folder in this project and put keystore into it, run `app` project, it will build out `L Tweaks System` apk, install it. 20 | 21 | * Reboot into recovery, clear dalvik cache. 22 | 23 | * Everything is ready, boot into system, find `L Tweaks System` app, set each preferences that what you want, reboot system/apps, enjoy. 24 | 25 | ## My working environment 26 | 27 | * Android Studio 3.3.2 28 | 29 | * Official AOSP, Android 10.0 30 | 31 | * Device: Pixel 3 32 | -------------------------------------------------------------------------------- /additional_files/frameworks/base/packages/SystemUI/res/drawable/ltweaks_nav_dpad_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | -------------------------------------------------------------------------------- /additional_files/frameworks/base/packages/SystemUI/res/drawable/ltweaks_nav_dpad_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | -------------------------------------------------------------------------------- /api/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /api/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /bin 3 | -------------------------------------------------------------------------------- /api/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | api 4 | Project api created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.buildship.core.gradleprojectbuilder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.buildship.core.gradleprojectnature 22 | 23 | 24 | -------------------------------------------------------------------------------- /api/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | connection.project.dir=.. 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /api/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 3 | org.eclipse.jdt.core.compiler.compliance=1.7 4 | org.eclipse.jdt.core.compiler.source=1.7 5 | -------------------------------------------------------------------------------- /api/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java-library' 2 | 3 | dependencies { 4 | implementation fileTree(include: ['*.jar'], dir: 'libs') 5 | implementation files('libs/android.jar') 6 | } 7 | 8 | sourceCompatibility = "7" 9 | targetCompatibility = "7" 10 | -------------------------------------------------------------------------------- /api/libs/android.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluesky139/LTweaksSystem/662118fadfa9f795d7d9948d0778c66a0b0b2325/api/libs/android.jar -------------------------------------------------------------------------------- /api/src/main/java/android/app/ActivityThread.java: -------------------------------------------------------------------------------- 1 | package android.app; 2 | 3 | public class ActivityThread { 4 | 5 | public static String currentPackageName() { 6 | return null; 7 | } 8 | 9 | public static Application currentApplication() { 10 | return null; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /api/src/main/java/android/content/pm/PackageParser.java: -------------------------------------------------------------------------------- 1 | package android.content.pm; 2 | 3 | import android.content.IntentFilter; 4 | 5 | import java.util.ArrayList; 6 | 7 | /** 8 | * Created by smallville on 2017/3/28. 9 | */ 10 | 11 | public class PackageParser { 12 | public final static class Package { 13 | public String packageName; 14 | public ApplicationInfo applicationInfo; 15 | public final ArrayList activities = new ArrayList(0); 16 | public final ArrayList receivers = new ArrayList(0); 17 | } 18 | 19 | public final static class Activity extends Component { 20 | public final ActivityInfo info = null; 21 | } 22 | 23 | public final static class ActivityIntentInfo extends IntentInfo { 24 | public Activity activity; 25 | } 26 | 27 | public static class Component { 28 | public final ArrayList intents = null; 29 | } 30 | 31 | public static class IntentInfo extends IntentFilter { 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /api/src/main/java/android/os/ServiceManager.java: -------------------------------------------------------------------------------- 1 | package android.os; 2 | 3 | public class ServiceManager { 4 | 5 | public static void addService(String name, IBinder service, boolean allowIsolated) { 6 | } 7 | 8 | public static IBinder getService(String name) { 9 | return null; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /api/src/main/java/android/os/SystemProperties.java: -------------------------------------------------------------------------------- 1 | package android.os; 2 | 3 | public class SystemProperties { 4 | 5 | public static String get(String key) { 6 | return null; 7 | } 8 | 9 | public static String get(String key, String def) { 10 | return null; 11 | } 12 | 13 | public static int getInt(String key, int def) { 14 | return 0; 15 | } 16 | 17 | public static long getLong(String key, long def) { 18 | return 0; 19 | } 20 | 21 | public static boolean getBoolean(String key, boolean def) { 22 | return false; 23 | } 24 | 25 | public static void set(String key, String val) { 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /api/src/main/java/android/webkit/WebViewProviderInfo.java: -------------------------------------------------------------------------------- 1 | package android.webkit; 2 | 3 | public class WebViewProviderInfo { 4 | 5 | public WebViewProviderInfo(String packageName, String description, 6 | boolean availableByDefault, boolean isFallback, String[] signatures) { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /api/src/main/java/com/android/internal/net/VpnConfig.java: -------------------------------------------------------------------------------- 1 | package com.android.internal.net; 2 | 3 | public class VpnConfig { 4 | 5 | public String user; 6 | } 7 | -------------------------------------------------------------------------------- /api/src/main/java/com/android/internal/telephony/Phone.java: -------------------------------------------------------------------------------- 1 | package com.android.internal.telephony; 2 | 3 | import android.os.Message; 4 | 5 | public class Phone { 6 | 7 | public void setPreferredNetworkType(int networkType, Message response) { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /api/src/main/java/com/android/internal/telephony/PhoneFactory.java: -------------------------------------------------------------------------------- 1 | package com.android.internal.telephony; 2 | 3 | public class PhoneFactory { 4 | 5 | public static Phone getDefaultPhone() { 6 | return null; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /api/src/main/java/com/android/internal/view/menu/MenuBuilder.java: -------------------------------------------------------------------------------- 1 | package com.android.internal.view.menu; 2 | 3 | public class MenuBuilder { 4 | 5 | public void onItemsChanged(boolean structureChanged) { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /api/src/main/java/dalvik/system/VMRuntime.java: -------------------------------------------------------------------------------- 1 | package dalvik.system; 2 | 3 | public final class VMRuntime { 4 | 5 | public static VMRuntime getRuntime() { 6 | return null; 7 | } 8 | 9 | public void setHiddenApiExemptions(String[] signaturePrefixes) { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /api/src/main/java/li/lingfeng/ltsystem/ILTweaks.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem; 2 | 3 | public class ILTweaks { 4 | 5 | public static abstract class Loader { 6 | public ILTweaksMethods methods = instantiateMethods(); 7 | protected abstract ILTweaksMethods instantiateMethods(); 8 | public abstract void initInZygote() throws Throwable; 9 | } 10 | 11 | public static abstract class MethodParam { 12 | public Object thisObject; 13 | public Object[] args; 14 | public abstract void before(Before before); 15 | public abstract void after(After after); 16 | public abstract boolean hasHook(); 17 | public abstract void hookBefore(); 18 | public abstract void hookAfter(); 19 | public abstract void setArg(int i, Object arg); 20 | public abstract boolean isArgsModified(); 21 | public abstract void setResult(Object result); 22 | public abstract void setResultSilently(Object result); 23 | public abstract void setThrowable(Throwable throwable); 24 | public abstract boolean hasResult(); 25 | public abstract Object getResult(); 26 | public abstract Object getResultOrThrowable() throws Throwable; 27 | } 28 | 29 | public interface Before { 30 | void before() throws Throwable; 31 | } 32 | 33 | public interface After { 34 | void after() throws Throwable; 35 | } 36 | 37 | public interface ParamCreator { 38 | MethodParam create(Object thisObject, Object... args); 39 | } 40 | } -------------------------------------------------------------------------------- /api/src/main/java/li/lingfeng/ltsystem/ILTweaksBridge.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem; 2 | 3 | public abstract class ILTweaksBridge { 4 | 5 | public static ILTweaks.Loader loader; 6 | public static ILTweaks.ParamCreator paramCreator; 7 | } 8 | -------------------------------------------------------------------------------- /api/src/main/java/li/lingfeng/ltsystem/LTHelper.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem; 2 | 3 | import android.app.ActivityThread; 4 | import android.app.Application; 5 | 6 | public class LTHelper { 7 | 8 | public static String currentPackageName() { 9 | return ActivityThread.currentPackageName(); 10 | } 11 | 12 | public static Application currentApplication() { 13 | return ActivityThread.currentApplication(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | app 4 | Project app created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.buildship.core.gradleprojectbuilder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.buildship.core.gradleprojectnature 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | connection.project.dir=.. 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /app/libs/indeterminate-checkbox.aar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluesky139/LTweaksSystem/662118fadfa9f795d7d9948d0778c66a0b0b2325/app/libs/indeterminate-checkbox.aar -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/li/lingfeng/ltsystem/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("li.lingfeng.ltsystem", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/aidl/li/lingfeng/ltsystem/ILTPref.aidl: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem; 2 | 3 | import li.lingfeng.ltsystem.ILTPrefListener; 4 | 5 | interface ILTPref { 6 | List getStringList(String key); 7 | void putStringList(String key, in List value); 8 | void appendStringToList(String key, String value, int limit); 9 | void addListener(String key, in ILTPrefListener listener); 10 | void removeListener(String key, in ILTPrefListener listener); 11 | } -------------------------------------------------------------------------------- /app/src/main/aidl/li/lingfeng/ltsystem/ILTPrefListener.aidl: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem; 2 | 3 | oneway interface ILTPrefListener { 4 | void onPrefChanged(String key); 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/assets/overture/domain_primary: -------------------------------------------------------------------------------- 1 | aliyun.com 2 | baidu.com 3 | adservice.google.com 4 | dl.google.com 5 | kh.google.com 6 | khm.google.com 7 | khm0.google.com 8 | khm1.google.com 9 | khm2.google.com 10 | khm3.google.com 11 | khmdb.google.com 12 | tools.google.com 13 | clientservices.googleapis.com 14 | fonts.googleapis.com 15 | khm.googleapis.com 16 | khm0.googleapis.com 17 | khm1.googleapis.com 18 | khm2.googleapis.com 19 | khm3.googleapis.com 20 | khmdb.googleapis.com 21 | storage.googleapis.com 22 | translate.googleapis.com 23 | update.googleapis.com 24 | safebrowsing.googleapis.com 25 | cn.gravatar.com 26 | connectivitycheck.gstatic.com 27 | csi.gstatic.com 28 | fonts.gstatic.com 29 | ssl.gstatic.com 30 | google.cn 31 | g.cn 32 | gov.cn 33 | qq.com 34 | sina.cn 35 | sina.com.cn 36 | sogou.com 37 | so.com 38 | soso.com 39 | weibo.com 40 | yahoo.cn 41 | youdao.com 42 | -------------------------------------------------------------------------------- /app/src/main/assets/overture/overture: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluesky139/LTweaksSystem/662118fadfa9f795d7d9948d0778c66a0b0b2325/app/src/main/assets/overture/overture -------------------------------------------------------------------------------- /app/src/main/assets/overture/overture.conf: -------------------------------------------------------------------------------- 1 | { 2 | "BindAddress": "127.0.0.1:5450", 3 | "RedirectIPv6Record": false, 4 | "DomainBase64Decode": false, 5 | "MinimumTTL": 120, 6 | "CacheSize": 4096, 7 | "PrimaryDNS": [{ 8 | "Name": "Primary-0", 9 | "Address": "114.114.114.114:53", 10 | "Timeout": 9, 11 | "EDNSClientSubnet": { 12 | "Policy": "disable" 13 | }, 14 | "Protocol": "udp" 15 | }, { 16 | "Name": "Primary-1", 17 | "Address": "114.114.115.115:53", 18 | "Timeout": 9, 19 | "EDNSClientSubnet": { 20 | "Policy": "disable" 21 | }, 22 | "Protocol": "udp" 23 | }], 24 | "AlternativeDNS": [{ 25 | "Name": "UserDef-0", 26 | "Address": "8.8.8.8:53", 27 | "Timeout": 12, 28 | "EDNSClientSubnet": { 29 | "Policy": "disable" 30 | }, 31 | "Socks5Address": "127.0.0.1:1080", 32 | "Protocol": "tcp" 33 | }], 34 | "IPNetworkFile": { 35 | "Primary": "china_ip_list.txt" 36 | }, 37 | "DomainFile": { 38 | "Primary": "domain_primary", 39 | "Alternative": "domain_alternative", 40 | "Matcher": "suffix-tree" 41 | }, 42 | "WhenPrimaryDNSAnswerNoneUse": "AlternativeDNS" 43 | } -------------------------------------------------------------------------------- /app/src/main/assets/overture/version.txt: -------------------------------------------------------------------------------- 1 | 2 -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/animation/EasingFunction.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.animation; 2 | 3 | import android.animation.TimeInterpolator; 4 | import android.annotation.SuppressLint; 5 | 6 | /** 7 | * Interface for creating custom made easing functions. Uses the 8 | * TimeInterpolator interface provided by Android. 9 | */ 10 | @SuppressLint("NewApi") 11 | public interface EasingFunction extends TimeInterpolator { 12 | 13 | @Override 14 | float getInterpolation(float input); 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/charts/BubbleChart.java: -------------------------------------------------------------------------------- 1 | 2 | package com.github.mikephil.charting.charts; 3 | 4 | import android.content.Context; 5 | import android.util.AttributeSet; 6 | 7 | import com.github.mikephil.charting.data.BubbleData; 8 | import com.github.mikephil.charting.interfaces.dataprovider.BubbleDataProvider; 9 | import com.github.mikephil.charting.renderer.BubbleChartRenderer; 10 | 11 | /** 12 | * The BubbleChart. Draws bubbles. Bubble chart implementation: Copyright 2015 13 | * Pierre-Marc Airoldi Licensed under Apache License 2.0. In the BubbleChart, it 14 | * is the area of the bubble, not the radius or diameter of the bubble that 15 | * conveys the data. 16 | * 17 | * @author Philipp Jahoda 18 | */ 19 | public class BubbleChart extends BarLineChartBase implements BubbleDataProvider { 20 | 21 | public BubbleChart(Context context) { 22 | super(context); 23 | } 24 | 25 | public BubbleChart(Context context, AttributeSet attrs) { 26 | super(context, attrs); 27 | } 28 | 29 | public BubbleChart(Context context, AttributeSet attrs, int defStyle) { 30 | super(context, attrs, defStyle); 31 | } 32 | 33 | @Override 34 | protected void init() { 35 | super.init(); 36 | 37 | mRenderer = new BubbleChartRenderer(this, mAnimator, mViewPortHandler); 38 | } 39 | 40 | public BubbleData getBubbleData() { 41 | return mData; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/charts/CandleStickChart.java: -------------------------------------------------------------------------------- 1 | 2 | package com.github.mikephil.charting.charts; 3 | 4 | import android.content.Context; 5 | import android.util.AttributeSet; 6 | 7 | import com.github.mikephil.charting.data.CandleData; 8 | import com.github.mikephil.charting.interfaces.dataprovider.CandleDataProvider; 9 | import com.github.mikephil.charting.renderer.CandleStickChartRenderer; 10 | 11 | /** 12 | * Financial chart type that draws candle-sticks (OHCL chart). 13 | * 14 | * @author Philipp Jahoda 15 | */ 16 | public class CandleStickChart extends BarLineChartBase implements CandleDataProvider { 17 | 18 | public CandleStickChart(Context context) { 19 | super(context); 20 | } 21 | 22 | public CandleStickChart(Context context, AttributeSet attrs) { 23 | super(context, attrs); 24 | } 25 | 26 | public CandleStickChart(Context context, AttributeSet attrs, int defStyle) { 27 | super(context, attrs, defStyle); 28 | } 29 | 30 | @Override 31 | protected void init() { 32 | super.init(); 33 | 34 | mRenderer = new CandleStickChartRenderer(this, mAnimator, mViewPortHandler); 35 | 36 | getXAxis().setSpaceMin(0.5f); 37 | getXAxis().setSpaceMax(0.5f); 38 | } 39 | 40 | @Override 41 | public CandleData getCandleData() { 42 | return mData; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/charts/LineChart.java: -------------------------------------------------------------------------------- 1 | 2 | package com.github.mikephil.charting.charts; 3 | 4 | import android.content.Context; 5 | import android.util.AttributeSet; 6 | 7 | import com.github.mikephil.charting.data.LineData; 8 | import com.github.mikephil.charting.interfaces.dataprovider.LineDataProvider; 9 | import com.github.mikephil.charting.renderer.LineChartRenderer; 10 | 11 | /** 12 | * Chart that draws lines, surfaces, circles, ... 13 | * 14 | * @author Philipp Jahoda 15 | */ 16 | public class LineChart extends BarLineChartBase implements LineDataProvider { 17 | 18 | public LineChart(Context context) { 19 | super(context); 20 | } 21 | 22 | public LineChart(Context context, AttributeSet attrs) { 23 | super(context, attrs); 24 | } 25 | 26 | public LineChart(Context context, AttributeSet attrs, int defStyle) { 27 | super(context, attrs, defStyle); 28 | } 29 | 30 | @Override 31 | protected void init() { 32 | super.init(); 33 | 34 | mRenderer = new LineChartRenderer(this, mAnimator, mViewPortHandler); 35 | } 36 | 37 | @Override 38 | public LineData getLineData() { 39 | return mData; 40 | } 41 | 42 | @Override 43 | protected void onDetachedFromWindow() { 44 | // releases the bitmap in the renderer to avoid oom error 45 | if (mRenderer != null && mRenderer instanceof LineChartRenderer) { 46 | ((LineChartRenderer) mRenderer).releaseBitmap(); 47 | } 48 | super.onDetachedFromWindow(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/data/BarLineScatterCandleBubbleData.java: -------------------------------------------------------------------------------- 1 | 2 | package com.github.mikephil.charting.data; 3 | 4 | import com.github.mikephil.charting.interfaces.datasets.IBarLineScatterCandleBubbleDataSet; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Baseclass for all Line, Bar, Scatter, Candle and Bubble data. 10 | * 11 | * @author Philipp Jahoda 12 | */ 13 | public abstract class BarLineScatterCandleBubbleData> 14 | extends ChartData { 15 | 16 | public BarLineScatterCandleBubbleData() { 17 | super(); 18 | } 19 | 20 | public BarLineScatterCandleBubbleData(T... sets) { 21 | super(sets); 22 | } 23 | 24 | public BarLineScatterCandleBubbleData(List sets) { 25 | super(sets); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/data/BarLineScatterCandleBubbleDataSet.java: -------------------------------------------------------------------------------- 1 | 2 | package com.github.mikephil.charting.data; 3 | 4 | import android.graphics.Color; 5 | 6 | import com.github.mikephil.charting.interfaces.datasets.IBarLineScatterCandleBubbleDataSet; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * Baseclass of all DataSets for Bar-, Line-, Scatter- and CandleStickChart. 12 | * 13 | * @author Philipp Jahoda 14 | */ 15 | public abstract class BarLineScatterCandleBubbleDataSet extends DataSet implements IBarLineScatterCandleBubbleDataSet { 16 | 17 | /** default highlight color */ 18 | protected int mHighLightColor = Color.rgb(255, 187, 115); 19 | 20 | public BarLineScatterCandleBubbleDataSet(List yVals, String label) { 21 | super(yVals, label); 22 | } 23 | 24 | /** 25 | * Sets the color that is used for drawing the highlight indicators. Dont 26 | * forget to resolve the color using getResources().getColor(...) or 27 | * Color.rgb(...). 28 | * 29 | * @param color 30 | */ 31 | public void setHighLightColor(int color) { 32 | mHighLightColor = color; 33 | } 34 | 35 | @Override 36 | public int getHighLightColor() { 37 | return mHighLightColor; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/data/BubbleData.java: -------------------------------------------------------------------------------- 1 | 2 | package com.github.mikephil.charting.data; 3 | 4 | import com.github.mikephil.charting.interfaces.datasets.IBubbleDataSet; 5 | 6 | import java.util.List; 7 | 8 | public class BubbleData extends BarLineScatterCandleBubbleData { 9 | 10 | public BubbleData() { 11 | super(); 12 | } 13 | 14 | public BubbleData(IBubbleDataSet... dataSets) { 15 | super(dataSets); 16 | } 17 | 18 | public BubbleData(List dataSets) { 19 | super(dataSets); 20 | } 21 | 22 | 23 | /** 24 | * Sets the width of the circle that surrounds the bubble when highlighted 25 | * for all DataSet objects this data object contains, in dp. 26 | * 27 | * @param width 28 | */ 29 | public void setHighlightCircleWidth(float width) { 30 | for (IBubbleDataSet set : mDataSets) { 31 | set.setHighlightCircleWidth(width); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/data/CandleData.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.data; 2 | 3 | import com.github.mikephil.charting.interfaces.datasets.ICandleDataSet; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class CandleData extends BarLineScatterCandleBubbleData { 9 | 10 | public CandleData() { 11 | super(); 12 | } 13 | 14 | public CandleData(List dataSets) { 15 | super(dataSets); 16 | } 17 | 18 | public CandleData(ICandleDataSet... dataSets) { 19 | super(dataSets); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/data/LineData.java: -------------------------------------------------------------------------------- 1 | 2 | package com.github.mikephil.charting.data; 3 | 4 | import com.github.mikephil.charting.interfaces.datasets.ILineDataSet; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * Data object that encapsulates all data associated with a LineChart. 11 | * 12 | * @author Philipp Jahoda 13 | */ 14 | public class LineData extends BarLineScatterCandleBubbleData { 15 | 16 | public LineData() { 17 | super(); 18 | } 19 | 20 | public LineData(ILineDataSet... dataSets) { 21 | super(dataSets); 22 | } 23 | 24 | public LineData(List dataSets) { 25 | super(dataSets); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/data/RadarData.java: -------------------------------------------------------------------------------- 1 | 2 | package com.github.mikephil.charting.data; 3 | 4 | import com.github.mikephil.charting.highlight.Highlight; 5 | import com.github.mikephil.charting.interfaces.datasets.IRadarDataSet; 6 | 7 | import java.util.ArrayList; 8 | import java.util.Arrays; 9 | import java.util.List; 10 | 11 | /** 12 | * Data container for the RadarChart. 13 | * 14 | * @author Philipp Jahoda 15 | */ 16 | public class RadarData extends ChartData { 17 | 18 | private List mLabels; 19 | 20 | public RadarData() { 21 | super(); 22 | } 23 | 24 | public RadarData(List dataSets) { 25 | super(dataSets); 26 | } 27 | 28 | public RadarData(IRadarDataSet... dataSets) { 29 | super(dataSets); 30 | } 31 | 32 | /** 33 | * Sets the labels that should be drawn around the RadarChart at the end of each web line. 34 | * 35 | * @param labels 36 | */ 37 | public void setLabels(List labels) { 38 | this.mLabels = labels; 39 | } 40 | 41 | /** 42 | * Sets the labels that should be drawn around the RadarChart at the end of each web line. 43 | * 44 | * @param labels 45 | */ 46 | public void setLabels(String... labels) { 47 | this.mLabels = Arrays.asList(labels); 48 | } 49 | 50 | public List getLabels() { 51 | return mLabels; 52 | } 53 | 54 | @Override 55 | public Entry getEntryForHighlight(Highlight highlight) { 56 | return getDataSetByIndex(highlight.getDataSetIndex()).getEntryForIndex((int) highlight.getX()); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/data/RadarEntry.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.data; 2 | 3 | import android.annotation.SuppressLint; 4 | 5 | /** 6 | * Created by philipp on 13/06/16. 7 | */ 8 | @SuppressLint("ParcelCreator") 9 | public class RadarEntry extends Entry { 10 | 11 | public RadarEntry(float value) { 12 | super(0f, value); 13 | } 14 | 15 | public RadarEntry(float value, Object data) { 16 | super(0f, value, data); 17 | } 18 | 19 | /** 20 | * This is the same as getY(). Returns the value of the RadarEntry. 21 | * 22 | * @return 23 | */ 24 | public float getValue() { 25 | return getY(); 26 | } 27 | 28 | public RadarEntry copy() { 29 | RadarEntry e = new RadarEntry(getY(), getData()); 30 | return e; 31 | } 32 | 33 | @Deprecated 34 | @Override 35 | public void setX(float x) { 36 | super.setX(x); 37 | } 38 | 39 | @Deprecated 40 | @Override 41 | public float getX() { 42 | return super.getX(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/data/ScatterData.java: -------------------------------------------------------------------------------- 1 | 2 | package com.github.mikephil.charting.data; 3 | 4 | import com.github.mikephil.charting.interfaces.datasets.IScatterDataSet; 5 | 6 | import java.util.List; 7 | 8 | public class ScatterData extends BarLineScatterCandleBubbleData { 9 | 10 | public ScatterData() { 11 | super(); 12 | } 13 | 14 | public ScatterData(List dataSets) { 15 | super(dataSets); 16 | } 17 | 18 | public ScatterData(IScatterDataSet... dataSets) { 19 | super(dataSets); 20 | } 21 | 22 | /** 23 | * Returns the maximum shape-size across all DataSets. 24 | * 25 | * @return 26 | */ 27 | public float getGreatestShapeSize() { 28 | 29 | float max = 0f; 30 | 31 | for (IScatterDataSet set : mDataSets) { 32 | float size = set.getScatterShapeSize(); 33 | 34 | if (size > max) 35 | max = size; 36 | } 37 | 38 | return max; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/exception/DrawingDataSetNotCreatedException.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.exception; 2 | 3 | public class DrawingDataSetNotCreatedException extends RuntimeException { 4 | 5 | /** 6 | * 7 | */ 8 | private static final long serialVersionUID = 1L; 9 | 10 | public DrawingDataSetNotCreatedException() { 11 | super("Have to create a new drawing set first. Call ChartData's createNewDrawingDataSet() method"); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/formatter/ColorFormatter.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.formatter; 2 | 3 | import com.github.mikephil.charting.data.DataSet; 4 | import com.github.mikephil.charting.data.Entry; 5 | import com.github.mikephil.charting.interfaces.datasets.IDataSet; 6 | 7 | /** 8 | * Interface that can be used to return a customized color instead of setting 9 | * colors via the setColor(...) method of the DataSet. 10 | * 11 | * @author Philipp Jahoda 12 | */ 13 | public interface ColorFormatter { 14 | 15 | /** 16 | * Returns the color to be used for the given Entry at the given index (in the entries array) 17 | * 18 | * @param index index in the entries array 19 | * @param e the entry to color 20 | * @param set the DataSet the entry belongs to 21 | * @return 22 | */ 23 | int getColor(int index, Entry e, IDataSet set); 24 | } -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/formatter/DefaultAxisValueFormatter.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.formatter; 2 | 3 | import com.github.mikephil.charting.components.AxisBase; 4 | 5 | import java.text.DecimalFormat; 6 | 7 | /** 8 | * Created by philipp on 02/06/16. 9 | */ 10 | public class DefaultAxisValueFormatter implements IAxisValueFormatter 11 | { 12 | 13 | /** 14 | * decimalformat for formatting 15 | */ 16 | protected DecimalFormat mFormat; 17 | 18 | /** 19 | * the number of decimal digits this formatter uses 20 | */ 21 | protected int digits = 0; 22 | 23 | /** 24 | * Constructor that specifies to how many digits the value should be 25 | * formatted. 26 | * 27 | * @param digits 28 | */ 29 | public DefaultAxisValueFormatter(int digits) { 30 | this.digits = digits; 31 | 32 | StringBuffer b = new StringBuffer(); 33 | for (int i = 0; i < digits; i++) { 34 | if (i == 0) 35 | b.append("."); 36 | b.append("0"); 37 | } 38 | 39 | mFormat = new DecimalFormat("###,###,###,##0" + b.toString()); 40 | } 41 | 42 | @Override 43 | public String getFormattedValue(float value, AxisBase axis) { 44 | // avoid memory allocations here (for performance) 45 | return mFormat.format(value); 46 | } 47 | 48 | /** 49 | * Returns the number of decimal digits this formatter uses or -1, if unspecified. 50 | * 51 | * @return 52 | */ 53 | public int getDecimalDigits() { 54 | return digits; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/formatter/DefaultFillFormatter.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.formatter; 2 | 3 | 4 | import com.github.mikephil.charting.data.LineData; 5 | import com.github.mikephil.charting.interfaces.dataprovider.LineDataProvider; 6 | import com.github.mikephil.charting.interfaces.datasets.ILineDataSet; 7 | 8 | /** 9 | * Default formatter that calculates the position of the filled line. 10 | * 11 | * @author Philipp Jahoda 12 | */ 13 | public class DefaultFillFormatter implements IFillFormatter 14 | { 15 | 16 | @Override 17 | public float getFillLinePosition(ILineDataSet dataSet, LineDataProvider dataProvider) { 18 | 19 | float fillMin = 0f; 20 | float chartMaxY = dataProvider.getYChartMax(); 21 | float chartMinY = dataProvider.getYChartMin(); 22 | 23 | LineData data = dataProvider.getLineData(); 24 | 25 | if (dataSet.getYMax() > 0 && dataSet.getYMin() < 0) { 26 | fillMin = 0f; 27 | } else { 28 | 29 | float max, min; 30 | 31 | if (data.getYMax() > 0) 32 | max = 0f; 33 | else 34 | max = chartMaxY; 35 | if (data.getYMin() < 0) 36 | min = 0f; 37 | else 38 | min = chartMinY; 39 | 40 | fillMin = dataSet.getYMin() >= 0 ? min : max; 41 | } 42 | 43 | return fillMin; 44 | } 45 | } -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/formatter/IAxisValueFormatter.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.formatter; 2 | 3 | import com.github.mikephil.charting.components.AxisBase; 4 | 5 | /** 6 | * Created by Philipp Jahoda on 20/09/15. 7 | * Custom formatter interface that allows formatting of 8 | * axis labels before they are being drawn. 9 | */ 10 | public interface IAxisValueFormatter 11 | { 12 | 13 | /** 14 | * Called when a value from an axis is to be formatted 15 | * before being drawn. For performance reasons, avoid excessive calculations 16 | * and memory allocations inside this method. 17 | * 18 | * @param value the value to be formatted 19 | * @param axis the axis the value belongs to 20 | * @return 21 | */ 22 | String getFormattedValue(float value, AxisBase axis); 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/formatter/IFillFormatter.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.formatter; 2 | 3 | import com.github.mikephil.charting.interfaces.datasets.ILineDataSet; 4 | import com.github.mikephil.charting.interfaces.dataprovider.LineDataProvider; 5 | 6 | /** 7 | * Interface for providing a custom logic to where the filling line of a LineDataSet 8 | * should end. This of course only works if setFillEnabled(...) is set to true. 9 | * 10 | * @author Philipp Jahoda 11 | */ 12 | public interface IFillFormatter 13 | { 14 | 15 | /** 16 | * Returns the vertical (y-axis) position where the filled-line of the 17 | * LineDataSet should end. 18 | * 19 | * @param dataSet the ILineDataSet that is currently drawn 20 | * @param dataProvider 21 | * @return 22 | */ 23 | float getFillLinePosition(ILineDataSet dataSet, LineDataProvider dataProvider); 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/formatter/IValueFormatter.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.formatter; 2 | 3 | import com.github.mikephil.charting.data.Entry; 4 | import com.github.mikephil.charting.utils.ViewPortHandler; 5 | 6 | /** 7 | * Interface that allows custom formatting of all values inside the chart before they are 8 | * being drawn to the screen. Simply create your own formatting class and let 9 | * it implement IValueFormatter. Then override the getFormattedValue(...) method 10 | * and return whatever you want. 11 | * 12 | * @author Philipp Jahoda 13 | */ 14 | public interface IValueFormatter 15 | { 16 | 17 | /** 18 | * Called when a value (from labels inside the chart) is formatted 19 | * before being drawn. For performance reasons, avoid excessive calculations 20 | * and memory allocations inside this method. 21 | * 22 | * @param value the value to be formatted 23 | * @param entry the entry the value belongs to - in e.g. BarChart, this is of class BarEntry 24 | * @param dataSetIndex the index of the DataSet the entry in focus belongs to 25 | * @param viewPortHandler provides information about the current chart state (scale, translation, ...) 26 | * @return the formatted label ready for being drawn 27 | */ 28 | String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler); 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/formatter/PercentFormatter.java: -------------------------------------------------------------------------------- 1 | 2 | package com.github.mikephil.charting.formatter; 3 | 4 | import com.github.mikephil.charting.components.AxisBase; 5 | import com.github.mikephil.charting.data.Entry; 6 | import com.github.mikephil.charting.utils.ViewPortHandler; 7 | 8 | import java.text.DecimalFormat; 9 | 10 | /** 11 | * This IValueFormatter is just for convenience and simply puts a "%" sign after 12 | * each value. (Recommeded for PieChart) 13 | * 14 | * @author Philipp Jahoda 15 | */ 16 | public class PercentFormatter implements IValueFormatter, IAxisValueFormatter 17 | { 18 | 19 | protected DecimalFormat mFormat; 20 | 21 | public PercentFormatter() { 22 | mFormat = new DecimalFormat("###,###,##0.0"); 23 | } 24 | 25 | /** 26 | * Allow a custom decimalformat 27 | * 28 | * @param format 29 | */ 30 | public PercentFormatter(DecimalFormat format) { 31 | this.mFormat = format; 32 | } 33 | 34 | // IValueFormatter 35 | @Override 36 | public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) { 37 | return mFormat.format(value) + " %"; 38 | } 39 | 40 | // IAxisValueFormatter 41 | @Override 42 | public String getFormattedValue(float value, AxisBase axis) { 43 | return mFormat.format(value) + " %"; 44 | } 45 | 46 | public int getDecimalDigits() { 47 | return 1; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/highlight/IHighlighter.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.highlight; 2 | 3 | /** 4 | * Created by philipp on 10/06/16. 5 | */ 6 | public interface IHighlighter 7 | { 8 | 9 | /** 10 | * Returns a Highlight object corresponding to the given x- and y- touch positions in pixels. 11 | * 12 | * @param x 13 | * @param y 14 | * @return 15 | */ 16 | Highlight getHighlight(float x, float y); 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/highlight/PieHighlighter.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.highlight; 2 | 3 | import com.github.mikephil.charting.charts.PieChart; 4 | import com.github.mikephil.charting.data.Entry; 5 | import com.github.mikephil.charting.interfaces.datasets.IPieDataSet; 6 | 7 | /** 8 | * Created by philipp on 12/06/16. 9 | */ 10 | public class PieHighlighter extends PieRadarHighlighter { 11 | 12 | public PieHighlighter(PieChart chart) { 13 | super(chart); 14 | } 15 | 16 | @Override 17 | protected Highlight getClosestHighlight(int index, float x, float y) { 18 | 19 | IPieDataSet set = mChart.getData().getDataSet(); 20 | 21 | final Entry entry = set.getEntryForIndex(index); 22 | 23 | return new Highlight(index, entry.getY(), x, y, 0, set.getAxisDependency()); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/highlight/Range.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.highlight; 2 | 3 | /** 4 | * Created by Philipp Jahoda on 24/07/15. Class that represents the range of one value in a stacked bar entry. e.g. 5 | * stack values are -10, 5, 20 -> then ranges are (-10 - 0, 0 - 5, 5 - 25). 6 | */ 7 | public final class Range { 8 | 9 | public float from; 10 | public float to; 11 | 12 | public Range(float from, float to) { 13 | this.from = from; 14 | this.to = to; 15 | } 16 | 17 | /** 18 | * Returns true if this range contains (if the value is in between) the given value, false if not. 19 | * 20 | * @param value 21 | * @return 22 | */ 23 | public boolean contains(float value) { 24 | 25 | if (value > from && value <= to) 26 | return true; 27 | else 28 | return false; 29 | } 30 | 31 | public boolean isLarger(float value) { 32 | return value > to; 33 | } 34 | 35 | public boolean isSmaller(float value) { 36 | return value < from; 37 | } 38 | } -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/interfaces/dataprovider/BarDataProvider.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.interfaces.dataprovider; 2 | 3 | import com.github.mikephil.charting.data.BarData; 4 | 5 | public interface BarDataProvider extends BarLineScatterCandleBubbleDataProvider { 6 | 7 | BarData getBarData(); 8 | boolean isDrawBarShadowEnabled(); 9 | boolean isDrawValueAboveBarEnabled(); 10 | boolean isHighlightFullBarEnabled(); 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/interfaces/dataprovider/BarLineScatterCandleBubbleDataProvider.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.interfaces.dataprovider; 2 | 3 | import com.github.mikephil.charting.components.YAxis.AxisDependency; 4 | import com.github.mikephil.charting.data.BarLineScatterCandleBubbleData; 5 | import com.github.mikephil.charting.utils.Transformer; 6 | 7 | public interface BarLineScatterCandleBubbleDataProvider extends ChartInterface { 8 | 9 | Transformer getTransformer(AxisDependency axis); 10 | boolean isInverted(AxisDependency axis); 11 | 12 | float getLowestVisibleX(); 13 | float getHighestVisibleX(); 14 | 15 | BarLineScatterCandleBubbleData getData(); 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/interfaces/dataprovider/BubbleDataProvider.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.interfaces.dataprovider; 2 | 3 | import com.github.mikephil.charting.data.BubbleData; 4 | 5 | public interface BubbleDataProvider extends BarLineScatterCandleBubbleDataProvider { 6 | 7 | BubbleData getBubbleData(); 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/interfaces/dataprovider/CandleDataProvider.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.interfaces.dataprovider; 2 | 3 | import com.github.mikephil.charting.data.CandleData; 4 | 5 | public interface CandleDataProvider extends BarLineScatterCandleBubbleDataProvider { 6 | 7 | CandleData getCandleData(); 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/interfaces/dataprovider/CombinedDataProvider.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.interfaces.dataprovider; 2 | 3 | import com.github.mikephil.charting.data.CombinedData; 4 | 5 | /** 6 | * Created by philipp on 11/06/16. 7 | */ 8 | public interface CombinedDataProvider extends LineDataProvider, BarDataProvider, BubbleDataProvider, CandleDataProvider, ScatterDataProvider { 9 | 10 | CombinedData getCombinedData(); 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/interfaces/dataprovider/LineDataProvider.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.interfaces.dataprovider; 2 | 3 | import com.github.mikephil.charting.components.YAxis; 4 | import com.github.mikephil.charting.data.LineData; 5 | 6 | public interface LineDataProvider extends BarLineScatterCandleBubbleDataProvider { 7 | 8 | LineData getLineData(); 9 | 10 | YAxis getAxis(YAxis.AxisDependency dependency); 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/interfaces/dataprovider/ScatterDataProvider.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.interfaces.dataprovider; 2 | 3 | import com.github.mikephil.charting.data.ScatterData; 4 | 5 | public interface ScatterDataProvider extends BarLineScatterCandleBubbleDataProvider { 6 | 7 | ScatterData getScatterData(); 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/interfaces/datasets/IBarLineScatterCandleBubbleDataSet.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.interfaces.datasets; 2 | 3 | import com.github.mikephil.charting.data.Entry; 4 | 5 | /** 6 | * Created by philipp on 21/10/15. 7 | */ 8 | public interface IBarLineScatterCandleBubbleDataSet extends IDataSet { 9 | 10 | /** 11 | * Returns the color that is used for drawing the highlight indicators. 12 | * 13 | * @return 14 | */ 15 | int getHighLightColor(); 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/interfaces/datasets/IBubbleDataSet.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.interfaces.datasets; 2 | 3 | import com.github.mikephil.charting.data.BubbleEntry; 4 | 5 | /** 6 | * Created by philipp on 21/10/15. 7 | */ 8 | public interface IBubbleDataSet extends IBarLineScatterCandleBubbleDataSet { 9 | 10 | /** 11 | * Sets the width of the circle that surrounds the bubble when highlighted, 12 | * in dp. 13 | * 14 | * @param width 15 | */ 16 | void setHighlightCircleWidth(float width); 17 | 18 | float getMaxSize(); 19 | 20 | boolean isNormalizeSizeEnabled(); 21 | 22 | /** 23 | * Returns the width of the highlight-circle that surrounds the bubble 24 | * @return 25 | */ 26 | float getHighlightCircleWidth(); 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/interfaces/datasets/ILineRadarDataSet.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.interfaces.datasets; 2 | 3 | import android.graphics.drawable.Drawable; 4 | 5 | import com.github.mikephil.charting.data.Entry; 6 | 7 | /** 8 | * Created by Philipp Jahoda on 21/10/15. 9 | */ 10 | public interface ILineRadarDataSet extends ILineScatterCandleRadarDataSet { 11 | 12 | /** 13 | * Returns the color that is used for filling the line surface area. 14 | * 15 | * @return 16 | */ 17 | int getFillColor(); 18 | 19 | /** 20 | * Returns the drawable used for filling the area below the line. 21 | * 22 | * @return 23 | */ 24 | Drawable getFillDrawable(); 25 | 26 | /** 27 | * Returns the alpha value that is used for filling the line surface, 28 | * default: 85 29 | * 30 | * @return 31 | */ 32 | int getFillAlpha(); 33 | 34 | /** 35 | * Returns the stroke-width of the drawn line 36 | * 37 | * @return 38 | */ 39 | float getLineWidth(); 40 | 41 | /** 42 | * Returns true if filled drawing is enabled, false if not 43 | * 44 | * @return 45 | */ 46 | boolean isDrawFilledEnabled(); 47 | 48 | /** 49 | * Set to true if the DataSet should be drawn filled (surface), and not just 50 | * as a line, disabling this will give great performance boost. Please note that this method 51 | * uses the canvas.clipPath(...) method for drawing the filled area. 52 | * For devices with API level < 18 (Android 4.3), hardware acceleration of the chart should 53 | * be turned off. Default: false 54 | * 55 | * @param enabled 56 | */ 57 | void setDrawFilled(boolean enabled); 58 | } 59 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/interfaces/datasets/ILineScatterCandleRadarDataSet.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.interfaces.datasets; 2 | 3 | import android.graphics.DashPathEffect; 4 | 5 | import com.github.mikephil.charting.data.Entry; 6 | 7 | /** 8 | * Created by Philipp Jahoda on 21/10/15. 9 | */ 10 | public interface ILineScatterCandleRadarDataSet extends IBarLineScatterCandleBubbleDataSet { 11 | 12 | /** 13 | * Returns true if vertical highlight indicator lines are enabled (drawn) 14 | * @return 15 | */ 16 | boolean isVerticalHighlightIndicatorEnabled(); 17 | 18 | /** 19 | * Returns true if vertical highlight indicator lines are enabled (drawn) 20 | * @return 21 | */ 22 | boolean isHorizontalHighlightIndicatorEnabled(); 23 | 24 | /** 25 | * Returns the line-width in which highlight lines are to be drawn. 26 | * @return 27 | */ 28 | float getHighlightLineWidth(); 29 | 30 | /** 31 | * Returns the DashPathEffect that is used for highlighting. 32 | * @return 33 | */ 34 | DashPathEffect getDashPathEffectHighlight(); 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/interfaces/datasets/IRadarDataSet.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.interfaces.datasets; 2 | 3 | import com.github.mikephil.charting.data.RadarEntry; 4 | 5 | /** 6 | * Created by Philipp Jahoda on 03/11/15. 7 | */ 8 | public interface IRadarDataSet extends ILineRadarDataSet { 9 | 10 | /// flag indicating whether highlight circle should be drawn or not 11 | boolean isDrawHighlightCircleEnabled(); 12 | 13 | /// Sets whether highlight circle should be drawn or not 14 | void setDrawHighlightCircleEnabled(boolean enabled); 15 | 16 | int getHighlightCircleFillColor(); 17 | 18 | /// The stroke color for highlight circle. 19 | /// If Utils.COLOR_NONE, the color of the dataset is taken. 20 | int getHighlightCircleStrokeColor(); 21 | 22 | int getHighlightCircleStrokeAlpha(); 23 | 24 | float getHighlightCircleInnerRadius(); 25 | 26 | float getHighlightCircleOuterRadius(); 27 | 28 | float getHighlightCircleStrokeWidth(); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/interfaces/datasets/IScatterDataSet.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.interfaces.datasets; 2 | 3 | import com.github.mikephil.charting.data.Entry; 4 | import com.github.mikephil.charting.renderer.scatter.IShapeRenderer; 5 | 6 | /** 7 | * Created by philipp on 21/10/15. 8 | */ 9 | public interface IScatterDataSet extends ILineScatterCandleRadarDataSet { 10 | 11 | /** 12 | * Returns the currently set scatter shape size 13 | * 14 | * @return 15 | */ 16 | float getScatterShapeSize(); 17 | 18 | /** 19 | * Returns radius of the hole in the shape 20 | * 21 | * @return 22 | */ 23 | float getScatterShapeHoleRadius(); 24 | 25 | /** 26 | * Returns the color for the hole in the shape 27 | * 28 | * @return 29 | */ 30 | int getScatterShapeHoleColor(); 31 | 32 | /** 33 | * Returns the IShapeRenderer responsible for rendering this DataSet. 34 | * 35 | * @return 36 | */ 37 | IShapeRenderer getShapeRenderer(); 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/jobs/MoveViewJob.java: -------------------------------------------------------------------------------- 1 | 2 | package com.github.mikephil.charting.jobs; 3 | 4 | import android.view.View; 5 | 6 | import com.github.mikephil.charting.utils.ObjectPool; 7 | import com.github.mikephil.charting.utils.Transformer; 8 | import com.github.mikephil.charting.utils.ViewPortHandler; 9 | 10 | /** 11 | * Created by Philipp Jahoda on 19/02/16. 12 | */ 13 | public class MoveViewJob extends ViewPortJob { 14 | 15 | private static ObjectPool pool; 16 | 17 | static { 18 | pool = ObjectPool.create(2, new MoveViewJob(null,0,0,null,null)); 19 | pool.setReplenishPercentage(0.5f); 20 | } 21 | 22 | public static MoveViewJob getInstance(ViewPortHandler viewPortHandler, float xValue, float yValue, Transformer trans, View v){ 23 | MoveViewJob result = pool.get(); 24 | result.mViewPortHandler = viewPortHandler; 25 | result.xValue = xValue; 26 | result.yValue = yValue; 27 | result.mTrans = trans; 28 | result.view = v; 29 | return result; 30 | } 31 | 32 | public static void recycleInstance(MoveViewJob instance){ 33 | pool.recycle(instance); 34 | } 35 | 36 | public MoveViewJob(ViewPortHandler viewPortHandler, float xValue, float yValue, Transformer trans, View v) { 37 | super(viewPortHandler, xValue, yValue, trans, v); 38 | } 39 | 40 | @Override 41 | public void run() { 42 | 43 | pts[0] = xValue; 44 | pts[1] = yValue; 45 | 46 | mTrans.pointValuesToPixel(pts); 47 | mViewPortHandler.centerViewPort(pts, view); 48 | 49 | this.recycleInstance(this); 50 | } 51 | 52 | @Override 53 | protected ObjectPool.Poolable instantiate() { 54 | return new MoveViewJob(mViewPortHandler, xValue, yValue, mTrans, view); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/jobs/ViewPortJob.java: -------------------------------------------------------------------------------- 1 | 2 | package com.github.mikephil.charting.jobs; 3 | 4 | import android.view.View; 5 | 6 | import com.github.mikephil.charting.utils.ObjectPool; 7 | import com.github.mikephil.charting.utils.Transformer; 8 | import com.github.mikephil.charting.utils.ViewPortHandler; 9 | 10 | /** 11 | * Runnable that is used for viewport modifications since they cannot be 12 | * executed at any time. This can be used to delay the execution of viewport 13 | * modifications until the onSizeChanged(...) method of the chart-view is called. 14 | * This is especially important if viewport modifying methods are called on the chart 15 | * directly after initialization. 16 | * 17 | * @author Philipp Jahoda 18 | */ 19 | public abstract class ViewPortJob extends ObjectPool.Poolable implements Runnable { 20 | 21 | protected float[] pts = new float[2]; 22 | 23 | protected ViewPortHandler mViewPortHandler; 24 | protected float xValue = 0f; 25 | protected float yValue = 0f; 26 | protected Transformer mTrans; 27 | protected View view; 28 | 29 | public ViewPortJob(ViewPortHandler viewPortHandler, float xValue, float yValue, 30 | Transformer trans, View v) { 31 | 32 | this.mViewPortHandler = viewPortHandler; 33 | this.xValue = xValue; 34 | this.yValue = yValue; 35 | this.mTrans = trans; 36 | this.view = v; 37 | 38 | } 39 | 40 | public float getXValue() { 41 | return xValue; 42 | } 43 | 44 | public float getYValue() { 45 | return yValue; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/listener/OnChartValueSelectedListener.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.listener; 2 | 3 | import com.github.mikephil.charting.data.Entry; 4 | import com.github.mikephil.charting.highlight.Highlight; 5 | 6 | /** 7 | * Listener for callbacks when selecting values inside the chart by 8 | * touch-gesture. 9 | * 10 | * @author Philipp Jahoda 11 | */ 12 | public interface OnChartValueSelectedListener { 13 | 14 | /** 15 | * Called when a value has been selected inside the chart. 16 | * 17 | * @param e The selected Entry 18 | * @param h The corresponding highlight object that contains information 19 | * about the highlighted position such as dataSetIndex, ... 20 | */ 21 | void onValueSelected(Entry e, Highlight h); 22 | 23 | /** 24 | * Called when nothing has been selected or an "un-select" has been made. 25 | */ 26 | void onNothingSelected(); 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/listener/OnDrawLineChartTouchListener.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.listener; 2 | 3 | import android.view.GestureDetector.SimpleOnGestureListener; 4 | import android.view.MotionEvent; 5 | import android.view.View; 6 | import android.view.View.OnTouchListener; 7 | 8 | public class OnDrawLineChartTouchListener extends SimpleOnGestureListener implements OnTouchListener { 9 | 10 | @Override 11 | public boolean onTouch(View v, MotionEvent event) { 12 | return false; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/listener/OnDrawListener.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.listener; 2 | 3 | import com.github.mikephil.charting.data.DataSet; 4 | import com.github.mikephil.charting.data.Entry; 5 | 6 | /** 7 | * Listener for callbacks when drawing on the chart. 8 | * 9 | * @author Philipp 10 | * 11 | */ 12 | public interface OnDrawListener { 13 | 14 | /** 15 | * Called whenever an entry is added with the finger. Note this is also called for entries that are generated by the 16 | * library, when the touch gesture is too fast and skips points. 17 | * 18 | * @param entry 19 | * the last drawn entry 20 | */ 21 | void onEntryAdded(Entry entry); 22 | 23 | /** 24 | * Called whenever an entry is moved by the user after beeing highlighted 25 | * 26 | * @param entry 27 | */ 28 | void onEntryMoved(Entry entry); 29 | 30 | /** 31 | * Called when drawing finger is lifted and the draw is finished. 32 | * 33 | * @param dataSet 34 | * the last drawn DataSet 35 | */ 36 | void onDrawFinished(DataSet dataSet); 37 | 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/renderer/Renderer.java: -------------------------------------------------------------------------------- 1 | 2 | package com.github.mikephil.charting.renderer; 3 | 4 | import com.github.mikephil.charting.utils.ViewPortHandler; 5 | 6 | /** 7 | * Abstract baseclass of all Renderers. 8 | * 9 | * @author Philipp Jahoda 10 | */ 11 | public abstract class Renderer { 12 | 13 | /** 14 | * the component that handles the drawing area of the chart and it's offsets 15 | */ 16 | protected ViewPortHandler mViewPortHandler; 17 | 18 | public Renderer(ViewPortHandler viewPortHandler) { 19 | this.mViewPortHandler = viewPortHandler; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/renderer/scatter/ChevronDownShapeRenderer.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.renderer.scatter; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | 6 | import com.github.mikephil.charting.interfaces.datasets.IScatterDataSet; 7 | import com.github.mikephil.charting.utils.Utils; 8 | import com.github.mikephil.charting.utils.ViewPortHandler; 9 | 10 | /** 11 | * Created by wajdic on 15/06/2016. 12 | * Created at Time 09:08 13 | */ 14 | public class ChevronDownShapeRenderer implements IShapeRenderer 15 | { 16 | 17 | 18 | @Override 19 | public void renderShape(Canvas c, IScatterDataSet dataSet, ViewPortHandler viewPortHandler, 20 | float posX, float posY, Paint renderPaint) { 21 | 22 | final float shapeHalf = dataSet.getScatterShapeSize() / 2f; 23 | 24 | renderPaint.setStyle(Paint.Style.STROKE); 25 | renderPaint.setStrokeWidth(Utils.convertDpToPixel(1f)); 26 | 27 | c.drawLine( 28 | posX, 29 | posY + (2 * shapeHalf), 30 | posX + (2 * shapeHalf), 31 | posY, 32 | renderPaint); 33 | 34 | c.drawLine( 35 | posX, 36 | posY + (2 * shapeHalf), 37 | posX - (2 * shapeHalf), 38 | posY, 39 | renderPaint); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/renderer/scatter/ChevronUpShapeRenderer.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.renderer.scatter; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | 6 | import com.github.mikephil.charting.interfaces.datasets.IScatterDataSet; 7 | import com.github.mikephil.charting.utils.Utils; 8 | import com.github.mikephil.charting.utils.ViewPortHandler; 9 | 10 | /** 11 | * Created by wajdic on 15/06/2016. 12 | * Created at Time 09:08 13 | */ 14 | public class ChevronUpShapeRenderer implements IShapeRenderer 15 | { 16 | 17 | 18 | @Override 19 | public void renderShape(Canvas c, IScatterDataSet dataSet, ViewPortHandler viewPortHandler, 20 | float posX, float posY, Paint renderPaint) { 21 | 22 | final float shapeHalf = dataSet.getScatterShapeSize() / 2f; 23 | 24 | renderPaint.setStyle(Paint.Style.STROKE); 25 | renderPaint.setStrokeWidth(Utils.convertDpToPixel(1f)); 26 | 27 | c.drawLine( 28 | posX, 29 | posY - (2 * shapeHalf), 30 | posX + (2 * shapeHalf), 31 | posY, 32 | renderPaint); 33 | 34 | c.drawLine( 35 | posX, 36 | posY - (2 * shapeHalf), 37 | posX - (2 * shapeHalf), 38 | posY, 39 | renderPaint); 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/renderer/scatter/CrossShapeRenderer.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.renderer.scatter; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | 6 | import com.github.mikephil.charting.interfaces.datasets.IScatterDataSet; 7 | import com.github.mikephil.charting.utils.Utils; 8 | import com.github.mikephil.charting.utils.ViewPortHandler; 9 | 10 | /** 11 | * Created by wajdic on 15/06/2016. 12 | * Created at Time 09:08 13 | */ 14 | public class CrossShapeRenderer implements IShapeRenderer 15 | { 16 | 17 | 18 | @Override 19 | public void renderShape(Canvas c, IScatterDataSet dataSet, ViewPortHandler viewPortHandler, 20 | float posX, float posY, Paint renderPaint) { 21 | 22 | final float shapeHalf = dataSet.getScatterShapeSize() / 2f; 23 | 24 | renderPaint.setStyle(Paint.Style.STROKE); 25 | renderPaint.setStrokeWidth(Utils.convertDpToPixel(1f)); 26 | 27 | c.drawLine( 28 | posX - shapeHalf, 29 | posY, 30 | posX + shapeHalf, 31 | posY, 32 | renderPaint); 33 | c.drawLine( 34 | posX, 35 | posY - shapeHalf, 36 | posX, 37 | posY + shapeHalf, 38 | renderPaint); 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/renderer/scatter/IShapeRenderer.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.renderer.scatter; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | 6 | import com.github.mikephil.charting.interfaces.datasets.IScatterDataSet; 7 | import com.github.mikephil.charting.utils.ViewPortHandler; 8 | 9 | /** 10 | * Created by wajdic on 15/06/2016. 11 | * Created at Time 09:07 12 | */ 13 | public interface IShapeRenderer 14 | { 15 | 16 | /** 17 | * Renders the provided ScatterDataSet with a shape. 18 | * 19 | * @param c Canvas object for drawing the shape 20 | * @param dataSet The DataSet to be drawn 21 | * @param viewPortHandler Contains information about the current state of the view 22 | * @param posX Position to draw the shape at 23 | * @param posY Position to draw the shape at 24 | * @param renderPaint Paint object used for styling and drawing 25 | */ 26 | void renderShape(Canvas c, IScatterDataSet dataSet, ViewPortHandler viewPortHandler, 27 | float posX, float posY, Paint renderPaint); 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/renderer/scatter/XShapeRenderer.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.renderer.scatter; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | 6 | import com.github.mikephil.charting.interfaces.datasets.IScatterDataSet; 7 | import com.github.mikephil.charting.utils.Utils; 8 | import com.github.mikephil.charting.utils.ViewPortHandler; 9 | 10 | /** 11 | * Created by wajdic on 15/06/2016. 12 | * Created at Time 09:08 13 | */ 14 | public class XShapeRenderer implements IShapeRenderer 15 | { 16 | 17 | 18 | @Override 19 | public void renderShape(Canvas c, IScatterDataSet dataSet, ViewPortHandler viewPortHandler, 20 | float posX, float posY, Paint renderPaint) { 21 | 22 | final float shapeHalf = dataSet.getScatterShapeSize() / 2f; 23 | 24 | renderPaint.setStyle(Paint.Style.STROKE); 25 | renderPaint.setStrokeWidth(Utils.convertDpToPixel(1f)); 26 | 27 | c.drawLine( 28 | posX - shapeHalf, 29 | posY - shapeHalf, 30 | posX + shapeHalf, 31 | posY + shapeHalf, 32 | renderPaint); 33 | c.drawLine( 34 | posX + shapeHalf, 35 | posY - shapeHalf, 36 | posX - shapeHalf, 37 | posY + shapeHalf, 38 | renderPaint); 39 | 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/utils/EntryXComparator.java: -------------------------------------------------------------------------------- 1 | package com.github.mikephil.charting.utils; 2 | 3 | import com.github.mikephil.charting.data.Entry; 4 | 5 | import java.util.Comparator; 6 | 7 | /** 8 | * Comparator for comparing Entry-objects by their x-value. 9 | * Created by philipp on 17/06/15. 10 | */ 11 | public class EntryXComparator implements Comparator { 12 | @Override 13 | public int compare(Entry entry1, Entry entry2) { 14 | float diff = entry1.getX() - entry2.getX(); 15 | 16 | if (diff == 0f) return 0; 17 | else { 18 | if (diff > 0f) return 1; 19 | else return -1; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/utils/HorizontalViewPortHandler.java: -------------------------------------------------------------------------------- 1 | 2 | package com.github.mikephil.charting.utils; 3 | 4 | /** 5 | * ViewPortHandler for HorizontalBarChart. 6 | */ 7 | public class HorizontalViewPortHandler extends ViewPortHandler { 8 | 9 | 10 | // @Override 11 | // public void setMinimumScaleX(float xScale) { 12 | // setMinimumScaleY(xScale); 13 | // } 14 | // 15 | // @Override 16 | // public void setMinimumScaleY(float yScale) { 17 | // setMinimumScaleX(yScale); 18 | // } 19 | // 20 | // @Override 21 | // public void setMinMaxScaleX(float minScaleX, float maxScaleX) { 22 | // setMinMaxScaleY(minScaleX, maxScaleX); 23 | // } 24 | // 25 | // @Override 26 | // public void setMinMaxScaleY(float minScaleY, float maxScaleY) { 27 | // setMinMaxScaleX(minScaleY, maxScaleY); 28 | // } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/utils/MPPointD.java: -------------------------------------------------------------------------------- 1 | 2 | package com.github.mikephil.charting.utils; 3 | 4 | import java.util.List; 5 | 6 | /** 7 | * Point encapsulating two double values. 8 | * 9 | * @author Philipp Jahoda 10 | */ 11 | public class MPPointD extends ObjectPool.Poolable { 12 | 13 | private static ObjectPool pool; 14 | 15 | static { 16 | pool = ObjectPool.create(64, new MPPointD(0,0)); 17 | pool.setReplenishPercentage(0.5f); 18 | } 19 | 20 | public static MPPointD getInstance(double x, double y){ 21 | MPPointD result = pool.get(); 22 | result.x = x; 23 | result.y = y; 24 | return result; 25 | } 26 | 27 | public static void recycleInstance(MPPointD instance){ 28 | pool.recycle(instance); 29 | } 30 | 31 | public static void recycleInstances(List instances){ 32 | pool.recycle(instances); 33 | } 34 | 35 | public double x; 36 | public double y; 37 | 38 | protected ObjectPool.Poolable instantiate(){ 39 | return new MPPointD(0,0); 40 | } 41 | 42 | private MPPointD(double x, double y) { 43 | this.x = x; 44 | this.y = y; 45 | } 46 | 47 | /** 48 | * returns a string representation of the object 49 | */ 50 | public String toString() { 51 | return "MPPointD, x: " + x + ", y: " + y; 52 | } 53 | } -------------------------------------------------------------------------------- /app/src/main/java/com/github/mikephil/charting/utils/TransformerHorizontalBarChart.java: -------------------------------------------------------------------------------- 1 | 2 | package com.github.mikephil.charting.utils; 3 | 4 | /** 5 | * Transformer class for the HorizontalBarChart. 6 | * 7 | * @author Philipp Jahoda 8 | */ 9 | public class TransformerHorizontalBarChart extends Transformer { 10 | 11 | public TransformerHorizontalBarChart(ViewPortHandler viewPortHandler) { 12 | super(viewPortHandler); 13 | } 14 | 15 | /** 16 | * Prepares the matrix that contains all offsets. 17 | * 18 | * @param inverted 19 | */ 20 | public void prepareMatrixOffset(boolean inverted) { 21 | 22 | mMatrixOffset.reset(); 23 | 24 | // offset.postTranslate(mOffsetLeft, getHeight() - mOffsetBottom); 25 | 26 | if (!inverted) 27 | mMatrixOffset.postTranslate(mViewPortHandler.offsetLeft(), 28 | mViewPortHandler.getChartHeight() - mViewPortHandler.offsetBottom()); 29 | else { 30 | mMatrixOffset 31 | .setTranslate( 32 | -(mViewPortHandler.getChartWidth() - mViewPortHandler.offsetRight()), 33 | mViewPortHandler.getChartHeight() - mViewPortHandler.offsetBottom()); 34 | mMatrixOffset.postScale(-1.0f, 1.0f); 35 | } 36 | 37 | // mMatrixOffset.set(offset); 38 | 39 | // mMatrixOffset.reset(); 40 | // 41 | // mMatrixOffset.postTranslate(mOffsetLeft, getHeight() - 42 | // mOffsetBottom); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/activities/JDActivity.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.activities; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.net.Uri; 6 | import android.os.Bundle; 7 | import android.widget.Toast; 8 | 9 | import li.lingfeng.ltsystem.utils.Logger; 10 | import li.lingfeng.ltsystem.utils.ShoppingUtils; 11 | 12 | /** 13 | * Created by smallville on 2017/1/4. 14 | */ 15 | 16 | public class JDActivity extends Activity { 17 | 18 | @Override 19 | protected void onCreate(Bundle savedInstanceState) { 20 | super.onCreate(savedInstanceState); 21 | if (!getIntent().getAction().equals(Intent.ACTION_VIEW)) { 22 | Toast.makeText(this, "Not supported.", Toast.LENGTH_SHORT).show(); 23 | finish(); 24 | return; 25 | } 26 | 27 | String text = getIntent().getDataString(); 28 | Logger.i("JDActivity url " + text); 29 | String itemId = ShoppingUtils.findItemIdByStore(text, ShoppingUtils.STORE_JD); 30 | if (itemId != null) { 31 | Intent intent = new Intent(Intent.ACTION_VIEW); 32 | intent.setData(Uri.parse("openapp.jdmobile://virtual?params={\"category\":\"jump\",\"des\":\"productDetail\",\"skuId\":\"" + itemId + "\",\"sourceType\":\"Item\",\"sourceValue\":\"view-ware\"}")); 33 | intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); 34 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 35 | startActivity(intent); 36 | finish(); 37 | return; 38 | } 39 | 40 | Toast.makeText(this, "Not supported.", Toast.LENGTH_SHORT).show(); 41 | finish(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/activities/LoadingDialog.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.activities; 2 | 3 | import android.app.Activity; 4 | import android.app.AlertDialog; 5 | import android.widget.ProgressBar; 6 | 7 | import li.lingfeng.ltsystem.utils.Logger; 8 | 9 | /** 10 | * Created by smallville on 2017/6/2. 11 | */ 12 | 13 | public class LoadingDialog { 14 | 15 | private static AlertDialog sDialog; 16 | 17 | public static void show(Activity activity) { 18 | if (sDialog != null) { 19 | Logger.w("LoadingDialog is already exist."); 20 | return; 21 | } 22 | sDialog = new AlertDialog.Builder(activity) 23 | .setView(new ProgressBar(activity)) 24 | .create(); 25 | sDialog.show(); 26 | } 27 | 28 | public static void dismiss() { 29 | if (sDialog != null) { 30 | sDialog.dismiss(); 31 | sDialog = null; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/activities/WeChatBrowserActivity.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.activities; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.support.annotation.Nullable; 7 | 8 | import li.lingfeng.ltsystem.prefs.ClassNames; 9 | import li.lingfeng.ltsystem.prefs.PackageNames; 10 | import li.lingfeng.ltsystem.utils.Logger; 11 | 12 | public class WeChatBrowserActivity extends Activity { 13 | 14 | @Override 15 | protected void onCreate(@Nullable Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | String url = getIntent().getDataString(); 18 | Logger.i("WeChatBrowserActivity url " + url); 19 | 20 | Intent intent = new Intent(Intent.ACTION_VIEW); 21 | intent.setClassName(PackageNames.WE_CHAT, ClassNames.WE_CHAT_LAUNCHER_UI); 22 | intent.putExtra("ltweaks_open_url", url); 23 | intent.setFlags(335544320); 24 | startActivity(intent); 25 | 26 | finish(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/fragments/ShoppingPrefFragment.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.fragments; 2 | 3 | import android.os.Bundle; 4 | import android.preference.Preference; 5 | 6 | import li.lingfeng.ltsystem.R; 7 | import li.lingfeng.ltsystem.activities.JDActivity; 8 | import li.lingfeng.ltsystem.fragments.base.Extra; 9 | import li.lingfeng.ltsystem.lib.PreferenceChange; 10 | import li.lingfeng.ltsystem.utils.ComponentUtils; 11 | 12 | /** 13 | * Created by smallville on 2016/12/25. 14 | */ 15 | 16 | public class ShoppingPrefFragment extends BasePrefFragment { 17 | 18 | @Override 19 | public void onCreate(Bundle savedInstanceState) { 20 | super.onCreate(savedInstanceState); 21 | addPreferencesFromResource(R.xml.pref_shopping); 22 | } 23 | 24 | @PreferenceChange(prefs = R.string.key_jd_open_link_in_app, refreshAtStart = true) 25 | private void enableJdOpenLinkInApp(Preference preference, boolean enabled, Extra extra) { 26 | if (extra.refreshAtStart) { 27 | uncheckPreferenceByDisabledComponent(R.string.key_jd_open_link_in_app, JDActivity.class); 28 | } else { 29 | ComponentUtils.enableComponent(JDActivity.class, enabled); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/fragments/base/Extra.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.fragments.base; 2 | 3 | /** 4 | * Created by sv on 18-2-18. 5 | */ 6 | 7 | public class Extra { 8 | public boolean refreshAtStart = false; 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/prefs/ActivityRequestCode.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.prefs; 2 | 3 | /** 4 | * Created by lilingfeng on 2017/7/6. 5 | */ 6 | 7 | public class ActivityRequestCode { 8 | 9 | public static final int KEYGUARD = 111; 10 | public static final int QQ_CLEAR_IMAGE_CHOOSER = 112; 11 | public static final int DRAWER_SELECT_HEADER_BACKGROUND = 113; 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/prefs/NotificationId.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.prefs; 2 | 3 | public class NotificationId { 4 | 5 | public static final int ADB_WIRELESS = 101; 6 | public static final int COPY_TO_SHARE_SERVICE = 102; 7 | public static final int CELL_LOCATION_SERVICE = 103; 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/services/BootReceiver.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.services; 2 | 3 | import android.content.BroadcastReceiver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | 7 | import li.lingfeng.ltsystem.R; 8 | import li.lingfeng.ltsystem.prefs.Prefs; 9 | import li.lingfeng.ltsystem.utils.Logger; 10 | 11 | public class BootReceiver extends BroadcastReceiver { 12 | @Override 13 | public void onReceive(Context context, Intent intent) { 14 | Logger.i("Boot completed."); 15 | if (Prefs.instance().getBoolean(R.string.key_system_share_copy_to_share, false)) { 16 | intent = new Intent(context, CopyToShareService.class); 17 | context.startService(intent); 18 | } 19 | if (Prefs.instance().getBoolean(R.string.key_phone_broadcast_cell_location_change, false) 20 | || Prefs.instance().getBoolean(R.string.key_phone_record_cells, false) 21 | || Prefs.instance().getBoolean(R.string.key_phone_broadcast_home_cells, false)) { 22 | intent = new Intent(context, CellLocationService.class); 23 | context.startService(intent); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/services/BrightnessTile.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.services; 2 | 3 | import android.provider.Settings; 4 | import android.service.quicksettings.Tile; 5 | import android.service.quicksettings.TileService; 6 | 7 | import li.lingfeng.ltsystem.R; 8 | import li.lingfeng.ltsystem.prefs.Prefs; 9 | import li.lingfeng.ltsystem.utils.Logger; 10 | 11 | public class BrightnessTile extends TileService { 12 | 13 | @Override 14 | public void onStartListening() { 15 | int value = Prefs.instance().getInt(R.string.key_quick_settings_tile_preconfigured_brightness, 0); 16 | if (value > 0) { 17 | updateTile(value); 18 | } 19 | } 20 | 21 | @Override 22 | public void onClick() { 23 | int value = Prefs.instance().getInt(R.string.key_quick_settings_tile_preconfigured_brightness, 0); 24 | if (value > 0) { 25 | Logger.i("Set brightness " + value); 26 | Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_MODE, 27 | Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL); 28 | Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, value); 29 | updateTile(value); 30 | } 31 | } 32 | 33 | private void updateTile(int value) { 34 | Tile tile = getQsTile(); 35 | tile.setLabel("Set " + value + " brightness"); 36 | try { 37 | tile.setState(Settings.System.getInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_MODE) 38 | == Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE); 39 | } catch (Settings.SettingNotFoundException e) { 40 | tile.setState(Tile.STATE_UNAVAILABLE); 41 | } 42 | tile.updateTile(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/services/RemoteLog.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.services; 2 | 3 | import android.content.ContentProvider; 4 | import android.content.ContentValues; 5 | import android.database.Cursor; 6 | import android.net.Uri; 7 | import android.support.annotation.NonNull; 8 | import android.support.annotation.Nullable; 9 | import android.util.Log; 10 | 11 | public class RemoteLog extends ContentProvider { 12 | 13 | @Override 14 | public boolean onCreate() { 15 | return true; 16 | } 17 | 18 | @Nullable 19 | @Override 20 | public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) { 21 | return null; 22 | } 23 | 24 | @Nullable 25 | @Override 26 | public String getType(@NonNull Uri uri) { 27 | return null; 28 | } 29 | 30 | @Nullable 31 | @Override 32 | public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) { 33 | String tag = values.getAsString("tag"); 34 | String level = values.getAsString("level"); 35 | String msg = values.getAsString("msg"); 36 | Log.d(tag + "[" + level + "]", msg); 37 | return null; 38 | } 39 | 40 | @Override 41 | public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) { 42 | return 0; 43 | } 44 | 45 | @Override 46 | public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) { 47 | return 0; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/services/Switch4G3G.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.services; 2 | 3 | import android.content.Intent; 4 | import android.graphics.drawable.Icon; 5 | import android.service.quicksettings.Tile; 6 | import android.service.quicksettings.TileService; 7 | 8 | import li.lingfeng.ltsystem.R; 9 | import li.lingfeng.ltsystem.utils.Logger; 10 | 11 | public class Switch4G3G extends TileService { 12 | 13 | private boolean mIs4G = true; 14 | 15 | @Override 16 | public void onStartListening() { 17 | updateTile(); 18 | } 19 | 20 | @Override 21 | public void onClick() { 22 | mIs4G = !mIs4G; 23 | Logger.d("Switch4G3G onClick " + mIs4G); 24 | Intent intent = new Intent(li.lingfeng.ltsystem.tweaks.system.Switch4G3G.ACTION_SWITCH); 25 | intent.putExtra("is_on", mIs4G); 26 | sendBroadcast(intent); 27 | updateTile(); 28 | } 29 | 30 | private void updateTile() { 31 | Tile tile = getQsTile(); 32 | tile.setIcon(Icon.createWithResource(this, mIs4G ? R.drawable.ic_4g : R.drawable.ic_3g)); 33 | tile.updateTile(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/communication/QQExternalBrowser.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.communication; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | 6 | import li.lingfeng.ltsystem.ILTweaks; 7 | import li.lingfeng.ltsystem.R; 8 | import li.lingfeng.ltsystem.lib.MethodsLoad; 9 | import li.lingfeng.ltsystem.prefs.PackageNames; 10 | import li.lingfeng.ltsystem.tweaks.TweakBase; 11 | import li.lingfeng.ltsystem.utils.ContextUtils; 12 | import li.lingfeng.ltsystem.utils.Logger; 13 | import li.lingfeng.ltsystem.utils.Utils; 14 | 15 | @MethodsLoad(packages = PackageNames.QQ, prefs = R.string.key_qq_outer_browser) 16 | public class QQExternalBrowser extends TweakBase { 17 | 18 | private static final String BROWSER_DELEGATED_ACTIVITY = "com.tencent.mobileqq.activity.QQBrowserDelegationActivity"; 19 | 20 | @Override 21 | public void android_app_Activity__startActivityForResult__Intent_int_Bundle(ILTweaks.MethodParam param) { 22 | param.before(() -> { 23 | Intent intent = (Intent) param.args[0]; 24 | if (intent.getComponent() == null 25 | || !intent.getComponent().getClassName().equals(BROWSER_DELEGATED_ACTIVITY)) { 26 | return; 27 | } 28 | 29 | Activity activity = (Activity) param.thisObject; 30 | String url = intent.getStringExtra("url"); 31 | if (Utils.isUrl(url)) { 32 | Logger.i("QQ url " + url); 33 | ContextUtils.startBrowser(activity, url); 34 | param.setResult(null); 35 | } 36 | }); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/communication/TTRssDarkenStartingWindow.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.communication; 2 | 3 | import android.graphics.Color; 4 | import android.graphics.drawable.ColorDrawable; 5 | import android.view.Window; 6 | 7 | import li.lingfeng.ltsystem.ILTweaks; 8 | import li.lingfeng.ltsystem.R; 9 | import li.lingfeng.ltsystem.lib.MethodsLoad; 10 | import li.lingfeng.ltsystem.prefs.PackageNames; 11 | import li.lingfeng.ltsystem.tweaks.TweakBase; 12 | import li.lingfeng.ltsystem.utils.Logger; 13 | 14 | @MethodsLoad(packages = PackageNames.ANDROID, prefs = R.string.key_ttrss_darken) 15 | public class TTRssDarkenStartingWindow extends TweakBase { 16 | 17 | @Override 18 | public void com_android_internal_policy_PhoneWindow__generateLayout__DecorView(ILTweaks.MethodParam param) { 19 | param.before(() -> { 20 | Window window = (Window) param.thisObject; 21 | if (window.getContext().getPackageName().equals(PackageNames.TT_RSS)) { 22 | ColorDrawable drawable = new ColorDrawable(Color.parseColor("#1c1d1e")); 23 | Logger.i("Set night background for tt-rss phone window."); 24 | window.setBackgroundDrawable(drawable); 25 | } 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/communication/TelegramDarkenStartingWindow.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.communication; 2 | 3 | import android.graphics.drawable.ColorDrawable; 4 | import android.view.Window; 5 | 6 | import li.lingfeng.ltsystem.ILTweaks; 7 | import li.lingfeng.ltsystem.R; 8 | import li.lingfeng.ltsystem.lib.MethodsLoad; 9 | import li.lingfeng.ltsystem.prefs.PackageNames; 10 | import li.lingfeng.ltsystem.tweaks.TweakBase; 11 | import li.lingfeng.ltsystem.utils.Logger; 12 | 13 | @MethodsLoad(packages = PackageNames.ANDROID, prefs = R.string.key_telegram_darken) 14 | public class TelegramDarkenStartingWindow extends TweakBase { 15 | 16 | @Override 17 | public void com_android_internal_policy_PhoneWindow__generateLayout__DecorView(ILTweaks.MethodParam param) { 18 | param.before(() -> { 19 | Window window = (Window) param.thisObject; 20 | if (window.getContext().getPackageName().equals(PackageNames.TELEGRAM)) { 21 | ColorDrawable drawable = new ColorDrawable(0x1D2733); 22 | Logger.i("Set night background for telegram phone window."); 23 | window.setBackgroundDrawable(drawable); 24 | } 25 | }); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/communication/TelegramDarkenVideoBackground.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.communication; 2 | 3 | import android.graphics.Color; 4 | import android.webkit.WebView; 5 | 6 | import li.lingfeng.ltsystem.ILTweaks; 7 | import li.lingfeng.ltsystem.R; 8 | import li.lingfeng.ltsystem.lib.MethodsLoad; 9 | import li.lingfeng.ltsystem.prefs.PackageNames; 10 | import li.lingfeng.ltsystem.tweaks.TweakBase; 11 | import li.lingfeng.ltsystem.utils.Logger; 12 | import li.lingfeng.ltsystem.utils.ReflectUtils; 13 | 14 | @MethodsLoad(packages = PackageNames.TELEGRAM, prefs = R.string.key_telegram_darken) 15 | public class TelegramDarkenVideoBackground extends TweakBase { 16 | 17 | private static final String EMBED_BOTTOM_SHEET = "org.telegram.ui.Components.EmbedBottomSheet"; 18 | 19 | @Override 20 | public void android_app_Dialog__show__(ILTweaks.MethodParam param) { 21 | beforeOnClass(EMBED_BOTTOM_SHEET, param, () -> { 22 | Logger.v("Set dark background on webView, in EmbedBottomSheet."); 23 | WebView webView = (WebView) ReflectUtils.getObjectField(param.thisObject, "webView"); 24 | webView.setBackgroundColor(Color.BLACK); 25 | }); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/communication/TelegramEditTextNoFocusFirst.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.communication; 2 | 3 | import li.lingfeng.ltsystem.ILTweaks; 4 | import li.lingfeng.ltsystem.R; 5 | import li.lingfeng.ltsystem.lib.MethodsLoad; 6 | import li.lingfeng.ltsystem.prefs.PackageNames; 7 | import li.lingfeng.ltsystem.tweaks.TweakBase; 8 | import li.lingfeng.ltsystem.utils.Logger; 9 | 10 | @MethodsLoad(packages = PackageNames.TELEGRAM, prefs = R.string.key_telegram_edittext_no_focus_first) 11 | public class TelegramEditTextNoFocusFirst extends TweakBase { 12 | 13 | private static final String CHAT_ACTIVITY_ENTER_VIEW = "org.telegram.ui.Components.ChatActivityEnterView"; 14 | 15 | @Override 16 | public void android_view_View__requestFocus__(ILTweaks.MethodParam param) { 17 | param.before(() -> { 18 | if (param.thisObject.getClass().getName().startsWith(CHAT_ACTIVITY_ENTER_VIEW)) { 19 | StackTraceElement[] elements = Thread.currentThread().getStackTrace(); 20 | for (int i = 0; i < Math.min(10, elements.length); ++i) { 21 | StackTraceElement element = elements[i]; 22 | if (element.getClassName().equals("android.widget.TextView")) { 23 | return; 24 | } 25 | } 26 | Logger.v("EditText no focus without keyboard."); 27 | param.setResult(false); 28 | } 29 | }); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/communication/TelegramHideSticker.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.communication; 2 | 3 | import li.lingfeng.ltsystem.ILTweaks; 4 | import li.lingfeng.ltsystem.R; 5 | import li.lingfeng.ltsystem.lib.MethodsLoad; 6 | import li.lingfeng.ltsystem.prefs.PackageNames; 7 | import li.lingfeng.ltsystem.tweaks.TweakBase; 8 | import li.lingfeng.ltsystem.utils.Logger; 9 | import li.lingfeng.ltsystem.utils.ReflectUtils; 10 | 11 | @MethodsLoad(packages = PackageNames.TELEGRAM, prefs = R.string.key_telegram_hide_sticker) 12 | public class TelegramHideSticker extends TweakBase { 13 | 14 | private static final String CHAT_MESSAGE_CALL = "org.telegram.ui.Cells.ChatMessageCell"; 15 | 16 | @Override 17 | public void android_view_View__setMeasuredDimension__int_int(ILTweaks.MethodParam param) { 18 | beforeOnClass(CHAT_MESSAGE_CALL, param, () -> { 19 | Object messageObject = ReflectUtils.getObjectField(param.thisObject, "currentMessageObject"); 20 | if (messageObject == null) { 21 | Logger.w("currentMessageObject is null."); 22 | return; 23 | } 24 | if ((boolean) ReflectUtils.callMethod(messageObject, "isAnyKindOfSticker")) { 25 | Logger.v("Hide sticker " + messageObject.hashCode()); 26 | param.setArg(1, 1); 27 | } 28 | }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/communication/WeChatIncomingRingtone.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.communication; 2 | 3 | import android.content.Context; 4 | import android.net.Uri; 5 | 6 | import li.lingfeng.ltsystem.ILTweaks; 7 | import li.lingfeng.ltsystem.R; 8 | import li.lingfeng.ltsystem.lib.MethodsLoad; 9 | import li.lingfeng.ltsystem.prefs.PackageNames; 10 | import li.lingfeng.ltsystem.prefs.Prefs; 11 | import li.lingfeng.ltsystem.tweaks.TweakBase; 12 | import li.lingfeng.ltsystem.utils.Logger; 13 | 14 | @MethodsLoad(packages = PackageNames.WE_CHAT, prefs = R.string.key_wechat_use_incoming_ringtone) 15 | public class WeChatIncomingRingtone extends TweakBase { 16 | 17 | @Override 18 | public void android_media_MediaPlayer__setDataSource__Context_Uri_Map_List(ILTweaks.MethodParam param) { 19 | param.before(() -> { 20 | Context context = (Context) param.args[0]; 21 | Uri uri = (Uri) param.args[1]; 22 | Logger.i("Setting media source, original is " + uri.toString()); 23 | 24 | int idPhonering = context.getResources().getIdentifier("phonering", "raw", "com.tencent.mm"); 25 | if (uri.toString().equals("android.resource://com.tencent.mm/" + idPhonering)) { 26 | String path = Prefs.instance().getString(R.string.key_wechat_set_incoming_ringtone, ""); 27 | param.setArg(1, Uri.parse(path)); 28 | Logger.i("Media source is changed to " + path); 29 | } 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/communication/WeChatMapDaytimeMode.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.communication; 2 | 3 | import android.app.Activity; 4 | import android.view.View; 5 | 6 | import li.lingfeng.ltsystem.ILTweaks; 7 | import li.lingfeng.ltsystem.R; 8 | import li.lingfeng.ltsystem.lib.MethodsLoad; 9 | import li.lingfeng.ltsystem.prefs.PackageNames; 10 | import li.lingfeng.ltsystem.tweaks.TweakBase; 11 | import li.lingfeng.ltsystem.utils.Logger; 12 | import li.lingfeng.ltsystem.utils.ReflectUtils; 13 | import li.lingfeng.ltsystem.utils.ViewUtils; 14 | 15 | @MethodsLoad(packages = PackageNames.WE_CHAT, prefs = R.string.key_wechat_map_daytime_mode) 16 | public class WeChatMapDaytimeMode extends TweakBase { 17 | 18 | private static final String LOCATION_ACTIVITY = "com.tencent.mm.plugin.location_soso.SoSoProxyUI"; 19 | private static final String MAP_VIEW = "com.tencent.tencentmap.mapsdk.maps.MapView"; 20 | private static final int MAP_TYPE_NORMAL = 1000; 21 | 22 | @Override 23 | public void android_app_Activity__performCreate__Bundle_PersistableBundle(ILTweaks.MethodParam param) { 24 | afterOnClass(LOCATION_ACTIVITY, param, () -> { 25 | Logger.v("Set map to daytime mode."); 26 | Activity activity = (Activity) param.thisObject; 27 | View mapView = ViewUtils.findViewByType(activity, findClass(MAP_VIEW)); 28 | Object map = ReflectUtils.callMethod(mapView, "getMap"); 29 | ReflectUtils.callMethod(map, "setMapType", new Object[] { 30 | MAP_TYPE_NORMAL 31 | }, new Class[] { 32 | int.class 33 | }); 34 | }); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/communication/WeiboShareMoveTaskToBack.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.communication; 2 | 3 | import li.lingfeng.ltsystem.R; 4 | import li.lingfeng.ltsystem.lib.MethodsLoad; 5 | import li.lingfeng.ltsystem.prefs.PackageNames; 6 | import li.lingfeng.ltsystem.tweaks.TweakMoveTaskToBack; 7 | 8 | @MethodsLoad(packages = PackageNames.WEIBO_SHARE, prefs = R.string.key_weibo_share_move_task_to_back) 9 | public class WeiboShareMoveTaskToBack extends TweakMoveTaskToBack { 10 | 11 | private static final String LAUNCHER = "com.hengye.share.Launcher"; 12 | 13 | @Override 14 | protected String getLaunchActivity() { 15 | return LAUNCHER; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/entertainment/BilibiliDisableTeenModeHint.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.entertainment; 2 | 3 | import android.content.Intent; 4 | 5 | import li.lingfeng.ltsystem.ILTweaks; 6 | import li.lingfeng.ltsystem.R; 7 | import li.lingfeng.ltsystem.lib.MethodsLoad; 8 | import li.lingfeng.ltsystem.prefs.PackageNames; 9 | import li.lingfeng.ltsystem.tweaks.TweakBase; 10 | import li.lingfeng.ltsystem.utils.Logger; 11 | 12 | @MethodsLoad(packages = PackageNames.BILIBILI, prefs = R.string.key_bilibili_disable_teen_mode_hint) 13 | public class BilibiliDisableTeenModeHint extends TweakBase { 14 | 15 | private static final String TEEN_MODE_DIALOG_ACTIVITY = "com.bilibili.teenagersmode.ui.TeenagersModeDialogActivity"; 16 | 17 | @Override 18 | public void android_app_Activity__startActivityForResult__Intent_int_Bundle(ILTweaks.MethodParam param) { 19 | param.before(() -> { 20 | Intent intent = (Intent) param.args[0]; 21 | if (intent.getComponent() != null && intent.getComponent().getClassName().equals(TEEN_MODE_DIALOG_ACTIVITY)) { 22 | Logger.v("Disable teen mode dialog hint."); 23 | param.setResult(null); 24 | } 25 | }); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/entertainment/BilibiliHideFollow.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.entertainment; 2 | 3 | import android.app.Activity; 4 | import android.view.View; 5 | 6 | import li.lingfeng.ltsystem.ILTweaks; 7 | import li.lingfeng.ltsystem.R; 8 | import li.lingfeng.ltsystem.lib.MethodsLoad; 9 | import li.lingfeng.ltsystem.prefs.PackageNames; 10 | import li.lingfeng.ltsystem.tweaks.TweakBase; 11 | import li.lingfeng.ltsystem.utils.Logger; 12 | import li.lingfeng.ltsystem.utils.ViewUtils; 13 | 14 | @MethodsLoad(packages = PackageNames.BILIBILI, prefs = R.string.key_bilibili_hide_follow) 15 | public class BilibiliHideFollow extends TweakBase { 16 | 17 | private static final String AUTHOR_SPACE_ACTIVITY = "com.bilibili.app.authorspace.ui.AuthorSpaceActivity"; 18 | 19 | @Override 20 | public void android_app_Activity__performCreate__Bundle_PersistableBundle(ILTweaks.MethodParam param) { 21 | afterOnClass(AUTHOR_SPACE_ACTIVITY, param, () -> { 22 | Activity activity = (Activity) param.thisObject; 23 | View followGuideView = ViewUtils.findViewByName(activity, "follow_guide"); 24 | if (followGuideView != null) { 25 | Logger.v("Remove follow_guide."); 26 | ViewUtils.removeView(followGuideView); 27 | } 28 | }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/entertainment/BilibiliKeepBrightness.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.entertainment; 2 | 3 | import android.view.WindowManager; 4 | 5 | import li.lingfeng.ltsystem.ILTweaks; 6 | import li.lingfeng.ltsystem.R; 7 | import li.lingfeng.ltsystem.lib.MethodsLoad; 8 | import li.lingfeng.ltsystem.prefs.PackageNames; 9 | import li.lingfeng.ltsystem.tweaks.TweakBase; 10 | import li.lingfeng.ltsystem.utils.Logger; 11 | 12 | @MethodsLoad(packages = PackageNames.BILIBILI, prefs = R.string.key_bilibili_keep_brightness) 13 | public class BilibiliKeepBrightness extends TweakBase { 14 | 15 | @Override 16 | public void com_android_internal_policy_PhoneWindow__setAttributes__WindowManager$LayoutParams(ILTweaks.MethodParam param) { 17 | param.before(() -> { 18 | WindowManager.LayoutParams params = (WindowManager.LayoutParams) param.args[0]; 19 | if (params.screenBrightness != WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE) { 20 | Logger.v("Keep current brightness instead of " + params.screenBrightness); 21 | params.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE; 22 | } 23 | }); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/entertainment/BilibiliRemoveUpperAd.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.entertainment; 2 | 3 | import android.app.Activity; 4 | import android.view.View; 5 | 6 | import li.lingfeng.ltsystem.ILTweaks; 7 | import li.lingfeng.ltsystem.R; 8 | import li.lingfeng.ltsystem.lib.MethodsLoad; 9 | import li.lingfeng.ltsystem.prefs.PackageNames; 10 | import li.lingfeng.ltsystem.tweaks.TweakBase; 11 | import li.lingfeng.ltsystem.utils.ViewUtils; 12 | 13 | @MethodsLoad(packages = PackageNames.BILIBILI, prefs = R.string.key_bilibili_remove_upper_ad) 14 | public class BilibiliRemoveUpperAd extends TweakBase { 15 | 16 | private static final String VIDEO_DETAILS_ACTIVITY = "com.bilibili.video.videodetail.VideoDetailsActivity"; 17 | 18 | @Override 19 | public void android_app_Activity__performCreate__Bundle_PersistableBundle(ILTweaks.MethodParam param) { 20 | afterOnClass(VIDEO_DETAILS_ACTIVITY, param, () -> { 21 | Activity activity = (Activity) param.thisObject; 22 | View adContainer = ViewUtils.findViewByName(activity, "upper_ad_container"); 23 | adContainer.setVisibility(View.GONE); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/entertainment/DoubanMoveTaskToBack.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.entertainment; 2 | 3 | import li.lingfeng.ltsystem.R; 4 | import li.lingfeng.ltsystem.lib.MethodsLoad; 5 | import li.lingfeng.ltsystem.prefs.PackageNames; 6 | import li.lingfeng.ltsystem.tweaks.TweakMoveTaskToBack; 7 | 8 | @MethodsLoad(packages = PackageNames.DOUBAN, prefs = R.string.key_douban_move_task_to_back) 9 | public class DoubanMoveTaskToBack extends TweakMoveTaskToBack { 10 | 11 | private static final String SPLASH_ACTIVITY = "com.douban.frodo.activity.SplashActivity"; 12 | 13 | @Override 14 | protected String getLaunchActivity() { 15 | return SPLASH_ACTIVITY; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/entertainment/SteamChinese.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.entertainment; 2 | 3 | import android.content.Context; 4 | import android.content.res.Configuration; 5 | 6 | import java.util.Locale; 7 | 8 | import li.lingfeng.ltsystem.ILTweaks; 9 | import li.lingfeng.ltsystem.R; 10 | import li.lingfeng.ltsystem.lib.MethodsLoad; 11 | import li.lingfeng.ltsystem.prefs.PackageNames; 12 | import li.lingfeng.ltsystem.tweaks.TweakBase; 13 | import li.lingfeng.ltsystem.utils.Logger; 14 | 15 | @MethodsLoad(packages = PackageNames.STEAM, prefs = R.string.key_steam_chinese) 16 | public class SteamChinese extends TweakBase { 17 | 18 | // https://github.com/Flo354/XposedAppLocale/blob/master/app/src/main/java/com/flo354/xposed/applocale/XposedMod.java 19 | @Override 20 | public void android_content_ContextWrapper__attachBaseContext__Context(ILTweaks.MethodParam param) { 21 | param.before(() -> { 22 | if (param.args[0] == null || !(param.args[0] instanceof Context)) { 23 | Logger.stackTrace("null ??? " + param.args[0]); 24 | return; 25 | } 26 | Logger.i("Set zh-CN locale."); 27 | Context context = (Context) param.args[0]; 28 | Configuration config = new Configuration(context.getResources().getConfiguration()); 29 | config.setLocale(new Locale("zh", "CN")); 30 | context = context.createConfigurationContext(config); 31 | param.setArg(0, context); 32 | }); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/entertainment/SteamDatabase.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.entertainment; 2 | 3 | import android.app.Activity; 4 | import android.view.MenuItem; 5 | import android.widget.Toast; 6 | 7 | import java.util.regex.Matcher; 8 | import java.util.regex.Pattern; 9 | 10 | import li.lingfeng.ltsystem.R; 11 | import li.lingfeng.ltsystem.lib.MethodsLoad; 12 | import li.lingfeng.ltsystem.prefs.PackageNames; 13 | import li.lingfeng.ltsystem.utils.ContextUtils; 14 | 15 | @MethodsLoad(packages = PackageNames.STEAM, prefs = R.string.key_steam_database) 16 | public class SteamDatabase extends SteamBase { 17 | 18 | @Override 19 | protected String newMenuName() { 20 | return "Steam Database"; 21 | } 22 | 23 | @Override 24 | protected int newMenuPriority() { 25 | return 4; 26 | } 27 | 28 | @Override 29 | protected int newMenuShowAsAction() { 30 | return MenuItem.SHOW_AS_ACTION_NEVER; 31 | } 32 | 33 | @Override 34 | protected void menuItemSelected(Activity activity) throws Throwable { 35 | String url = getUrl(activity); 36 | if (url == null) { 37 | return; 38 | } 39 | 40 | Pattern pattern = Pattern.compile("^https?://store\\.steampowered\\.com/app/(\\d+)/"); 41 | Matcher matcher = pattern.matcher(url); 42 | if (!matcher.find()) { 43 | Toast.makeText(activity, "Can't find game id.", Toast.LENGTH_SHORT).show(); 44 | return; 45 | } 46 | 47 | String gameId = matcher.group(1); 48 | ContextUtils.startBrowser(activity, "https://steamdb.info/app/" + gameId + "/"); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/entertainment/SteamGoReviews.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.entertainment; 2 | 3 | import android.app.Activity; 4 | import android.view.MenuItem; 5 | 6 | import li.lingfeng.ltsystem.R; 7 | import li.lingfeng.ltsystem.lib.MethodsLoad; 8 | import li.lingfeng.ltsystem.prefs.PackageNames; 9 | import li.lingfeng.ltsystem.utils.Logger; 10 | import li.lingfeng.ltsystem.utils.ViewUtils; 11 | 12 | @MethodsLoad(packages = PackageNames.STEAM, prefs = R.string.key_steam_go_reviews) 13 | public class SteamGoReviews extends SteamBase { 14 | 15 | @Override 16 | protected String newMenuName() { 17 | return "Go Reviews"; 18 | } 19 | 20 | @Override 21 | protected int newMenuPriority() { 22 | return 2; 23 | } 24 | 25 | @Override 26 | protected int newMenuShowAsAction() { 27 | return MenuItem.SHOW_AS_ACTION_NEVER; 28 | } 29 | 30 | @Override 31 | protected void menuItemSelected(Activity activity) throws Throwable { 32 | Logger.i("Steam go reviews."); 33 | ViewUtils.executeJs(getWebView(activity), "document.getElementById('Reviews_summary').scrollIntoView();"); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/entertainment/SteamGoTop.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.entertainment; 2 | 3 | import android.app.Activity; 4 | import android.view.MenuItem; 5 | 6 | import li.lingfeng.ltsystem.R; 7 | import li.lingfeng.ltsystem.lib.MethodsLoad; 8 | import li.lingfeng.ltsystem.prefs.PackageNames; 9 | import li.lingfeng.ltsystem.utils.Logger; 10 | import li.lingfeng.ltsystem.utils.ViewUtils; 11 | 12 | @MethodsLoad(packages = PackageNames.STEAM, prefs = R.string.key_steam_go_top) 13 | public class SteamGoTop extends SteamBase { 14 | 15 | @Override 16 | protected String newMenuName() { 17 | return "Go Top"; 18 | } 19 | 20 | @Override 21 | protected int newMenuPriority() { 22 | return 1; 23 | } 24 | 25 | @Override 26 | protected int newMenuShowAsAction() { 27 | return MenuItem.SHOW_AS_ACTION_NEVER; 28 | } 29 | 30 | @Override 31 | protected void menuItemSelected(Activity activity) throws Throwable { 32 | Logger.i("Steam go top."); 33 | ViewUtils.executeJs(getWebView(activity), 34 | "if (document.getElementsByClassName('page_title_area game_title_area page_content').length > 0) {\n" 35 | + " document.getElementsByClassName('page_title_area game_title_area page_content')[0].scrollIntoView();\n" 36 | + "} else {\n" 37 | + " window.scrollTo(0, 0);\n" 38 | + "}"); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/entertainment/SteamShare.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.entertainment; 2 | 3 | import android.app.Activity; 4 | import android.view.MenuItem; 5 | 6 | import li.lingfeng.ltsystem.R; 7 | import li.lingfeng.ltsystem.lib.MethodsLoad; 8 | import li.lingfeng.ltsystem.prefs.PackageNames; 9 | import li.lingfeng.ltsystem.utils.ShareUtils; 10 | 11 | @MethodsLoad(packages = PackageNames.STEAM, prefs = R.string.key_steam_share_url) 12 | public class SteamShare extends SteamBase { 13 | @Override 14 | protected String newMenuName() { 15 | return "Share"; 16 | } 17 | 18 | @Override 19 | protected int newMenuPriority() { 20 | return 3; 21 | } 22 | 23 | @Override 24 | protected int newMenuShowAsAction() { 25 | return MenuItem.SHOW_AS_ACTION_NEVER; 26 | } 27 | 28 | @Override 29 | protected void menuItemSelected(Activity activity) throws Throwable { 30 | String url = getUrl(activity); 31 | if (url != null) { 32 | ShareUtils.shareText(activity, url); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/entertainment/TachiyomiDarkenStartingWindow.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.entertainment; 2 | 3 | import android.graphics.drawable.ColorDrawable; 4 | import android.view.Window; 5 | 6 | import li.lingfeng.ltsystem.ILTweaks; 7 | import li.lingfeng.ltsystem.R; 8 | import li.lingfeng.ltsystem.lib.MethodsLoad; 9 | import li.lingfeng.ltsystem.prefs.PackageNames; 10 | import li.lingfeng.ltsystem.tweaks.TweakBase; 11 | import li.lingfeng.ltsystem.utils.Logger; 12 | 13 | @MethodsLoad(packages = PackageNames.ANDROID, prefs = R.string.key_tachiyomi_darken) 14 | public class TachiyomiDarkenStartingWindow extends TweakBase { 15 | 16 | @Override 17 | public void com_android_internal_policy_PhoneWindow__generateLayout__DecorView(ILTweaks.MethodParam param) { 18 | param.before(() -> { 19 | Window window = (Window) param.thisObject; 20 | if (window.getContext().getPackageName().equals(PackageNames.TACHIYOMI)) { 21 | ColorDrawable drawable = new ColorDrawable(0x1C1C1D); 22 | Logger.i("Set night background for Tachiyomi phone window."); 23 | window.setBackgroundDrawable(drawable); 24 | window.setNavigationBarColor(0x1C1C1D); 25 | } 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/google/ChromeArchiveIs.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.google; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import li.lingfeng.ltsystem.R; 7 | import li.lingfeng.ltsystem.lib.MethodsLoad; 8 | import li.lingfeng.ltsystem.prefs.PackageNames; 9 | import li.lingfeng.ltsystem.utils.ContextUtils; 10 | 11 | @MethodsLoad(packages = { 12 | PackageNames.CHROME, 13 | PackageNames.CHROME_BETA, 14 | PackageNames.CHROME_DEV, 15 | PackageNames.CHROME_CANARY 16 | }, prefs = R.string.key_chrome_archive_is) 17 | public class ChromeArchiveIs extends ChromeBase { 18 | 19 | @Override 20 | protected Map newMenus() { 21 | Map infos = new HashMap<>(1); 22 | String title = ContextUtils.getLString(R.string.chrome_archive_is); 23 | infos.put(title, new MenuInfo(title, 1004, (activity, url, isCustomTab) -> { 24 | loadUrl(activity, "https://archive.is/newest/" + url); 25 | })); 26 | return infos; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/google/ChromeCache.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.google; 2 | 3 | import android.net.Uri; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | import li.lingfeng.ltsystem.R; 9 | import li.lingfeng.ltsystem.lib.MethodsLoad; 10 | import li.lingfeng.ltsystem.prefs.PackageNames; 11 | import li.lingfeng.ltsystem.utils.ContextUtils; 12 | 13 | @MethodsLoad(packages = { 14 | PackageNames.CHROME, 15 | PackageNames.CHROME_BETA, 16 | PackageNames.CHROME_DEV, 17 | PackageNames.CHROME_CANARY 18 | }, prefs = R.string.key_chrome_google_cache) 19 | public class ChromeCache extends ChromeBase { 20 | 21 | @Override 22 | protected Map newMenus() { 23 | Map infos = new HashMap<>(1); 24 | String title = ContextUtils.getLString(R.string.chrome_google_cache); 25 | infos.put(title, new MenuInfo(title, 1002, (activity, url, isCustomTab) -> { 26 | String cachedUrl = (url.startsWith("https") ? "https" : "http") + "://webcache.googleusercontent.com/search?q=cache:" 27 | + Uri.encode(url); 28 | loadUrl(activity, cachedUrl); 29 | })); 30 | return infos; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/google/ChromeGoTopOrBottom.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.google; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import li.lingfeng.ltsystem.R; 7 | import li.lingfeng.ltsystem.lib.MethodsLoad; 8 | import li.lingfeng.ltsystem.prefs.PackageNames; 9 | import li.lingfeng.ltsystem.utils.ContextUtils; 10 | 11 | @MethodsLoad(packages = { 12 | PackageNames.CHROME, 13 | PackageNames.CHROME_BETA, 14 | PackageNames.CHROME_DEV, 15 | PackageNames.CHROME_CANARY 16 | }, prefs = R.string.key_chrome_go_top_or_bottom) 17 | public class ChromeGoTopOrBottom extends ChromeBase { 18 | 19 | @Override 20 | protected Map newMenus() { 21 | Map infos = new HashMap<>(2); 22 | String title = ContextUtils.getLString(R.string.chrome_go_top); 23 | infos.put(title, new MenuInfo(title, 1005, (activity, url, isCustomTab) -> { 24 | loadUrl(activity, "javascript:window.scrollTo(0, 0);"); 25 | })); 26 | title = ContextUtils.getLString(R.string.chrome_go_bottom); 27 | infos.put(title, new MenuInfo(title, 1006, (activity, url, isCustomTab) -> { 28 | loadUrl(activity, "javascript:window.scrollTo(0, document.body.scrollHeight);"); 29 | })); 30 | return infos; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/google/ChromeWayback.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.google; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import li.lingfeng.ltsystem.R; 7 | import li.lingfeng.ltsystem.lib.MethodsLoad; 8 | import li.lingfeng.ltsystem.prefs.PackageNames; 9 | import li.lingfeng.ltsystem.utils.ContextUtils; 10 | 11 | @MethodsLoad(packages = { 12 | PackageNames.CHROME, 13 | PackageNames.CHROME_BETA, 14 | PackageNames.CHROME_DEV, 15 | PackageNames.CHROME_CANARY 16 | }, prefs = R.string.key_chrome_wayback) 17 | public class ChromeWayback extends ChromeBase { 18 | 19 | @Override 20 | protected Map newMenus() { 21 | Map infos = new HashMap<>(1); 22 | String title = ContextUtils.getLString(R.string.chrome_wayback_machine); 23 | infos.put(title, new MenuInfo(title, 1003, (activity, url, isCustomTab) -> { 24 | loadUrl(activity, "https://web.archive.org/web/*/" + url); 25 | })); 26 | return infos; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/google/GoogleMapChinese.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.google; 2 | 3 | import android.content.Context; 4 | import android.content.res.Configuration; 5 | 6 | import java.util.Locale; 7 | 8 | import li.lingfeng.ltsystem.ILTweaks; 9 | import li.lingfeng.ltsystem.R; 10 | import li.lingfeng.ltsystem.lib.MethodsLoad; 11 | import li.lingfeng.ltsystem.prefs.PackageNames; 12 | import li.lingfeng.ltsystem.tweaks.TweakBase; 13 | import li.lingfeng.ltsystem.utils.Logger; 14 | 15 | @MethodsLoad(packages = PackageNames.GOOGLE_MAP, prefs = R.string.key_google_map_chinese) 16 | public class GoogleMapChinese extends TweakBase { 17 | 18 | @Override 19 | public void android_content_ContextWrapper__attachBaseContext__Context(ILTweaks.MethodParam param) { 20 | param.before(() -> { 21 | if (param.args[0] == null || !(param.args[0] instanceof Context)) { 22 | Logger.stackTrace("null ??? " + param.args[0]); 23 | return; 24 | } 25 | Logger.i("Set zh-CN locale."); 26 | Context context = (Context) param.args[0]; 27 | Configuration config = new Configuration(context.getResources().getConfiguration()); 28 | config.setLocale(new Locale("zh", "CN")); 29 | context = context.createConfigurationContext(config); 30 | param.setArg(0, context); 31 | }); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/google/GooglePhotosHideSuggestiion.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.google; 2 | 3 | import android.view.View; 4 | 5 | import li.lingfeng.ltsystem.ILTweaks; 6 | import li.lingfeng.ltsystem.R; 7 | import li.lingfeng.ltsystem.lib.MethodsLoad; 8 | import li.lingfeng.ltsystem.prefs.PackageNames; 9 | import li.lingfeng.ltsystem.tweaks.TweakBase; 10 | import li.lingfeng.ltsystem.utils.ContextUtils; 11 | import li.lingfeng.ltsystem.utils.Logger; 12 | 13 | @MethodsLoad(packages = PackageNames.GOOGLE_PHOTOS, prefs = R.string.key_google_photos_hide_suggestion) 14 | public class GooglePhotosHideSuggestiion extends TweakBase { 15 | 16 | private int mId = -1; 17 | 18 | @Override 19 | public void android_view_View__setVisibility__int(ILTweaks.MethodParam param) { 20 | param.before(() -> { 21 | if (mId == -1) { 22 | mId = ContextUtils.getIdId("suggested_action_inflated_view"); 23 | } 24 | if (mId > 0 && ((View) param.thisObject).getId() == mId && (int) param.args[0] == View.VISIBLE) { 25 | Logger.v("Hide suggested_action_inflated_view."); 26 | param.setResult(null); 27 | } 28 | }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/google/GooglePhotosShareFix.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.google; 2 | 3 | import android.content.Intent; 4 | 5 | import li.lingfeng.ltsystem.ILTweaks; 6 | import li.lingfeng.ltsystem.R; 7 | import li.lingfeng.ltsystem.lib.MethodsLoad; 8 | import li.lingfeng.ltsystem.prefs.PackageNames; 9 | import li.lingfeng.ltsystem.tweaks.TweakBase; 10 | 11 | @MethodsLoad(packages = PackageNames.GOOGLE_PHOTOS, prefs = R.string.key_google_photos_share_fix) 12 | public class GooglePhotosShareFix extends TweakBase { 13 | 14 | @Override 15 | public void android_app_Activity__startActivityForResult__Intent_int_Bundle(ILTweaks.MethodParam param) { 16 | param.before(() -> { 17 | Intent intent = (Intent) param.args[0]; 18 | if (Intent.ACTION_SEND.equals(intent.getAction()) || Intent.ACTION_SEND_MULTIPLE.equals(intent.getAction())) { 19 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT); 20 | } 21 | }); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/google/GooglePlayServicesDismissSystemUpdate.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.google; 2 | 3 | import android.app.Activity; 4 | 5 | import li.lingfeng.ltsystem.ILTweaks; 6 | import li.lingfeng.ltsystem.R; 7 | import li.lingfeng.ltsystem.lib.MethodsLoad; 8 | import li.lingfeng.ltsystem.prefs.PackageNames; 9 | import li.lingfeng.ltsystem.tweaks.TweakBase; 10 | import li.lingfeng.ltsystem.utils.Logger; 11 | 12 | @MethodsLoad(packages = PackageNames.GMS, prefs = R.string.key_google_play_services_dismiss_system_update) 13 | public class GooglePlayServicesDismissSystemUpdate extends TweakBase { 14 | 15 | private static final String UPDATE_DIALOG = "com.google.android.gms.update.phone.PopupDialog"; 16 | 17 | @Override 18 | public void android_app_Activity__performCreate__Bundle_PersistableBundle(ILTweaks.MethodParam param) { 19 | afterOnClass(UPDATE_DIALOG, param, () -> { 20 | Logger.v("Dismiss system update dialog."); 21 | Activity activity = (Activity) param.thisObject; 22 | activity.finish(); 23 | }); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/google/YoutubeDarkenStartingWindow.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.google; 2 | 3 | import android.content.Context; 4 | import android.graphics.Color; 5 | import android.graphics.drawable.ColorDrawable; 6 | import android.graphics.drawable.Drawable; 7 | import android.view.View; 8 | import android.view.Window; 9 | 10 | import li.lingfeng.ltsystem.ILTweaks; 11 | import li.lingfeng.ltsystem.R; 12 | import li.lingfeng.ltsystem.lib.MethodsLoad; 13 | import li.lingfeng.ltsystem.prefs.PackageNames; 14 | import li.lingfeng.ltsystem.tweaks.TweakBase; 15 | import li.lingfeng.ltsystem.utils.Logger; 16 | 17 | @MethodsLoad(packages = PackageNames.ANDROID, prefs = R.string.key_youtube_darken) 18 | public class YoutubeDarkenStartingWindow extends TweakBase { 19 | 20 | @Override 21 | public void com_android_internal_policy_PhoneWindow__generateLayout__DecorView(ILTweaks.MethodParam param) { 22 | param.after(() -> { 23 | Window window = (Window) param.thisObject; 24 | Context context = window.getContext(); 25 | if (context.getPackageName().equals(PackageNames.YOUTUBE)) { 26 | View decorView = (View) param.args[0]; 27 | if (decorView.getBackground() instanceof ColorDrawable) { 28 | Logger.i("Set night background for Youtube phone window."); 29 | Drawable drawable = new ColorDrawable(0xFF282828); 30 | window.setBackgroundDrawable(drawable); 31 | window.setNavigationBarColor(Color.BLACK); 32 | window.setStatusBarColor(Color.BLACK); 33 | } 34 | } 35 | }); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/shopping/JDAds.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.shopping; 2 | 3 | import android.content.Intent; 4 | 5 | import li.lingfeng.ltsystem.ILTweaks; 6 | import li.lingfeng.ltsystem.R; 7 | import li.lingfeng.ltsystem.lib.MethodsLoad; 8 | import li.lingfeng.ltsystem.prefs.PackageNames; 9 | import li.lingfeng.ltsystem.tweaks.TweakBase; 10 | import li.lingfeng.ltsystem.utils.Logger; 11 | import li.lingfeng.ltsystem.utils.ReflectUtils; 12 | 13 | @MethodsLoad(packages = PackageNames.JD, prefs = R.string.key_jd_ads) 14 | public class JDAds extends TweakBase { 15 | 16 | private static final String MAIN_FRAME_ACTIVITY = "com.jingdong.app.mall.MainFrameActivity"; 17 | private static final String AD_ACTIVITY = "com.jingdong.app.mall.ad.ADActivity"; 18 | private static final String BASE_FRAME_UTIL = "com.jingdong.common.BaseFrameUtil"; 19 | 20 | @Override 21 | public void android_app_Activity__performCreate__Bundle_PersistableBundle(ILTweaks.MethodParam param) { 22 | beforeOnClass(MAIN_FRAME_ACTIVITY, param, () -> { 23 | Logger.d("Set needStartImage false."); 24 | ReflectUtils.setStaticBooleanField(findClass(BASE_FRAME_UTIL), "needStartImage", false); 25 | }); 26 | } 27 | 28 | @Override 29 | public void android_app_Activity__startActivityForResult__Intent_int_Bundle(ILTweaks.MethodParam param) { 30 | param.before(() -> { 31 | Intent intent = (Intent) param.args[0]; 32 | if (intent.getComponent() != null && intent.getComponent().getClassName().equals(AD_ACTIVITY)) { 33 | Logger.v("Ignore ADActivity"); 34 | param.setResult(null); 35 | } 36 | }); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/shopping/JDBasicShare.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.shopping; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | 6 | import li.lingfeng.ltsystem.ILTweaks; 7 | import li.lingfeng.ltsystem.R; 8 | import li.lingfeng.ltsystem.lib.MethodsLoad; 9 | import li.lingfeng.ltsystem.prefs.PackageNames; 10 | import li.lingfeng.ltsystem.tweaks.TweakBase; 11 | import li.lingfeng.ltsystem.utils.Logger; 12 | 13 | @MethodsLoad(packages = PackageNames.JD, prefs = R.string.key_jd_basic_share_activity) 14 | public class JDBasicShare extends TweakBase { 15 | 16 | private static final String SHARE_ACTIVITY = "com.jingdong.app.mall.basic.ShareActivity"; 17 | 18 | @Override 19 | public void android_app_Activity__performCreate__Bundle_PersistableBundle(ILTweaks.MethodParam param) { 20 | beforeOnClass(SHARE_ACTIVITY, param, () -> { 21 | Activity activity = (Activity) param.thisObject; 22 | Intent intent = activity.getIntent(); 23 | int action = intent.getIntExtra("action", 0); 24 | if (action != 1) { 25 | intent.putExtra("action", 1); 26 | Logger.i("ShareActivity action " + action + " -> 1"); 27 | } 28 | }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/shopping/JDHistory.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.shopping; 2 | 3 | import android.app.Activity; 4 | import android.app.AlertDialog; 5 | import android.view.View; 6 | 7 | import li.lingfeng.ltsystem.ILTweaks; 8 | import li.lingfeng.ltsystem.R; 9 | import li.lingfeng.ltsystem.activities.JDHistoryLayout; 10 | import li.lingfeng.ltsystem.lib.MethodsLoad; 11 | import li.lingfeng.ltsystem.prefs.PackageNames; 12 | import li.lingfeng.ltsystem.tweaks.TweakBase; 13 | import li.lingfeng.ltsystem.utils.Logger; 14 | import li.lingfeng.ltsystem.utils.ViewUtils; 15 | 16 | @MethodsLoad(packages = PackageNames.JD, prefs = R.string.key_jd_history) 17 | public class JDHistory extends TweakBase { 18 | 19 | private static final String DETAIL_ACTIVITY = "com.jd.lib.productdetail.ProductDetailActivity"; 20 | 21 | @Override 22 | public void android_app_Activity__performCreate__Bundle_PersistableBundle(ILTweaks.MethodParam param) { 23 | param.before(() -> { 24 | Logger.useRemote("JD"); 25 | }); 26 | afterOnClass(DETAIL_ACTIVITY, param, () -> { 27 | Activity activity = (Activity) param.thisObject; 28 | View shareView = ViewUtils.findViewByName(activity, "pd_nav_share"); 29 | shareView.setOnLongClickListener(view -> { 30 | try { 31 | showHistoryDialog(activity); 32 | } catch (Throwable e) { 33 | Logger.e("showHistoryDialog exception.", e); 34 | } 35 | return true; 36 | }); 37 | }); 38 | } 39 | 40 | private void showHistoryDialog(Activity activity) { 41 | new AlertDialog.Builder(activity) 42 | .setView(new JDHistoryLayout(activity)) 43 | .show(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/shopping/SMZDMSkipSplash.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.shopping; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | 6 | import li.lingfeng.ltsystem.ILTweaks; 7 | import li.lingfeng.ltsystem.R; 8 | import li.lingfeng.ltsystem.lib.MethodsLoad; 9 | import li.lingfeng.ltsystem.prefs.PackageNames; 10 | import li.lingfeng.ltsystem.tweaks.TweakBase; 11 | import li.lingfeng.ltsystem.utils.Logger; 12 | 13 | @MethodsLoad(packages = PackageNames.SMZDM, prefs = R.string.key_smzdm_skip_splash) 14 | public class SMZDMSkipSplash extends TweakBase { 15 | 16 | private static final String WELCOME_ACTIVITY = "com.smzdm.client.android.app.WelComeActivity"; 17 | private static final String HOME_ACTIVITY = "com.smzdm.client.android.app.HomeActivity"; 18 | 19 | @Override 20 | public void android_app_Activity__performCreate__Bundle_PersistableBundle(ILTweaks.MethodParam param) { 21 | afterOnClass(WELCOME_ACTIVITY, param, () -> { 22 | Activity activity = (Activity) param.thisObject; 23 | if (!activity.isFinishing()) { 24 | Logger.v("Skip WelComeActivity."); 25 | Intent intent = new Intent(); 26 | intent.setClassName(PackageNames.SMZDM, HOME_ACTIVITY); 27 | activity.startActivity(intent); 28 | activity.finish(); 29 | } 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/shopping/TaobaoAds.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.shopping; 2 | 3 | import android.content.Intent; 4 | 5 | import li.lingfeng.ltsystem.ILTweaks; 6 | import li.lingfeng.ltsystem.R; 7 | import li.lingfeng.ltsystem.lib.MethodsLoad; 8 | import li.lingfeng.ltsystem.prefs.PackageNames; 9 | import li.lingfeng.ltsystem.tweaks.TweakBase; 10 | import li.lingfeng.ltsystem.utils.Logger; 11 | 12 | @MethodsLoad(packages = PackageNames.TAOBAO, prefs = R.string.key_taobao_ads) 13 | public class TaobaoAds extends TweakBase { 14 | 15 | private static final String BOOT_IMAGE_ACTIVITY = "com.taobao.bootimage.activity.BootImageActivity"; 16 | 17 | @Override 18 | public void android_app_Activity__startActivityForResult__Intent_int_Bundle(ILTweaks.MethodParam param) { 19 | param.before(() -> { 20 | Intent intent = (Intent) param.args[0]; 21 | // action: action.fill.splash.content 22 | if (intent.getComponent() != null && intent.getComponent().getClassName().equals(BOOT_IMAGE_ACTIVITY)) { 23 | Logger.v("Ignore BootImageActivity"); 24 | param.setResult(null); 25 | } 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/system/AppInfoPackageName.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.system; 2 | 3 | import android.content.ClipData; 4 | import android.content.ClipboardManager; 5 | import android.content.Context; 6 | import android.util.Pair; 7 | 8 | import li.lingfeng.ltsystem.ILTweaks; 9 | import li.lingfeng.ltsystem.LTHelper; 10 | import li.lingfeng.ltsystem.R; 11 | import li.lingfeng.ltsystem.lib.MethodsLoad; 12 | import li.lingfeng.ltsystem.prefs.PackageNames; 13 | 14 | @MethodsLoad(packages = PackageNames.ANDROID_SETTINGS, prefs = R.string.key_app_info_package_name) 15 | public class AppInfoPackageName extends AppInfo { 16 | @Override 17 | protected Pair[] newMenuNames(ILTweaks.MethodParam param) throws Throwable { 18 | return new Pair[] { 19 | Pair.create(getPackageName(param), 990) 20 | }; 21 | } 22 | 23 | @Override 24 | protected void menuItemSelected(CharSequence menuName, ILTweaks.MethodParam param) throws Throwable { 25 | ClipboardManager clipboardManager = (ClipboardManager) LTHelper.currentApplication().getSystemService(Context.CLIPBOARD_SERVICE); 26 | clipboardManager.setPrimaryClip(ClipData.newPlainText(null, getPackageName(param))); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/system/Debuggable.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.system; 2 | 3 | import android.content.pm.ApplicationInfo; 4 | 5 | import li.lingfeng.ltsystem.ILTweaks; 6 | import li.lingfeng.ltsystem.R; 7 | import li.lingfeng.ltsystem.lib.MethodsLoad; 8 | import li.lingfeng.ltsystem.prefs.PackageNames; 9 | import li.lingfeng.ltsystem.tweaks.TweakBase; 10 | import li.lingfeng.ltsystem.utils.Logger; 11 | 12 | @MethodsLoad(packages = PackageNames.ANDROID, prefs = R.string.key_debug_debuggable) 13 | public class Debuggable extends TweakBase { 14 | 15 | @Override 16 | public void com_android_server_am_ProcessList__startProcessLocked__String_ApplicationInfo_boolean_int_HostingRecord_boolean_boolean_int_boolean_String_String_String$array_Runnable(ILTweaks.MethodParam param) { 17 | param.before(() -> { 18 | ApplicationInfo info = (ApplicationInfo) param.args[1]; 19 | if (info.packageName.equals(PackageNames.ANDROID)) { 20 | Logger.i("Set FLAG_DEBUGGABLE at startProcessLocked() for all apps."); 21 | } else { 22 | info.flags |= ApplicationInfo.FLAG_DEBUGGABLE; 23 | } 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/system/DenyAccessPhoneNumber.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.system; 2 | 3 | import android.content.pm.ApplicationInfo; 4 | import android.os.Process; 5 | 6 | import li.lingfeng.ltsystem.ILTweaks; 7 | import li.lingfeng.ltsystem.LTHelper; 8 | import li.lingfeng.ltsystem.R; 9 | import li.lingfeng.ltsystem.lib.MethodsLoad; 10 | import li.lingfeng.ltsystem.tweaks.TweakBase; 11 | import li.lingfeng.ltsystem.utils.Logger; 12 | 13 | @MethodsLoad(packages = {}, prefs = R.string.key_phone_deny_access_phone_number) 14 | public class DenyAccessPhoneNumber extends TweakBase { 15 | 16 | @Override 17 | public void android_telephony_TelephonyManager__getLine1Number__int(ILTweaks.MethodParam param) { 18 | handleGet(param, "getLine1Number"); 19 | } 20 | 21 | @Override 22 | public void android_telephony_SubscriptionInfo__getNumber__(ILTweaks.MethodParam param) { 23 | handleGet(param, "getNumber"); 24 | } 25 | 26 | private void handleGet(ILTweaks.MethodParam param, String methodName) { 27 | param.before(() -> { 28 | ApplicationInfo appInfo = LTHelper.currentApplication().getApplicationInfo(); 29 | if (appInfo.uid < Process.FIRST_APPLICATION_UID || appInfo.uid > Process.LAST_APPLICATION_UID) { 30 | return; 31 | } 32 | Logger.d("Deny access phone number from " + methodName + " by " + appInfo.packageName); 33 | param.setResult(null); 34 | }); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/system/Doze.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.system; 2 | 3 | import li.lingfeng.ltsystem.ILTweaks; 4 | import li.lingfeng.ltsystem.R; 5 | import li.lingfeng.ltsystem.lib.MethodsLoad; 6 | import li.lingfeng.ltsystem.prefs.PackageNames; 7 | import li.lingfeng.ltsystem.tweaks.TweakBase; 8 | import li.lingfeng.ltsystem.utils.Logger; 9 | import li.lingfeng.ltsystem.utils.ReflectUtils; 10 | 11 | @MethodsLoad(packages = PackageNames.ANDROID, prefs = R.string.key_phone_doze) 12 | public class Doze extends TweakBase { 13 | 14 | @Override 15 | public void com_android_server_DeviceIdleController__onStart__(ILTweaks.MethodParam param) { 16 | param.after(() -> { 17 | // config_enableAutoPowerModes 18 | Logger.i("DeviceIdleController enable auto power modes."); 19 | ReflectUtils.setBooleanField(param.thisObject, "mLightEnabled", true); 20 | ReflectUtils.setBooleanField(param.thisObject, "mDeepEnabled", true); 21 | }); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/system/ForceGPURendering.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.system; 2 | 3 | import li.lingfeng.ltsystem.ILTweaks; 4 | import li.lingfeng.ltsystem.R; 5 | import li.lingfeng.ltsystem.lib.MethodsLoad; 6 | import li.lingfeng.ltsystem.tweaks.TweakBase; 7 | import li.lingfeng.ltsystem.utils.Logger; 8 | 9 | @MethodsLoad(packages = {}, prefs = R.string.key_display_force_gpu_rendering) 10 | public class ForceGPURendering extends TweakBase { 11 | 12 | @Override 13 | public void android_view_Window__setWindowManager__WindowManager_IBinder_String_boolean(ILTweaks.MethodParam param) { 14 | param.before(() -> { 15 | String appName = (String) param.args[2]; 16 | boolean hardwareAccelerated = (boolean) param.args[3]; 17 | if (!hardwareAccelerated) { 18 | Logger.v("Set hardware accelerated for " + appName); 19 | param.setArg(3, true); 20 | } 21 | }); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/system/HSPAPSignal.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.system; 2 | 3 | import li.lingfeng.ltsystem.ILTweaks; 4 | import li.lingfeng.ltsystem.R; 5 | import li.lingfeng.ltsystem.lib.MethodsLoad; 6 | import li.lingfeng.ltsystem.prefs.PackageNames; 7 | import li.lingfeng.ltsystem.tweaks.TweakBase; 8 | import li.lingfeng.ltsystem.utils.Logger; 9 | import li.lingfeng.ltsystem.utils.ReflectUtils; 10 | 11 | @MethodsLoad(packages = PackageNames.ANDROID_SYSTEM_UI, prefs = R.string.key_display_hspap_signal) 12 | public class HSPAPSignal extends TweakBase { 13 | 14 | @Override 15 | public void com_android_systemui_statusbar_policy_NetworkControllerImpl$Config__readConfig__Context(ILTweaks.MethodParam param) { 16 | param.after(() -> { 17 | Logger.i("Set hspaDataDistinguishable to true."); 18 | ReflectUtils.setBooleanField(param.getResult(), "hspaDataDistinguishable", true); 19 | }); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/system/HiddenApiNoExemptions.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.system; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | 5 | import li.lingfeng.ltsystem.ILTweaks; 6 | import li.lingfeng.ltsystem.R; 7 | import li.lingfeng.ltsystem.lib.MethodsLoad; 8 | import li.lingfeng.ltsystem.prefs.PackageNames; 9 | import li.lingfeng.ltsystem.tweaks.TweakBase; 10 | import li.lingfeng.ltsystem.utils.Logger; 11 | import li.lingfeng.ltsystem.utils.PackageUtils; 12 | 13 | @MethodsLoad(packages = {}, excludedPackages = PackageNames.ANDROID, prefs = R.string.key_debug_hidden_api_no_exemptions) 14 | public class HiddenApiNoExemptions extends TweakBase { 15 | 16 | @Override 17 | public void dalvik_system_VMRuntime__setHiddenApiExemptions__String$array(ILTweaks.MethodParam param) { 18 | param.before(() -> { 19 | if (getPackageName() == null) { 20 | return; 21 | } 22 | if (PackageUtils.isUserInstalledPackage(getPackageName())) { 23 | Logger.d("Hidden API no exemptions for " + getPackageName() + ", " + StringUtils.join(param.args, ", ")); 24 | param.setResult(null); 25 | } 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/system/LightAmberInDaylight.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.system; 2 | 3 | import li.lingfeng.ltsystem.ILTweaks; 4 | import li.lingfeng.ltsystem.R; 5 | import li.lingfeng.ltsystem.lib.MethodsLoad; 6 | import li.lingfeng.ltsystem.prefs.PackageNames; 7 | import li.lingfeng.ltsystem.tweaks.TweakBase; 8 | import li.lingfeng.ltsystem.utils.Logger; 9 | import li.lingfeng.ltsystem.utils.ReflectUtils; 10 | 11 | @MethodsLoad(packages = PackageNames.ANDROID, prefs = R.string.key_display_light_amber_in_daylight) 12 | public class LightAmberInDaylight extends TweakBase { 13 | 14 | private static final String NIGHT_DISPLAY_SERVICE = "com.android.server.display.color.ColorDisplayService"; 15 | private static final float[] MATRIX_LIGHT_AMBER = new float[] { // ~= 5500K 16 | 1, 0, 0, 0, 17 | 0, 0.933f, 0, 0, 18 | 0, 0, 0.870f, 0, 19 | 0, 0, 0, 1 20 | }; 21 | 22 | @Override 23 | public void com_android_server_display_color_ColorDisplayService__static__(ILTweaks.MethodParam param) { 24 | param.after(() -> { 25 | Logger.i("Set light amber in daylight."); 26 | ReflectUtils.setStaticObjectField(findClass(NIGHT_DISPLAY_SERVICE), "MATRIX_IDENTITY", MATRIX_LIGHT_AMBER); 27 | }); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/system/MiXplorerIgnoreCPUUsageKill.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.system; 2 | 3 | import li.lingfeng.ltsystem.ILTweaks; 4 | import li.lingfeng.ltsystem.R; 5 | import li.lingfeng.ltsystem.lib.MethodsLoad; 6 | import li.lingfeng.ltsystem.prefs.PackageNames; 7 | import li.lingfeng.ltsystem.tweaks.TweakBase; 8 | import li.lingfeng.ltsystem.utils.Logger; 9 | import li.lingfeng.ltsystem.utils.ReflectUtils; 10 | 11 | @MethodsLoad(packages = PackageNames.ANDROID, prefs = R.string.key_mixplorer_ignore_cpu_usage_kill) 12 | public class MiXplorerIgnoreCPUUsageKill extends TweakBase { 13 | 14 | @Override 15 | public void com_android_server_am_ProcessRecord__kill__String_boolean(ILTweaks.MethodParam param) { 16 | param.before(() -> { 17 | String processName = (String) ReflectUtils.getObjectField(param.thisObject, "processName"); 18 | if (PackageNames.MIXPLORER.equals(processName)) { 19 | for (StackTraceElement element : Thread.currentThread().getStackTrace()) { 20 | if (element.getMethodName().equals("checkExcessivePowerUsageLocked")) { 21 | Logger.i("com.mixplorer should be killed by \"" + param.args[0] + "\", but keep it."); 22 | param.setResult(null); 23 | return; 24 | } 25 | } 26 | } 27 | }); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/system/NormalizeTranslateFloatingMenu.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.system; 2 | 3 | import android.content.Intent; 4 | import android.content.pm.PackageParser; 5 | 6 | import li.lingfeng.ltsystem.ILTweaks; 7 | import li.lingfeng.ltsystem.R; 8 | import li.lingfeng.ltsystem.lib.MethodsLoad; 9 | import li.lingfeng.ltsystem.prefs.PackageNames; 10 | import li.lingfeng.ltsystem.tweaks.TweakBase; 11 | import li.lingfeng.ltsystem.utils.Logger; 12 | 13 | @MethodsLoad(packages = PackageNames.ANDROID, prefs = R.string.key_text_normalize_translate_menu) 14 | public class NormalizeTranslateFloatingMenu extends TweakBase { 15 | 16 | @Override 17 | public void android_content_pm_PackageParser__parsePackage__File_int_boolean(ILTweaks.MethodParam param) { 18 | param.after(() -> { 19 | PackageParser.Package pkg = (PackageParser.Package) param.getResult(); 20 | if (pkg == null) { 21 | return; 22 | } 23 | for (PackageParser.Activity activity : pkg.activities) { 24 | for (PackageParser.IntentInfo intent : activity.intents) { 25 | if (intent.countActions() > 0 && intent.getAction(0).equals(Intent.ACTION_TRANSLATE)) { 26 | Logger.i("Remove android.intent.action.TRANSLATE from " + activity); 27 | activity.intents.remove(intent); 28 | return; 29 | } 30 | } 31 | } 32 | }); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/system/QuickEditDarkenStartingWindow.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.system; 2 | 3 | import android.graphics.drawable.ColorDrawable; 4 | import android.view.Window; 5 | 6 | import li.lingfeng.ltsystem.ILTweaks; 7 | import li.lingfeng.ltsystem.R; 8 | import li.lingfeng.ltsystem.lib.MethodsLoad; 9 | import li.lingfeng.ltsystem.prefs.PackageNames; 10 | import li.lingfeng.ltsystem.tweaks.TweakBase; 11 | import li.lingfeng.ltsystem.utils.Logger; 12 | 13 | @MethodsLoad(packages = PackageNames.ANDROID, prefs = R.string.key_quick_edit_darken) 14 | public class QuickEditDarkenStartingWindow extends TweakBase { 15 | 16 | @Override 17 | public void com_android_internal_policy_PhoneWindow__generateLayout__DecorView(ILTweaks.MethodParam param) { 18 | param.before(() -> { 19 | Window window = (Window) param.thisObject; 20 | if (window.getContext().getPackageName().equals(PackageNames.QUICK_EDIT)) { 21 | ColorDrawable drawable = new ColorDrawable(0x303030); 22 | Logger.i("Set night background for QuickEdit phone window."); 23 | window.setBackgroundDrawable(drawable); 24 | } 25 | }); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/system/SettingsExpandAll.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.system; 2 | 3 | import li.lingfeng.ltsystem.ILTweaks; 4 | import li.lingfeng.ltsystem.R; 5 | import li.lingfeng.ltsystem.lib.MethodsLoad; 6 | import li.lingfeng.ltsystem.prefs.PackageNames; 7 | import li.lingfeng.ltsystem.tweaks.TweakBase; 8 | import li.lingfeng.ltsystem.utils.Logger; 9 | import li.lingfeng.ltsystem.utils.ReflectUtils; 10 | 11 | @MethodsLoad(packages = PackageNames.ANDROID_SETTINGS, prefs = R.string.key_app_info_settings_expand_all) 12 | public class SettingsExpandAll extends TweakBase { 13 | 14 | @Override 15 | public void com_android_settings_widget_HighlightablePreferenceGroupAdapter__adjustInitialExpandedChildCount__SettingsPreferenceFragment(ILTweaks.MethodParam param) { 16 | param.after(() -> { 17 | Object host = param.args[0]; 18 | if (host != null) { 19 | Object screen = ReflectUtils.callMethod(host, "getPreferenceScreen"); 20 | if (screen != null) { 21 | Logger.v("setInitialExpandedChildrenCount " + screen + " to max."); 22 | ReflectUtils.callMethod(screen, "setInitialExpandedChildrenCount", 23 | new Object[] { Integer.MAX_VALUE }, new Class[] { int.class }); 24 | } 25 | } 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/system/SettingsSuggestionDisable.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.system; 2 | 3 | import android.content.ComponentName; 4 | 5 | import li.lingfeng.ltsystem.ILTweaks; 6 | import li.lingfeng.ltsystem.R; 7 | import li.lingfeng.ltsystem.lib.MethodsLoad; 8 | import li.lingfeng.ltsystem.prefs.PackageNames; 9 | import li.lingfeng.ltsystem.tweaks.TweakBase; 10 | import li.lingfeng.ltsystem.utils.Logger; 11 | 12 | @MethodsLoad(packages = PackageNames.ANDROID_SETTINGS, prefs = R.string.key_app_info_settings_suggestion_disable) 13 | public class SettingsSuggestionDisable extends TweakBase { 14 | 15 | @Override 16 | public void com_android_settings_dashboard_suggestions_SuggestionFeatureProviderImpl__getSuggestionServiceComponent__(ILTweaks.MethodParam param) { 17 | param.before(() -> { 18 | Logger.d("getSuggestionServiceComponent return empty component."); 19 | param.setResult(new ComponentName("", "")); 20 | }); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/system/ShadowsocksHideVPNInfo.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.system; 2 | 3 | import android.util.SparseArray; 4 | 5 | import com.android.internal.net.VpnConfig; 6 | 7 | import li.lingfeng.ltsystem.ILTweaks; 8 | import li.lingfeng.ltsystem.R; 9 | import li.lingfeng.ltsystem.lib.MethodsLoad; 10 | import li.lingfeng.ltsystem.prefs.PackageNames; 11 | import li.lingfeng.ltsystem.tweaks.TweakBase; 12 | import li.lingfeng.ltsystem.utils.Logger; 13 | import li.lingfeng.ltsystem.utils.ReflectUtils; 14 | 15 | @MethodsLoad(packages = PackageNames.ANDROID_SYSTEM_UI, prefs = R.string.key_shadowsocks_hide_vpn_info) 16 | public class ShadowsocksHideVPNInfo extends TweakBase { 17 | 18 | @Override 19 | public void com_android_systemui_statusbar_policy_SecurityControllerImpl__updateState__(ILTweaks.MethodParam param) { 20 | param.after(() -> { 21 | SparseArray currentVpns = (SparseArray) ReflectUtils.getObjectField(param.thisObject, "mCurrentVpns"); 22 | for (int i = currentVpns.size() - 1; i >= 0; --i) { 23 | String packageName = currentVpns.get(i).user; 24 | if (packageName.equals(PackageNames.SHADOWSOCKS)) { 25 | Logger.v("Remove Shadowsocks from SystemUI."); 26 | currentVpns.removeAt(i); 27 | } 28 | } 29 | }); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/system/SolidExplorerDarkenStartingWindow.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.system; 2 | 3 | import android.graphics.drawable.ColorDrawable; 4 | import android.view.Window; 5 | 6 | import li.lingfeng.ltsystem.ILTweaks; 7 | import li.lingfeng.ltsystem.R; 8 | import li.lingfeng.ltsystem.lib.MethodsLoad; 9 | import li.lingfeng.ltsystem.prefs.PackageNames; 10 | import li.lingfeng.ltsystem.tweaks.TweakBase; 11 | import li.lingfeng.ltsystem.utils.Logger; 12 | 13 | @MethodsLoad(packages = PackageNames.ANDROID, prefs = R.string.key_solid_explorer_darken) 14 | public class SolidExplorerDarkenStartingWindow extends TweakBase { 15 | 16 | @Override 17 | public void com_android_internal_policy_PhoneWindow__generateLayout__DecorView(ILTweaks.MethodParam param) { 18 | param.before(() -> { 19 | Window window = (Window) param.thisObject; 20 | if (window.getContext().getPackageName().equals(PackageNames.SOLID_EXPLORER)) { 21 | ColorDrawable drawable = new ColorDrawable(0x303030); 22 | Logger.i("Set night background for solid explorer phone window."); 23 | window.setBackgroundDrawable(drawable); 24 | } 25 | }); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/tweaks/system/WebSearchGoBrowser.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.tweaks.system; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.net.Uri; 6 | 7 | import li.lingfeng.ltsystem.ILTweaks; 8 | import li.lingfeng.ltsystem.R; 9 | import li.lingfeng.ltsystem.lib.MethodsLoad; 10 | import li.lingfeng.ltsystem.prefs.PackageNames; 11 | import li.lingfeng.ltsystem.tweaks.TweakBase; 12 | import li.lingfeng.ltsystem.utils.ContextUtils; 13 | 14 | @MethodsLoad(packages = {}, prefs = R.string.key_web_search_to_browser, excludedPackages = PackageNames.ANDROID) 15 | public class WebSearchGoBrowser extends TweakBase { 16 | 17 | @Override 18 | public void android_app_Activity__startActivityForResult__Intent_int_Bundle(ILTweaks.MethodParam param) { 19 | param.before(() -> { 20 | Intent intent = (Intent) param.args[0]; 21 | if (Intent.ACTION_WEB_SEARCH.equals(intent.getAction())) { 22 | String query = intent.getStringExtra("query"); 23 | String url = "https://www.google.com/search?q=" + Uri.encode(query); 24 | Activity activity = (Activity) param.thisObject; 25 | ContextUtils.startBrowser(activity, url); 26 | param.setResult(null); 27 | } 28 | }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/utils/Callback.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.utils; 2 | 3 | /** 4 | * Created by smallville on 2017/6/2. 5 | */ 6 | 7 | public class Callback { 8 | public static interface C0 { 9 | void onResult(); 10 | } 11 | 12 | public static interface C1 { 13 | void onResult(A a); 14 | } 15 | 16 | public static interface C2 { 17 | void onResult(A a, B b); 18 | } 19 | 20 | public static interface C3 { 21 | void onResult(A a, B b, C c); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/li/lingfeng/ltsystem/utils/Triple.java: -------------------------------------------------------------------------------- 1 | package li.lingfeng.ltsystem.utils; 2 | 3 | import java.util.Objects; 4 | 5 | /** 6 | * Created by sv on 18-2-14. 7 | */ 8 | 9 | public class Triple { 10 | public final F first; 11 | public final S second; 12 | public final T third; 13 | 14 | public Triple(F first, S second, T third) { 15 | this.first = first; 16 | this.second = second; 17 | this.third = third; 18 | } 19 | 20 | @Override 21 | public boolean equals(Object obj) { 22 | if (!(obj instanceof Triple)) { 23 | return false; 24 | } 25 | Triple t = (Triple) obj; 26 | return Objects.equals(t.first, first) && Objects.equals(t.second, second) 27 | && Objects.equals(t.third, third); 28 | } 29 | 30 | @Override 31 | public int hashCode() { 32 | return (first == null ? 0 : first.hashCode()) ^ (second == null ? 0 : second.hashCode()) 33 | ^ (third == null ? 0 : third.hashCode()); 34 | } 35 | 36 | @Override 37 | public String toString() { 38 | return "Triple{" + String.valueOf(first) + "," + String.valueOf(second) + "," + String.valueOf(third) + "}"; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_3g.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_4g.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_add.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_coin.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_communication.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_computer.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_edit.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_entertainment.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_google.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_incognito.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_info.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_qs_brightness_auto_off_alpha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluesky139/LTweaksSystem/662118fadfa9f795d7d9948d0778c66a0b0b2325/app/src/main/res/drawable/ic_qs_brightness_auto_off_alpha.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_qs_signal_hp.xml: -------------------------------------------------------------------------------- 1 | 7 | 9 | 12 | 13 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_quick_settings_adb_wireless_off.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_quick_settings_adb_wireless_on.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_search.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_select_all.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_shopping.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tools.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_wifi.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/jd_history_fade_red.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/jd_history_marker_border.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/stat_sys_data_fully_connected_hp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/youdao_dict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluesky139/LTweaksSystem/662118fadfa9f795d7d9948d0778c66a0b0b2325/app/src/main/res/drawable/youdao_dict.png -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_image_search.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_jd_history.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 14 | 15 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_list_check.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 13 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_qrcode.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 15 | 16 | 22 | 23 |