Showing preview only (3,111K chars total). Download the full file or copy to clipboard to get everything.
Repository: xb2016/EhViewer-NekoInverter
Branch: master
Commit: 8b8607e6b4b8
Files: 615
Total size: 2.8 MB
Directory structure:
gitextract_k4e444b1/
├── .editorconfig
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug-report.yml
│ │ └── config.yml
│ └── workflows/
│ ├── ci.yml
│ └── releases.yml
├── .gitignore
├── LICENSE
├── NOTICE
├── README.md
├── app/
│ ├── .gitignore
│ ├── build.gradle.kts
│ ├── keystore/
│ │ └── androidkey.jks
│ ├── proguard-rules.pro
│ ├── schemas/
│ │ └── com.hippo.network.CookiesDatabase/
│ │ ├── 1.json
│ │ └── 2.json
│ └── src/
│ ├── debug/
│ │ └── res/
│ │ └── values/
│ │ └── strings.xml
│ └── main/
│ ├── AndroidManifest.xml
│ ├── cpp/
│ │ ├── 0001-Insert-link-libs.patch
│ │ ├── 0002-Fix-zip_time-performance.patch
│ │ ├── 0003-Use-UTF-8-as-default-charset-on-bionic.patch
│ │ ├── CMakeLists.txt
│ │ ├── archive.c
│ │ ├── ehviewer.h
│ │ ├── gifutils.c
│ │ ├── hash.c
│ │ ├── image.c
│ │ ├── natsort/
│ │ │ ├── strnatcmp.c
│ │ │ └── strnatcmp.h
│ │ └── nettle/
│ │ ├── .gitignore
│ │ ├── CMakeLists.txt
│ │ ├── config.h
│ │ ├── keymap.h
│ │ ├── rotors.h
│ │ └── version.h
│ ├── java/
│ │ ├── com/
│ │ │ └── hippo/
│ │ │ ├── app/
│ │ │ │ ├── CheckBoxDialogBuilder.kt
│ │ │ │ ├── EditTextCheckBoxDialogBuilder.kt
│ │ │ │ ├── EditTextDialogBuilder.kt
│ │ │ │ └── ListCheckBoxDialogBuilder.kt
│ │ │ ├── database/
│ │ │ │ ├── MSQLiteBuilder.kt
│ │ │ │ └── MSQLiteOpenHelper.kt
│ │ │ ├── drawable/
│ │ │ │ ├── AddDeleteDrawable.kt
│ │ │ │ ├── BatteryDrawable.kt
│ │ │ │ ├── DrawerArrowDrawable.kt
│ │ │ │ ├── PreciselyClipDrawable.kt
│ │ │ │ ├── TriangleDrawable.kt
│ │ │ │ ├── UnikeryDrawable.kt
│ │ │ │ └── WrapDrawable.kt
│ │ │ ├── easyrecyclerview/
│ │ │ │ ├── EasyRecyclerView.kt
│ │ │ │ ├── FastScroller.kt
│ │ │ │ ├── HandlerDrawable.kt
│ │ │ │ ├── LayoutManagerUtils.kt
│ │ │ │ ├── LinearDividerItemDecoration.kt
│ │ │ │ ├── MarginItemDecoration.kt
│ │ │ │ ├── SimpleHolder.kt
│ │ │ │ └── SimpleSmoothScroller.kt
│ │ │ ├── ehviewer/
│ │ │ │ ├── AppConfig.java
│ │ │ │ ├── Crash.kt
│ │ │ │ ├── EhApplication.kt
│ │ │ │ ├── EhDB.kt
│ │ │ │ ├── EhProxySelector.kt
│ │ │ │ ├── FavouriteStatusRouter.java
│ │ │ │ ├── GetText.kt
│ │ │ │ ├── Settings.kt
│ │ │ │ ├── UrlOpener.kt
│ │ │ │ ├── WindowInsetsAnimationHelper.java
│ │ │ │ ├── client/
│ │ │ │ │ ├── EhCacheKeyFactory.kt
│ │ │ │ │ ├── EhClient.kt
│ │ │ │ │ ├── EhCookieStore.kt
│ │ │ │ │ ├── EhEngine.kt
│ │ │ │ │ ├── EhFilter.kt
│ │ │ │ │ ├── EhRequest.kt
│ │ │ │ │ ├── EhRequestBuilder.kt
│ │ │ │ │ ├── EhTagDatabase.kt
│ │ │ │ │ ├── EhUrl.kt
│ │ │ │ │ ├── EhUrlOpener.kt
│ │ │ │ │ ├── EhUtils.kt
│ │ │ │ │ ├── data/
│ │ │ │ │ │ ├── AbstractGalleryInfo.kt
│ │ │ │ │ │ ├── BaseGalleryInfo.kt
│ │ │ │ │ │ ├── FavListUrlBuilder.kt
│ │ │ │ │ │ ├── GalleryComment.kt
│ │ │ │ │ │ ├── GalleryCommentList.kt
│ │ │ │ │ │ ├── GalleryDetail.kt
│ │ │ │ │ │ ├── GalleryInfo.kt
│ │ │ │ │ │ ├── GalleryPreview.kt
│ │ │ │ │ │ ├── GalleryTagGroup.kt
│ │ │ │ │ │ ├── LargePreviewSet.kt
│ │ │ │ │ │ ├── ListUrlBuilder.kt
│ │ │ │ │ │ ├── NormalPreviewSet.kt
│ │ │ │ │ │ └── PreviewSet.kt
│ │ │ │ │ ├── exception/
│ │ │ │ │ │ ├── CloudflareBypassException.kt
│ │ │ │ │ │ ├── EhException.kt
│ │ │ │ │ │ ├── InsufficientFundsException.kt
│ │ │ │ │ │ ├── NoHAtHClientException.kt
│ │ │ │ │ │ ├── NotLoggedInException.kt
│ │ │ │ │ │ ├── OffensiveException.kt
│ │ │ │ │ │ ├── ParseException.kt
│ │ │ │ │ │ ├── PiningException.kt
│ │ │ │ │ │ └── QuotaExceededException.kt
│ │ │ │ │ └── parser/
│ │ │ │ │ ├── ArchiveParser.kt
│ │ │ │ │ ├── EventPaneParser.kt
│ │ │ │ │ ├── FavoritesParser.kt
│ │ │ │ │ ├── ForumsParser.kt
│ │ │ │ │ ├── GalleryApiParser.kt
│ │ │ │ │ ├── GalleryDetailParser.kt
│ │ │ │ │ ├── GalleryDetailUrlParser.kt
│ │ │ │ │ ├── GalleryListParser.kt
│ │ │ │ │ ├── GalleryListUrlParser.kt
│ │ │ │ │ ├── GalleryMultiPageViewerParser.kt
│ │ │ │ │ ├── GalleryNotAvailableParser.kt
│ │ │ │ │ ├── GalleryPageApiParser.kt
│ │ │ │ │ ├── GalleryPageParser.kt
│ │ │ │ │ ├── GalleryPageUrlParser.kt
│ │ │ │ │ ├── GalleryTokenApiParser.kt
│ │ │ │ │ ├── HomeParser.kt
│ │ │ │ │ ├── ParserUtils.kt
│ │ │ │ │ ├── ProfileParser.kt
│ │ │ │ │ ├── RateGalleryParser.kt
│ │ │ │ │ ├── SignInParser.kt
│ │ │ │ │ ├── TorrentParser.kt
│ │ │ │ │ ├── UserConfigParser.kt
│ │ │ │ │ ├── VoteCommentParser.kt
│ │ │ │ │ └── VoteTagParser.kt
│ │ │ │ ├── coil/
│ │ │ │ │ ├── DiskCache.kt
│ │ │ │ │ ├── DownloadThumbInterceptor.kt
│ │ │ │ │ ├── LockPool.kt
│ │ │ │ │ ├── MergeInterceptor.kt
│ │ │ │ │ └── NamedMutex.kt
│ │ │ │ ├── dao/
│ │ │ │ │ ├── BasicDao.kt
│ │ │ │ │ ├── BookmarkInfo.kt
│ │ │ │ │ ├── BookmarksDao.kt
│ │ │ │ │ ├── DownloadDirname.kt
│ │ │ │ │ ├── DownloadDirnameDao.kt
│ │ │ │ │ ├── DownloadInfo.kt
│ │ │ │ │ ├── DownloadLabel.kt
│ │ │ │ │ ├── DownloadLabelDao.kt
│ │ │ │ │ ├── DownloadsDao.kt
│ │ │ │ │ ├── EhDatabase.kt
│ │ │ │ │ ├── Filter.kt
│ │ │ │ │ ├── FilterDao.kt
│ │ │ │ │ ├── HistoryDao.kt
│ │ │ │ │ ├── HistoryInfo.kt
│ │ │ │ │ ├── LocalFavoriteInfo.kt
│ │ │ │ │ ├── LocalFavoritesDao.kt
│ │ │ │ │ ├── QuickSearch.kt
│ │ │ │ │ └── QuickSearchDao.kt
│ │ │ │ ├── download/
│ │ │ │ │ ├── DownloadManager.kt
│ │ │ │ │ └── DownloadService.kt
│ │ │ │ ├── gallery/
│ │ │ │ │ ├── ArchiveGalleryProvider.kt
│ │ │ │ │ ├── EhGalleryProvider.kt
│ │ │ │ │ └── GalleryProvider2.kt
│ │ │ │ ├── jni/
│ │ │ │ │ ├── Archive.kt
│ │ │ │ │ ├── GifUtils.kt
│ │ │ │ │ ├── Hash.kt
│ │ │ │ │ └── Image.kt
│ │ │ │ ├── preference/
│ │ │ │ │ ├── AccountPreference.kt
│ │ │ │ │ ├── CleanRedundancyPreference.kt
│ │ │ │ │ ├── ClearSearchHistoryPreference.kt
│ │ │ │ │ ├── ImageLimitsPreference.kt
│ │ │ │ │ ├── ProxyPreference.kt
│ │ │ │ │ ├── RestoreDownloadPreference.kt
│ │ │ │ │ ├── TaskPreference.kt
│ │ │ │ │ ├── UserAgentPreference.kt
│ │ │ │ │ └── VersionPreference.kt
│ │ │ │ ├── shortcuts/
│ │ │ │ │ └── ShortcutsActivity.kt
│ │ │ │ ├── spider/
│ │ │ │ │ ├── DownloadInfoMagics.kt
│ │ │ │ │ ├── SpiderDen.kt
│ │ │ │ │ ├── SpiderInfo.kt
│ │ │ │ │ └── SpiderQueen.kt
│ │ │ │ ├── ui/
│ │ │ │ │ ├── CommonOperations.kt
│ │ │ │ │ ├── EhActivity.kt
│ │ │ │ │ ├── GalleryActivity.kt
│ │ │ │ │ ├── MainActivity.kt
│ │ │ │ │ ├── SettingsActivity.kt
│ │ │ │ │ ├── WebViewActivity.kt
│ │ │ │ │ ├── dialog/
│ │ │ │ │ │ └── SelectItemWithIconAdapter.kt
│ │ │ │ │ ├── fragment/
│ │ │ │ │ │ ├── AboutFragment.kt
│ │ │ │ │ │ ├── AdvancedFragment.kt
│ │ │ │ │ │ ├── BaseFragment.kt
│ │ │ │ │ │ ├── BasePreferenceFragment.kt
│ │ │ │ │ │ ├── DownloadFragment.kt
│ │ │ │ │ │ ├── EhFragment.kt
│ │ │ │ │ │ ├── FilterFragment.kt
│ │ │ │ │ │ ├── MyTagsFragment.kt
│ │ │ │ │ │ ├── PrivacyFragment.kt
│ │ │ │ │ │ ├── ReadFragment.kt
│ │ │ │ │ │ ├── SetSecurityFragment.kt
│ │ │ │ │ │ ├── SettingsFragment.kt
│ │ │ │ │ │ └── UConfigFragment.kt
│ │ │ │ │ └── scene/
│ │ │ │ │ ├── BaseScene.kt
│ │ │ │ │ ├── CookieSignInScene.kt
│ │ │ │ │ ├── DownloadsScene.kt
│ │ │ │ │ ├── EhCallback.kt
│ │ │ │ │ ├── EnterGalleryDetailTransaction.kt
│ │ │ │ │ ├── FavoritesScene.kt
│ │ │ │ │ ├── GalleryAdapter.kt
│ │ │ │ │ ├── GalleryCommentsScene.kt
│ │ │ │ │ ├── GalleryDetailScene.kt
│ │ │ │ │ ├── GalleryHolder.kt
│ │ │ │ │ ├── GalleryInfoScene.kt
│ │ │ │ │ ├── GalleryListScene.kt
│ │ │ │ │ ├── GalleryPreviewsScene.kt
│ │ │ │ │ ├── HistoryScene.kt
│ │ │ │ │ ├── ProgressScene.kt
│ │ │ │ │ ├── SecurityScene.kt
│ │ │ │ │ ├── SelectSiteScene.kt
│ │ │ │ │ ├── SignInScene.kt
│ │ │ │ │ ├── SolidScene.kt
│ │ │ │ │ ├── ToolbarScene.kt
│ │ │ │ │ ├── TransitionNameFactory.kt
│ │ │ │ │ └── WebViewSignInScene.kt
│ │ │ │ ├── util/
│ │ │ │ │ └── WebViewExtensions.kt
│ │ │ │ └── widget/
│ │ │ │ ├── AdvanceSearchTable.kt
│ │ │ │ ├── CategoryTable.kt
│ │ │ │ ├── DialogWebChromeClient.java
│ │ │ │ ├── EhStageLayout.kt
│ │ │ │ ├── FixedThumb.kt
│ │ │ │ ├── GalleryGuideView.java
│ │ │ │ ├── GalleryHeader.java
│ │ │ │ ├── GalleryInfoContentHelper.kt
│ │ │ │ ├── GalleryRatingBar.java
│ │ │ │ ├── ImageSearchLayout.kt
│ │ │ │ ├── ResizeableFixedThumb.kt
│ │ │ │ ├── ReversibleSeekBar.java
│ │ │ │ ├── SearchBar.kt
│ │ │ │ ├── SearchDatabase.java
│ │ │ │ ├── SearchEditText.java
│ │ │ │ ├── SearchLayout.kt
│ │ │ │ ├── SeekBarPanel.kt
│ │ │ │ ├── SimpleRatingView.java
│ │ │ │ └── TileThumb.java
│ │ │ ├── glgallery/
│ │ │ │ ├── DownUpDetector.java
│ │ │ │ ├── Fling.java
│ │ │ │ ├── GalleryPageView.java
│ │ │ │ ├── GalleryProvider.kt
│ │ │ │ ├── GalleryView.java
│ │ │ │ ├── GestureRecognizer.java
│ │ │ │ ├── ImageView.java
│ │ │ │ ├── PagerLayoutManager.java
│ │ │ │ ├── ScrollLayoutManager.java
│ │ │ │ └── SimpleAdapter.java
│ │ │ ├── glview/
│ │ │ │ ├── anim/
│ │ │ │ │ ├── AlphaAnimation.java
│ │ │ │ │ ├── Animation.java
│ │ │ │ │ ├── CanvasAnimation.java
│ │ │ │ │ └── FloatAnimation.java
│ │ │ │ ├── glrenderer/
│ │ │ │ │ ├── BasicTexture.java
│ │ │ │ │ ├── CanvasTexture.java
│ │ │ │ │ ├── GLCanvas.java
│ │ │ │ │ ├── GLES11Canvas.java
│ │ │ │ │ ├── GLES11IdImpl.java
│ │ │ │ │ ├── GLES20Canvas.java
│ │ │ │ │ ├── GLES20IdImpl.java
│ │ │ │ │ ├── GLId.java
│ │ │ │ │ ├── GLPaint.java
│ │ │ │ │ ├── MovableTextTexture.java
│ │ │ │ │ ├── NativeTexture.java
│ │ │ │ │ ├── RawTexture.java
│ │ │ │ │ ├── SpriteTexture.java
│ │ │ │ │ ├── StringTexture.java
│ │ │ │ │ ├── Texture.java
│ │ │ │ │ ├── TiledTexture.java
│ │ │ │ │ └── UploadedTexture.java
│ │ │ │ ├── image/
│ │ │ │ │ ├── GLImageMovableTextView.java
│ │ │ │ │ ├── ImageMovableTextTexture.java
│ │ │ │ │ ├── ImageSpriteTexture.java
│ │ │ │ │ ├── ImageTexture.java
│ │ │ │ │ └── ImageWrapper.java
│ │ │ │ ├── util/
│ │ │ │ │ └── GalleryUtils.java
│ │ │ │ ├── view/
│ │ │ │ │ ├── AnimationTime.java
│ │ │ │ │ ├── GLRoot.java
│ │ │ │ │ ├── GLRootView.java
│ │ │ │ │ ├── GLView.java
│ │ │ │ │ ├── Gravity.java
│ │ │ │ │ ├── OrientationSource.java
│ │ │ │ │ ├── TouchHelper.java
│ │ │ │ │ └── TouchOwner.java
│ │ │ │ └── widget/
│ │ │ │ ├── GLFrameLayout.java
│ │ │ │ ├── GLLinearLayout.java
│ │ │ │ ├── GLProgressView.java
│ │ │ │ └── GLTextureView.java
│ │ │ ├── image/
│ │ │ │ └── Image.kt
│ │ │ ├── network/
│ │ │ │ ├── CookieDatabase.kt
│ │ │ │ ├── CookieSet.kt
│ │ │ │ ├── InetValidator.kt
│ │ │ │ ├── StatusCodeException.kt
│ │ │ │ └── UrlBuilder.kt
│ │ │ ├── okhttp/
│ │ │ │ └── ChromeRequestBuilder.kt
│ │ │ ├── preference/
│ │ │ │ ├── DialogPreference.kt
│ │ │ │ └── UrlPreference.kt
│ │ │ ├── scene/
│ │ │ │ ├── Announcer.kt
│ │ │ │ ├── SceneApplication.kt
│ │ │ │ ├── SceneFragment.kt
│ │ │ │ ├── StageActivity.kt
│ │ │ │ ├── StageLayout.kt
│ │ │ │ └── TransitionHelper.kt
│ │ │ ├── text/
│ │ │ │ └── URLImageGetter.kt
│ │ │ ├── unifile/
│ │ │ │ ├── Contracts.kt
│ │ │ │ ├── DocumentsContractApi19.kt
│ │ │ │ ├── DocumentsContractApi21.kt
│ │ │ │ ├── FilenameFilter.kt
│ │ │ │ ├── MediaContract.kt
│ │ │ │ ├── MediaFile.kt
│ │ │ │ ├── RawFile.kt
│ │ │ │ ├── SingleDocumentFile.kt
│ │ │ │ ├── TreeDocumentFile.kt
│ │ │ │ ├── UniFile.kt
│ │ │ │ ├── UniFileExtensions.kt
│ │ │ │ ├── UriHandler.kt
│ │ │ │ └── Utils.kt
│ │ │ ├── util/
│ │ │ │ ├── AppHelper.kt
│ │ │ │ ├── BBCode.kt
│ │ │ │ ├── ClipboardUtil.kt
│ │ │ │ ├── CoroutinesExtensions.kt
│ │ │ │ ├── DateTimeUtil.kt
│ │ │ │ ├── ExceptionUtils.kt
│ │ │ │ ├── FDUtils.kt
│ │ │ │ ├── HtmlCompat.kt
│ │ │ │ ├── JsoupUtils.java
│ │ │ │ ├── LogCat.java
│ │ │ │ ├── ParcelableCompat.kt
│ │ │ │ ├── ReadableTime.kt
│ │ │ │ ├── SDKUtils.kt
│ │ │ │ ├── SqlUtils.java
│ │ │ │ ├── TextUrl.java
│ │ │ │ └── URLEncoderCompat.kt
│ │ │ ├── view/
│ │ │ │ ├── BringOutTransition.java
│ │ │ │ └── ViewTransition.java
│ │ │ ├── widget/
│ │ │ │ ├── AutoWrapLayout.java
│ │ │ │ ├── BatteryView.kt
│ │ │ │ ├── CheckTextView.kt
│ │ │ │ ├── ColorView.java
│ │ │ │ ├── ContentLayout.kt
│ │ │ │ ├── CuteSpinner.java
│ │ │ │ ├── DateUtils.java
│ │ │ │ ├── DrawerView.java
│ │ │ │ ├── FabLayout.kt
│ │ │ │ ├── FixedAspectImageView.kt
│ │ │ │ ├── IgnoreFitsSystemWindowsFullyDraggableDrawerContentLayout.kt
│ │ │ │ ├── IndicatingListView.java
│ │ │ │ ├── LinkifyTextView.java
│ │ │ │ ├── LoadImageView.kt
│ │ │ │ ├── MaxSizeContainer.java
│ │ │ │ ├── ObservedTextView.java
│ │ │ │ ├── RadioGridGroup.java
│ │ │ │ ├── SearchBarMover.java
│ │ │ │ ├── SimpleGridAutoSpanLayout.java
│ │ │ │ ├── SimpleGridLayout.java
│ │ │ │ ├── Slider.java
│ │ │ │ ├── TextClock.java
│ │ │ │ ├── lockpattern/
│ │ │ │ │ ├── LockPatternUtils.java
│ │ │ │ │ └── LockPatternView.java
│ │ │ │ └── recyclerview/
│ │ │ │ ├── AutoGridLayoutManager.java
│ │ │ │ └── AutoStaggeredGridLayoutManager.java
│ │ │ └── yorozuya/
│ │ │ ├── AnimationUtils.java
│ │ │ ├── AssertError.java
│ │ │ ├── AssertException.java
│ │ │ ├── AssertUtils.java
│ │ │ ├── ConcurrentPool.java
│ │ │ ├── FileUtils.java
│ │ │ ├── IOUtils.java
│ │ │ ├── IOUtils.kt
│ │ │ ├── IntIdGenerator.java
│ │ │ ├── LayoutUtils.java
│ │ │ ├── MathUtils.java
│ │ │ ├── NumberUtils.java
│ │ │ ├── OSUtils.java
│ │ │ ├── ObjectUtils.java
│ │ │ ├── Pool.java
│ │ │ ├── ResourcesUtils.java
│ │ │ ├── SimpleAnimatorListener.java
│ │ │ ├── SimpleHandler.java
│ │ │ ├── StringUtils.java
│ │ │ ├── StringUtils.kt
│ │ │ ├── Utilities.java
│ │ │ ├── ViewUtils.java
│ │ │ ├── collect/
│ │ │ │ ├── IntList.kt
│ │ │ │ └── LongList.kt
│ │ │ └── thread/
│ │ │ ├── InfiniteThreadExecutor.java
│ │ │ ├── PriorityThread.java
│ │ │ └── PriorityThreadFactory.java
│ │ └── eu/
│ │ └── kanade/
│ │ └── tachiyomi/
│ │ └── network/
│ │ └── interceptor/
│ │ ├── CloudflareInterceptor.kt
│ │ └── WebViewInterceptor.kt
│ └── res/
│ ├── anim/
│ │ ├── accelerate_quart.xml
│ │ ├── decelerate_quart.xml
│ │ ├── decelerate_quint.xml
│ │ ├── scene_close_exit.xml
│ │ ├── scene_open_enter.xml
│ │ ├── scene_open_enter_horizontal.xml
│ │ └── scene_open_exit.xml
│ ├── color/
│ │ ├── content_reactive.xml
│ │ ├── content_reactive_black.xml
│ │ └── primary_text_material_black.xml
│ ├── drawable/
│ │ ├── big_download.xml
│ │ ├── big_filter.xml
│ │ ├── big_history.xml
│ │ ├── big_sad_pandroid.xml
│ │ ├── category_background.xml
│ │ ├── check_text_view_foreground.xml
│ │ ├── default_avatar.xml
│ │ ├── divider_gallery_detail.xml
│ │ ├── divider_gallery_detail_dark.xml
│ │ ├── ic_baseline_dark_mode_24.xml
│ │ ├── ic_baseline_format_list_numbered_24.xml
│ │ ├── ic_baseline_menu_24.xml
│ │ ├── ic_baseline_reorder_24.xml
│ │ ├── ic_baseline_warning_24.xml
│ │ ├── ic_launcher_foreground.xml
│ │ ├── ic_launcher_monochrome.xml
│ │ ├── ic_pause_108dp.xml
│ │ ├── ic_play_arrow_108dp.xml
│ │ ├── image_failed.xml
│ │ ├── round_side_rect.xml
│ │ ├── spacer_keyline.xml
│ │ ├── spacer_x6.xml
│ │ ├── tile_background.xml
│ │ ├── v_adb_primary_x24.xml
│ │ ├── v_archive_primary_x48.xml
│ │ ├── v_arrow_left_dark_x24.xml
│ │ ├── v_book_open_primary_x24.xml
│ │ ├── v_book_open_x24.xml
│ │ ├── v_check_all_dark_x24.xml
│ │ ├── v_check_dark_x24.xml
│ │ ├── v_clear_all_dark_x24.xml
│ │ ├── v_close_dark_x24.xml
│ │ ├── v_cookie_brown_x48.xml
│ │ ├── v_delete_x24.xml
│ │ ├── v_dots_vertical_secondary_dark_x24.xml
│ │ ├── v_download_box_dark_x24.xml
│ │ ├── v_download_primary_x24.xml
│ │ ├── v_download_x16.xml
│ │ ├── v_download_x24.xml
│ │ ├── v_eh_subscription_black_x24.xml
│ │ ├── v_filter_dark_x24.xml
│ │ ├── v_fire_black_x24.xml
│ │ ├── v_folder_move_x24.xml
│ │ ├── v_go_to_dark_x24.xml
│ │ ├── v_heart_box_dark_x24.xml
│ │ ├── v_heart_broken_x24.xml
│ │ ├── v_heart_outline_primary_x48.xml
│ │ ├── v_heart_primary_x48.xml
│ │ ├── v_heart_x16.xml
│ │ ├── v_heart_x24.xml
│ │ ├── v_help_circle_x24.xml
│ │ ├── v_history_black_x24.xml
│ │ ├── v_homepage_black_x24.xml
│ │ ├── v_info_outline_dark_x24.xml
│ │ ├── v_info_primary_x24.xml
│ │ ├── v_last_page_x24.xml
│ │ ├── v_magnify_x24.xml
│ │ ├── v_pause_x24.xml
│ │ ├── v_pencil_dark_x24.xml
│ │ ├── v_pin_top_24.xml
│ │ ├── v_play_x24.xml
│ │ ├── v_plus_dark_x24.xml
│ │ ├── v_refresh_dark_x24.xml
│ │ ├── v_reply_dark_x24.xml
│ │ ├── v_sad_panda_primary_x24.xml
│ │ ├── v_sec_primary_x24.xml
│ │ ├── v_send_dark_x24.xml
│ │ ├── v_settings_black_x24.xml
│ │ ├── v_share_primary_x48.xml
│ │ ├── v_similar_primary_x48.xml
│ │ ├── v_slider_bubble.xml
│ │ ├── v_star_half_x16.xml
│ │ ├── v_star_outline_x16.xml
│ │ ├── v_star_x16.xml
│ │ └── v_utorrent_primary_x48.xml
│ ├── drawable-v25/
│ │ ├── ic_shortcut_start.xml
│ │ └── ic_shortcut_stop.xml
│ ├── drawable-v26/
│ │ ├── ic_shortcut_start.xml
│ │ └── ic_shortcut_stop.xml
│ ├── layout/
│ │ ├── activity_filter.xml
│ │ ├── activity_gallery.xml
│ │ ├── activity_main.xml
│ │ ├── activity_preference.xml
│ │ ├── activity_set_security.xml
│ │ ├── activity_webview.xml
│ │ ├── dialog_add_filter.xml
│ │ ├── dialog_archive_list.xml
│ │ ├── dialog_checkbox_builder.xml
│ │ ├── dialog_edittext_builder.xml
│ │ ├── dialog_edittextcheckbox_builder.xml
│ │ ├── dialog_gallery_menu.xml
│ │ ├── dialog_go_to.xml
│ │ ├── dialog_item_select_with_icon.xml
│ │ ├── dialog_js_prompt.xml
│ │ ├── dialog_list_checkbox_builder.xml
│ │ ├── dialog_rate.xml
│ │ ├── dialog_recycler_view.xml
│ │ ├── dialog_torrent_list.xml
│ │ ├── drawer_list_rv.xml
│ │ ├── gallery_detail_actions.xml
│ │ ├── gallery_detail_comments.xml
│ │ ├── gallery_detail_content.xml
│ │ ├── gallery_detail_header.xml
│ │ ├── gallery_detail_info.xml
│ │ ├── gallery_detail_previews.xml
│ │ ├── gallery_detail_tags.xml
│ │ ├── gallery_tag_group.xml
│ │ ├── item_cute_spinner_item.xml
│ │ ├── item_download.xml
│ │ ├── item_drawer_favorites.xml
│ │ ├── item_drawer_list.xml
│ │ ├── item_filter.xml
│ │ ├── item_filter_header.xml
│ │ ├── item_gallery_comment.xml
│ │ ├── item_gallery_comment_more.xml
│ │ ├── item_gallery_comment_progress.xml
│ │ ├── item_gallery_grid.xml
│ │ ├── item_gallery_info_data.xml
│ │ ├── item_gallery_info_header.xml
│ │ ├── item_gallery_list.xml
│ │ ├── item_gallery_list_thumb_height.xml
│ │ ├── item_gallery_preview.xml
│ │ ├── item_gallery_tag.xml
│ │ ├── item_history.xml
│ │ ├── item_hosts.xml
│ │ ├── item_select_dialog.xml
│ │ ├── item_simple_list_2.xml
│ │ ├── nav_header_main.xml
│ │ ├── preference_dialog_proxy.xml
│ │ ├── preference_dialog_task.xml
│ │ ├── preference_recyclerview.xml
│ │ ├── scene_cookie_sign_in.xml
│ │ ├── scene_download.xml
│ │ ├── scene_favorites.xml
│ │ ├── scene_gallery_comments.xml
│ │ ├── scene_gallery_detail.xml
│ │ ├── scene_gallery_info.xml
│ │ ├── scene_gallery_list.xml
│ │ ├── scene_gallery_previews.xml
│ │ ├── scene_history.xml
│ │ ├── scene_login.xml
│ │ ├── scene_progress.xml
│ │ ├── scene_security.xml
│ │ ├── scene_select_site.xml
│ │ ├── scene_toolbar.xml
│ │ ├── search_action.xml
│ │ ├── search_advance.xml
│ │ ├── search_category.xml
│ │ ├── search_image.xml
│ │ ├── search_normal.xml
│ │ ├── widget_advance_search_table.xml
│ │ ├── widget_category_table.xml
│ │ ├── widget_content_layout.xml
│ │ ├── widget_gallery_guide_1.xml
│ │ ├── widget_gallery_guide_2.xml
│ │ ├── widget_image_search.xml
│ │ └── widget_search_bar.xml
│ ├── layout-land/
│ │ └── activity_set_security.xml
│ ├── menu/
│ │ ├── activity_filter.xml
│ │ ├── activity_u_config.xml
│ │ ├── context_comment.xml
│ │ ├── download_label_option.xml
│ │ ├── drawer_download.xml
│ │ ├── drawer_favorites.xml
│ │ ├── drawer_gallery_list.xml
│ │ ├── nav_drawer_main.xml
│ │ ├── quicksearch_option.xml
│ │ ├── scene_download.xml
│ │ ├── scene_gallery_detail.xml
│ │ ├── scene_gallery_previews.xml
│ │ └── scene_history.xml
│ ├── mipmap-anydpi-v26/
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ ├── raw/
│ │ └── isrgrootx1
│ ├── transition/
│ │ ├── trans_fade.xml
│ │ └── trans_move.xml
│ ├── values/
│ │ ├── arrays.xml
│ │ ├── attrs.xml
│ │ ├── bools.xml
│ │ ├── color_launcher.xml
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── drawables.xml
│ │ ├── ids.xml
│ │ ├── pathdata.xml
│ │ ├── strings.xml
│ │ ├── styles.xml
│ │ ├── themes.xml
│ │ └── themes_override.xml
│ ├── values-ja/
│ │ └── strings.xml
│ ├── values-night/
│ │ ├── color_launcher.xml
│ │ ├── colors.xml
│ │ └── styles.xml
│ ├── values-sw600dp/
│ │ └── dimens.xml
│ ├── values-sw720dp-land/
│ │ └── dimens.xml
│ ├── values-v24/
│ │ └── arrays.xml
│ ├── values-zh-rCN/
│ │ ├── bools.xml
│ │ └── strings.xml
│ ├── values-zh-rHK/
│ │ ├── bools.xml
│ │ └── strings.xml
│ ├── values-zh-rTW/
│ │ ├── bools.xml
│ │ └── strings.xml
│ ├── xml/
│ │ ├── about_settings.xml
│ │ ├── advanced_settings.xml
│ │ ├── backup_scheme.xml
│ │ ├── data_extraction_rules.xml
│ │ ├── download_settings.xml
│ │ ├── eh_settings.xml
│ │ ├── filepaths.xml
│ │ ├── locale_config.xml
│ │ ├── privacy_settings.xml
│ │ ├── read_settings.xml
│ │ └── settings_headers.xml
│ └── xml-v25/
│ └── shortcuts.xml
├── build.gradle.kts
├── docs/
│ ├── CHANGELOG/
│ │ └── zh-cn.md
│ └── README/
│ └── zh-cn.md
├── gradle/
│ ├── libs.versions.toml
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── settings.gradle.kts
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
[*.{kt,kts}]
ij_kotlin_imports_layout = *
ij_kotlin_line_break_after_multiline_when_entry = false
ktlint_code_style = intellij_idea
ktlint_function_naming_ignore_when_annotated_with = Composable
ktlint_standard_class-signature = disabled
ktlint_standard_mixed-condition-operators = disabled
================================================
FILE: .github/ISSUE_TEMPLATE/bug-report.yml
================================================
name: Bug 反馈 / Bug report
description: 提交一个问题报告 / Create a bug report
labels:
- "bug"
body:
- type: markdown
attributes:
value: |
感谢您愿意为 Ehviewer-NekoInverter 做出贡献!
提交问题报告前,还请首先完成文末的自查步骤
Thanks for your contribution to the Ehviewer-NekoInverter Project!
Please complete the self-review steps at the end of the article before submitting the bug report
- type: textarea
id: reproduce
attributes:
label: 复现步骤 / Steps to reproduce
description: |
在此处写下复现的方式,请详细描述每一个步骤,包括画廊链接、相关设置等
Describe how to reproduce here, please describe each step in detail, include gallery links or settings
placeholder: |
1.
2.
3.
validations:
required: true
- type: textarea
id : expected
attributes:
label: 预期行为 / Expected behaviour
description: |
在此处说明正常情况下应用的预期行为
Describe what should be happened here
placeholder: |
它应该 ...
It should be ...
validations:
required: true
- type: textarea
id: actual
attributes:
label: 实际行为 / Actual behaviour
description: |
在此处描绘应用的实际行为,最好附上截图或录屏
Describe what actually happened here, screenshots or screen recordings are better
placeholder: |
实际上它 ...
Actually it ...
[截图或录屏] / [Screenshots or screen recordings]
validations:
required: true
- type: textarea
id: log
attributes:
label: 应用日志 / App logs
description: |
您可以通过设置-高级-导出日志 来获得日志文件,请确保日志完整,过长的日志请以文件形式上传
You can get logs file in Settings - Advanced - Dump logcat
placeholder: 06-15 17:44:53.704 23382 23382 E ...
validations:
required: true
- type: textarea
id: more
attributes:
label: 备注 / Additional details
description: |
在此处写下其他您想说的内容
Describe additional details here
placeholder: |
其他有用的信息与附件
Additional details and attachments
validations:
required: false
- type: input
id: site
attributes:
label: 浏览站点 / Browsing site
description: E-Hentai / ExHentai
placeholder: E-Hentai
validations:
required: true
- type: input
id: version
attributes:
label: EhViewer 版本号 / EhViewer version code
description: |
您可以在设置 - 关于处找到版本号
You can get version code in Settings - About
placeholder: 1.7.28
validations:
required: true
- type: input
id: ci
attributes:
label: EhViewer CI 版本 / EhViewer CI version
description: |
请确保您已经使用 [最新 CI 版本](https://github.com/EhViewer-NekoInverter/EhViewer/actions/workflows/ci.yml) 测试,请填入您使用的 CI 版本网址
Please make sure you have tested with the [latest CI version](https://github.com/EhViewer-NekoInverter/EhViewer/actions/workflows/ci.yml), simply drop GitHub Action CI download page url here
placeholder: https://github.com/EhViewer-NekoInverter/EhViewer/actions/runs/XXXXXXXXXX
validations:
required: true
- type: input
id: system
attributes:
label: Android 系统版本 / Android version
description: Android 分支名称 + 版本号 / AOSP fork name + version code
placeholder: MIUI 12.5, ArrowOS 12.1
validations:
required: true
- type: input
id: device
attributes:
label: 设备型号 / Device model
description: 在此填入设备型号 / Put device model here
placeholder: OnePlus 7 Pro, Xiaomi 12 Ultra
validations:
required: true
- type: input
id: SoC
attributes:
label: SoC 型号 / SoC model
description: 在此填入 SoC 型号 / Put SoC model here
placeholder: 骁龙 8+ Gen 1, Snapdragon 8+ Gen 1
validations:
required: true
- type: checkboxes
id: check
attributes:
label: 自查步骤 / Self-review steps
description: |
请确保您已经遵守以下所有必选项,否则 issue 会被立即关闭
Please ensure you have obtained all needed options, otherwise the issue will be closed immediately
options:
- label: 如果您有足够的时间和能力,并愿意为修复此问题提交 PR ,请勾上此复选框 / Pull request is welcome. Check this if you want to start a pull request
required: false
- label: 您已仔细查看并知情 [Q&A](https://github.com/EhViewer-NekoInverter/EhViewer/issues/18) 中的内容 / You have checked [Q&A](https://github.com/EhViewer-NekoInverter/EhViewer/issues/18) carefully
required: true
- label: 您已搜索过 [Issue Tracker](https://github.com/EhViewer-NekoInverter/EhViewer/issues),没有找到类似的问题 / I have searched on [Issue Tracker](https://github.com/EhViewer-NekoInverter/EhViewer/issues), No duplicate or related open issue has been found
required: true
- label: 您确保这个 Issue 只提及一个问题。如果您有多个问题报告,烦请发起多个 Issue / Ensure there is only one bug report in this issue. Please make mutiply issue for mutiply bugs
required: true
- label: 您确保已使用 [最新 CI 版本](https://github.com/EhViewer-NekoInverter/EhViewer/actions/workflows/ci.yml) 测试,并且该问题在最新 CI 版本中并未解决 / This bug have not solved in [latest CI version](https://github.com/EhViewer-NekoInverter/EhViewer/actions/workflows/ci.yml)
required: true
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
- name: 所有其他问题 / All other questions
url: https://www.google.com/
about: 咨询谷歌 / Ask Google for help
================================================
FILE: .github/workflows/ci.yml
================================================
name: CI
on:
push:
branches:
- '*'
pull_request:
workflow_dispatch:
jobs:
linux:
name: Build
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 21
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
- name: Spotless Check
run: ./gradlew spotlessCheck
- name: Gradle Build
run: ./gradlew assembleRelease
- name: Upload Universal
uses: actions/upload-artifact@v4
with:
name: universal-${{ github.sha }}
path: app/build/outputs/apk/release/app-universal-release.apk
- name: Upload ARM64
uses: actions/upload-artifact@v4
with:
name: arm64-v8a-${{ github.sha }}
path: app/build/outputs/apk/release/app-arm64-v8a-release.apk
- name: Upload ARM32
uses: actions/upload-artifact@v4
with:
name: armeabi-v7a-${{ github.sha }}
path: app/build/outputs/apk/release/app-armeabi-v7a-release.apk
- name: Upload x86_64
uses: actions/upload-artifact@v4
with:
name: x86_64-${{ github.sha }}
path: app/build/outputs/apk/release/app-x86_64-release.apk
- name: Upload mapping
uses: actions/upload-artifact@v4
with:
name: mapping-${{ github.sha }}
path: app/build/outputs/mapping/release/mapping.txt
- name: Upload native debug symbols
uses: actions/upload-artifact@v4
with:
name: native-debug-symbols-${{ github.sha }}
path: app/build/outputs/native-debug-symbols/release/native-debug-symbols.zip
================================================
FILE: .github/workflows/releases.yml
================================================
name: Releases
on:
push:
tags:
- "*"
jobs:
linux:
name: Build
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 21
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
- name: Gradle Build
run: ./gradlew assembleRelease
- name: Rename Apks
run: |
mv app/build/outputs/apk/release/app-universal-release.apk EhViewer-${{ github.ref_name }}-universal.apk
mv app/build/outputs/apk/release/app-arm64-v8a-release.apk EhViewer-${{ github.ref_name }}-arm64-v8a.apk
mv app/build/outputs/apk/release/app-armeabi-v7a-release.apk EhViewer-${{ github.ref_name }}-armeabi-v7a.apk
mv app/build/outputs/apk/release/app-x86_64-release.apk EhViewer-${{ github.ref_name }}-x86_64.apk
mv app/build/outputs/mapping/release/mapping.txt EhViewer-${{ github.ref_name }}-mapping.txt
mv app/build/outputs/native-debug-symbols/release/native-debug-symbols.zip EhViewer-${{ github.ref_name }}-native-debug-symbols.zip
- name: Releases
uses: softprops/action-gh-release@v2
with:
body: Bump Version
files: |
EhViewer-${{ github.ref_name }}-universal.apk
EhViewer-${{ github.ref_name }}-arm64-v8a.apk
EhViewer-${{ github.ref_name }}-armeabi-v7a.apk
EhViewer-${{ github.ref_name }}-x86_64.apk
EhViewer-${{ github.ref_name }}-mapping.txt
EhViewer-${{ github.ref_name }}-native-debug-symbols.zip
================================================
FILE: .gitignore
================================================
.gradle
/local.properties
.DS_Store
/build
/src
*.iml
.idea
/captures
release
google-services.json
/.kotlin
================================================
FILE: LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.
================================================
FILE: NOTICE
================================================
EhViewer
Copyright 2014-2016 Hippo Seven
An Unofficial E-Hentai Application for Android.
香风智乃是最可爱的女孩子。
chino kafuu is the cutest girl.
================================================
FILE: README.md
================================================
<p align="right">
<strong>English</strong>
<span> | </span>
<a href="/docs/README/zh-cn.md">
简体中文
</a>
</p>
<h1 align="center">
<img src="https://github.com/EhViewer-NekoInverter/Arts/blob/main/launcher_icon-web.webp" width="150" alt="EhViewer">
<br>EhViewer<br>
</h1>
<p align="center">
<a href="https://github.com/EhViewer-NekoInverter/EhViewer/actions/workflows/ci.yml">
<img src="https://img.shields.io/github/actions/workflow/status/EhViewer-NekoInverter/EhViewer/ci.yml?style=flat-square" alt="Github Actions">
</a>
<a href="/LICENSE">
<img src="https://img.shields.io/github/license/EhViewer-NekoInverter/EhViewer?style=flat-square" alt="LICENSE">
</a>
<a href="https://github.com/EhViewer-NekoInverter/Ehviewer/releases">
<img src="https://img.shields.io/github/v/release/EhViewer-NekoInverter/Ehviewer?style=flat-square&include_prereleases" alt="Releases">
</a>
<a href="https://github.com/EhViewer-NekoInverter/EhViewer/issues">
<img src="https://img.shields.io/github/issues/EhViewer-NekoInverter/EhViewer?style=flat-square" alt="Issues">
</a>
</p>
<div align="center">
<h3>
<a href="#description">
Description
</a>
<span> | </span>
<a href="#download">
Download
</a>
<span> | </span>
<a href="#screenshot">
Screenshot
</a>
<span> | </span>
<a href="#thanks">
Thanks
</a>
<span> | </span>
<a href="#license">
License
</a>
</h3>
</div>
# Description
An EhViewer fork with classic Material Design 2 style
This fork is for personal use and does not accept feature requests; for common usage issues, please refer to the [Q&A](https://github.com/EhViewer-NekoInverter/EhViewer/issues/18)
If you prefer Material Design 3, consider using [EhViewer-Overhauled](https://github.com/FooIbar/EhViewer)
# Download
| Android Version | Notes |
|-----------------|------------------------------|
| 6.0-8.1 | No support for animated WebP |
| 9.0+ | Full support |
- Please go to **[GitHub Releases](https://github.com/EhViewer-NekoInverter/EhViewer/releases)** to download the release version
- If the release version has unresolved issues, go to **[GitHub Actions](https://github.com/EhViewer-NekoInverter/EhViewer/actions/workflows/ci.yml?query=branch%3Amaster)** to download the CI version (GitHub account login required)
# Screenshot


# Thanks
Here are the libraries
- [AOSP & AndroidX](https://source.android.com/)
- [Kotlin & KotlinX](https://kotlinlang.org/)
- [Coil](https://coil-kt.github.io/coil/)
- [FullDraggableDrawer](https://github.com/PureWriter/FullDraggableDrawer)
- [Jsoup](https://jsoup.org/)
- [Ktor](https://ktor.io/)
- [Libarchive](http://www.libarchive.org/)
- [MDC-Android](https://github.com/material-components/material-components-android)
- [OkHttp](https://square.github.io/okhttp/)
- [RikkaX](https://github.com/RikkaApps/RikkaX)
Tag translation
- [EhTagTranslation](https://github.com/EhTagTranslation/Database)
Translators
- ja: [Re*Index. (ot_inc)](https://github.com/reindex-ot)
# License
Copyright 2014-2019 Hippo Seven
Copyright 2020-2022 NekoInverter
Copyright 2022-2025 Moedog
EhViewer is free software:
you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation,
either version 3 of the License, or (at your option) any later version.
EhViewer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with EhViewer.
If not, see <https://www.gnu.org/licenses/>.
================================================
FILE: app/.gitignore
================================================
/build
/src/main/java-gen
manifest-merger-release-report.txt
/src/main/libs
/src/main/obj
# Intellij
*.iml
/.cxx
================================================
FILE: app/build.gradle.kts
================================================
import java.time.Instant
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
val isRelease: Boolean
get() = gradle.startParameter.taskNames.any { it.contains("Release") }
val supportedAbis = arrayOf("arm64-v8a", "x86_64", "armeabi-v7a")
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.parcelize)
alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.ksp)
alias(libs.plugins.spotless)
}
@Suppress("UnstableApiUsage")
android {
androidResources {
localeFilters += listOf(
"zh",
"zh-rCN",
"zh-rHK",
"zh-rTW",
"ja",
)
}
splits {
abi {
isEnable = true
reset()
if (isRelease) {
include(*supportedAbis)
isUniversalApk = true
} else {
include("x86_64", "x86")
}
}
}
val signConfig = signingConfigs.create("release") {
storeFile = File(projectDir.path + "/keystore/androidkey.jks")
storePassword = "000000"
keyAlias = "key0"
keyPassword = "000000"
enableV3Signing = true
enableV4Signing = true
}
val commitSha by lazy {
val stdout = providers.exec {
commandLine = "git rev-parse --short=7 HEAD".split(' ')
}.standardOutput
stdout.asText.get().trim()
}
val buildTime by lazy {
val formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm").withZone(ZoneOffset.UTC)
formatter.format(Instant.now())
}
defaultConfig {
applicationId = "org.moedog.ehviewer"
versionCode = 180014
versionName = "1.8.13"
buildConfigField("String", "VERSION_CODE", "\"${defaultConfig.versionCode}\"")
buildConfigField("String", "COMMIT_SHA", "\"$commitSha\"")
ndk {
if (isRelease) {
abiFilters.addAll(supportedAbis)
}
debugSymbolLevel = "FULL"
}
}
externalNativeBuild {
cmake {
path = File("src/main/cpp/CMakeLists.txt")
}
}
compileOptions {
isCoreLibraryDesugaringEnabled = true
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
lint {
abortOnError = true
checkReleaseBuilds = false
disable.add("MissingTranslation")
}
packaging {
resources {
excludes += "/META-INF/**"
excludes += "/kotlin/**"
excludes += "**.txt"
excludes += "**.bin"
}
}
dependenciesInfo.includeInApk = false
buildTypes {
release {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles("proguard-rules.pro")
signingConfig = signConfig
buildConfigField("String", "BUILD_TIME", "\"$buildTime\"")
}
debug {
applicationIdSuffix = ".debug"
buildConfigField("String", "BUILD_TIME", "\"\"")
}
}
buildFeatures {
buildConfig = true
}
namespace = "com.hippo.ehviewer"
}
dependencies {
// https://developer.android.com/jetpack/androidx/releases/activity
implementation(libs.androidx.activity)
implementation(libs.androidx.appcompat)
implementation(libs.androidx.biometric)
implementation(libs.androidx.browser)
implementation(libs.androidx.collection)
implementation(libs.androidx.webkit)
implementation(libs.androidx.core)
implementation(libs.androidx.coordinatorlayout)
implementation(libs.androidx.fragment)
// https://developer.android.com/jetpack/androidx/releases/lifecycle
implementation(libs.androidx.lifecycle.process)
// https://developer.android.com/jetpack/androidx/releases/paging
implementation(libs.androidx.paging.runtime)
implementation(libs.androidx.preference)
implementation(libs.androidx.recyclerview)
// https://developer.android.com/jetpack/androidx/releases/room
ksp(libs.androidx.room.compiler)
implementation(libs.androidx.room.paging)
implementation(libs.androidx.swiperefreshlayout)
implementation(libs.drawer)
implementation(libs.material)
// https://square.github.io/okhttp/changelogs/changelog/
implementation(platform(libs.okhttp.bom))
implementation(libs.okhttp.coroutines)
implementation(libs.okhttp.tls)
implementation(libs.okio.jvm)
// https://github.com/RikkaApps/RikkaX
implementation(libs.bundles.rikkax)
// https://coil-kt.github.io/coil/changelog/
implementation(platform(libs.coil.bom))
implementation(libs.bundles.coil)
implementation(libs.kotlinx.coroutines.android)
implementation(libs.kotlinx.datetime)
implementation(libs.kotlinx.serialization.cbor)
implementation(libs.ktor.utils)
implementation(libs.jsoup)
coreLibraryDesugaring(libs.desugar)
}
kotlin {
compilerOptions {
jvmTarget = JvmTarget.JVM_21
progressiveMode = true
optIn.addAll(
"coil3.annotation.ExperimentalCoilApi",
"kotlin.contracts.ExperimentalContracts",
"kotlin.time.ExperimentalTime",
"kotlinx.coroutines.ExperimentalCoroutinesApi",
"kotlinx.coroutines.FlowPreview",
"kotlinx.coroutines.InternalCoroutinesApi",
"kotlinx.serialization.ExperimentalSerializationApi",
)
}
}
configurations.all {
exclude("dev.rikka.rikkax.appcompat", "appcompat")
}
ksp {
arg("room.schemaLocation", "$projectDir/schemas")
arg("room.generateKotlin", "true")
}
val ktlintVersion = libs.ktlint.get().version
spotless {
kotlin {
// https://github.com/diffplug/spotless/issues/111
target("src/**/*.kt")
ktlint(ktlintVersion)
}
kotlinGradle {
ktlint(ktlintVersion)
}
}
================================================
FILE: app/proguard-rules.pro
================================================
-keepclassmembers class * implements android.os.Parcelable {
public static final ** CREATOR;
}
-keepclasseswithmembernames,includedescriptorclasses class * {
native <methods>;
}
-keepattributes LineNumberTable,SourceFile
-renamesourcefileattribute SourceFile
-repackageclasses
-allowaccessmodification
-overloadaggressively
================================================
FILE: app/schemas/com.hippo.network.CookiesDatabase/1.json
================================================
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "c801ee62729ba20a203b150211234d5c",
"entities": [
{
"tableName": "OK_HTTP_3_COOKIE",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`NAME` TEXT, `VALUE` TEXT, `EXPIRES_AT` INTEGER NOT NULL, `DOMAIN` TEXT, `PATH` TEXT, `SECURE` INTEGER NOT NULL, `HTTP_ONLY` INTEGER NOT NULL, `PERSISTENT` INTEGER NOT NULL, `HOST_ONLY` INTEGER NOT NULL, `_id` INTEGER NOT NULL, PRIMARY KEY(`_id`))",
"fields": [
{
"fieldPath": "name",
"columnName": "NAME",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "value",
"columnName": "VALUE",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "expiresAt",
"columnName": "EXPIRES_AT",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "domain",
"columnName": "DOMAIN",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "path",
"columnName": "PATH",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "secure",
"columnName": "SECURE",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "httpOnly",
"columnName": "HTTP_ONLY",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "persistent",
"columnName": "PERSISTENT",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "hostOnly",
"columnName": "HOST_ONLY",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"_id"
]
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'c801ee62729ba20a203b150211234d5c')"
]
}
}
================================================
FILE: app/schemas/com.hippo.network.CookiesDatabase/2.json
================================================
{
"formatVersion": 1,
"database": {
"version": 2,
"identityHash": "1b80cd29939b0f43934721f1289ba94d",
"entities": [
{
"tableName": "OK_HTTP_3_COOKIE",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`NAME` TEXT NOT NULL, `VALUE` TEXT NOT NULL, `EXPIRES_AT` INTEGER NOT NULL, `DOMAIN` TEXT NOT NULL, `PATH` TEXT NOT NULL, `SECURE` INTEGER NOT NULL, `HTTP_ONLY` INTEGER NOT NULL, `PERSISTENT` INTEGER NOT NULL, `HOST_ONLY` INTEGER NOT NULL, `_id` INTEGER, PRIMARY KEY(`_id`))",
"fields": [
{
"fieldPath": "name",
"columnName": "NAME",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "value",
"columnName": "VALUE",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "expiresAt",
"columnName": "EXPIRES_AT",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "domain",
"columnName": "DOMAIN",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "path",
"columnName": "PATH",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "secure",
"columnName": "SECURE",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "httpOnly",
"columnName": "HTTP_ONLY",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "persistent",
"columnName": "PERSISTENT",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "hostOnly",
"columnName": "HOST_ONLY",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"_id"
]
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '1b80cd29939b0f43934721f1289ba94d')"
]
}
}
================================================
FILE: app/src/debug/res/values/strings.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright 2016 Hippo Seven
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<resources>
<string name="app_name" translatable="false">EhViewer Debug</string>
</resources>
================================================
FILE: app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright 2016 Hippo Seven
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-feature android:name="android.software.leanback" android:required="false" />
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />
<uses-feature
android:glEsVersion="0x00030000"
android:required="true" />
<application
android:name="com.hippo.ehviewer.EhApplication"
android:allowBackup="true"
android:appCategory="image"
android:dataExtractionRules="@xml/data_extraction_rules"
android:enableOnBackInvokedCallback="false"
android:fullBackupContent="@xml/backup_scheme"
android:hasFragileUserData="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:localeConfig="@xml/locale_config"
android:largeHeap="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:theme="@style/AppTheme"
tools:ignore="UnusedAttribute">
<activity
android:name="com.hippo.ehviewer.ui.MainActivity"
android:banner="@mipmap/ic_leanback_banner"
android:configChanges="screenSize"
android:exported="true"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize|stateAlwaysHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.shortcuts"
android:resource="@xml/shortcuts" />
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="exhentai.org" />
<data android:host="e-hentai.org" />
</intent-filter>
<intent-filter android:label="@string/keyword_search">
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
<intent-filter android:label="@string/image_search">
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
</activity>
<activity
android:name="com.hippo.ehviewer.ui.GalleryActivity"
android:configChanges="screenSize"
android:exported="true"
android:launchMode="singleTask"
android:theme="@style/AppTheme.Gallery">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="file" />
<data android:scheme="content" />
<data android:host="*" />
<data android:mimeType="application/octet-stream" />
<data android:mimeType="application/7z" />
<data android:mimeType="application/rar" />
<data android:mimeType="application/zip" />
<data android:mimeType="application/x-7z-compressed" />
<data android:mimeType="application/x-rar-compressed" />
<data android:mimeType="application/x-zip-compressed" />
<data android:mimeType="application/x-tar" />
<data android:mimeType="application/x-xz" />
<data android:mimeType="application/gzip" />
<data android:mimeType="application/x-cbz" />
<data android:mimeType="application/x-cbr" />
<data android:mimeType="application/x-cbt" />
<data android:mimeType="application/x-cb7" />
<!-- untested -->
<data android:mimeType="application/vnd.comicbook+zip" />
<data android:mimeType="application/vnd.comicbook-rar" />
<data android:mimeType="application/x-compressed-tar" />
<data android:mimeType="application/x-bzip-compressed-tar" />
<data android:mimeType="application/x-lzma-compressed-tar" />
<data android:mimeType="application/x-xz-compressed-tar" />
</intent-filter>
</activity>
<activity
android:name="com.hippo.ehviewer.ui.SettingsActivity"
android:configChanges="screenSize"
android:label="@string/settings"
android:theme="@style/AppTheme" />
<activity
android:name="com.hippo.ehviewer.shortcuts.ShortcutsActivity"
android:excludeFromRecents="true"
android:launchMode="singleTask"
android:taskAffinity=""
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
<activity
android:name=".ui.WebViewActivity" />
<service
android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
android:enabled="false"
android:exported="false">
<meta-data
android:name="autoStoreLocales"
android:value="true" />
</service>
<service
android:name="com.hippo.ehviewer.download.DownloadService"
android:foregroundServiceType="dataSync"
android:label="@string/download_service_label" />
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
</application>
</manifest>
================================================
FILE: app/src/main/cpp/0001-Insert-link-libs.patch
================================================
From aee8f7147ddb262fd9e5feee8d5b17094cf3470f Mon Sep 17 00:00:00 2001
From: FooIbar <118464521+FooIbar@users.noreply.github.com>
Date: Tue, 26 Sep 2023 00:09:25 +0800
Subject: [PATCH] Insert link libs
---
CMakeLists.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ec97e4c7..420f204c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -438,7 +438,7 @@ IF(DEFINED __GNUWIN32PATH AND EXISTS "${__GNUWIN32PATH}")
# # endif
ENDIF(DEFINED __GNUWIN32PATH AND EXISTS "${__GNUWIN32PATH}")
-SET(ADDITIONAL_LIBS "")
+SET(ADDITIONAL_LIBS ${LIBARCHIVE_CUSTOM_LIBS})
#
# Find ZLIB
#
--
2.34.1
================================================
FILE: app/src/main/cpp/0002-Fix-zip_time-performance.patch
================================================
From e971b9f23727833cc39b9e325db30f383e5bfc30 Mon Sep 17 00:00:00 2001
From: Dude so hot <djohn@fbi.gov>
Date: Thu, 14 Nov 2024 00:28:13 +0800
Subject: [PATCH] Fix zip_time performance
Signed-off-by: Dude so hot <djohn@fbi.gov>
---
libarchive/archive_time.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/libarchive/archive_time.c b/libarchive/archive_time.c
index 3352c809..9289bf1e 100644
--- a/libarchive/archive_time.c
+++ b/libarchive/archive_time.c
@@ -53,6 +53,7 @@ FILETIME_to_ntfs(const FILETIME* filetime)
int64_t
dos_to_unix(uint32_t dos_time)
{
+ return 0;
uint16_t msTime, msDate;
struct tm ts;
time_t t;
--
2.47.0
================================================
FILE: app/src/main/cpp/0003-Use-UTF-8-as-default-charset-on-bionic.patch
================================================
From 86d199429b3fabc83f7dcc9afd72e7b4c7750b1a Mon Sep 17 00:00:00 2001
From: FooIbar <118464521+FooIbar@users.noreply.github.com>
Date: Thu, 14 Nov 2024 20:22:52 +0800
Subject: [PATCH] Use UTF-8 as default charset on bionic
---
libarchive/archive_string.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/libarchive/archive_string.c b/libarchive/archive_string.c
index abf7ad66..63a73c58 100644
--- a/libarchive/archive_string.c
+++ b/libarchive/archive_string.c
@@ -423,7 +423,9 @@ static const char *
default_iconv_charset(const char *charset) {
if (charset != NULL && charset[0] != '\0')
return charset;
-#if HAVE_LOCALE_CHARSET && !defined(__APPLE__)
+#ifdef __BIONIC__
+ return "UTF-8";
+#elif HAVE_LOCALE_CHARSET && !defined(__APPLE__)
/* locale_charset() is broken on Mac OS */
return locale_charset();
#elif HAVE_NL_LANGINFO
--
2.43.0
================================================
FILE: app/src/main/cpp/CMakeLists.txt
================================================
cmake_minimum_required(VERSION 3.14)
project(ehviewer C)
include(FetchContent)
if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Ofast -fvisibility=hidden -fvisibility-inlines-hidden -funroll-loops -flto \
-mllvm -polly \
-mllvm -polly-run-dce \
-mllvm -polly-run-inliner \
-mllvm -polly-isl-arg=--no-schedule-serialize-sccs \
-mllvm -polly-ast-use-context \
-mllvm -polly-detect-keep-going \
-mllvm -polly-position=before-vectorizer \
-mllvm -polly-vectorizer=stripmine \
-mllvm -polly-detect-profitability-min-per-loop-insts=40 \
-mllvm -polly-invariant-load-hoisting")
endif (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
option(BUILD_TESTING OFF)
option(XZ_DOC OFF)
option(XZ_LZIP_DECODER OFF)
option(XZ_MICROLZMA_DECODER OFF)
option(XZ_MICROLZMA_ENCODER OFF)
option(XZ_TOOL_LZMADEC OFF)
option(XZ_TOOL_LZMAINFO OFF)
option(XZ_TOOL_XZ OFF)
option(XZ_TOOL_XZDEC OFF)
FetchContent_Declare(
liblzma
GIT_REPOSITORY https://github.com/tukaani-project/xz.git
GIT_TAG v5.8.1
GIT_SHALLOW 1
)
FetchContent_MakeAvailable(liblzma)
include_directories(${liblzma_SOURCE_DIR}/src/liblzma/api)
# Build GNUTLS libnettle
FetchContent_Declare(
nettle
URL https://ftp.gnu.org/gnu/nettle/nettle-3.10.2.tar.gz
URL_MD5 b28bcbf6f045ff007940a9401673600d
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/nettle/nettle
)
FetchContent_MakeAvailable(nettle)
add_subdirectory(nettle)
# Configure libnettle support for libarchive
include_directories(nettle)
include_directories(.)
set(HAVE_LIBNETTLE 1)
set(HAVE_NETTLE_AES_H 1)
set(HAVE_NETTLE_HMAC_H 1)
set(HAVE_NETTLE_MD5_H 1)
set(HAVE_NETTLE_PBKDF2_H 1)
set(HAVE_NETTLE_RIPEMD160_H 1)
set(HAVE_NETTLE_SHA_H 1)
# Configure lzma support for libarchive
SET(HAVE_LIBLZMA 1)
SET(HAVE_LZMA_H 1)
SET(HAVE_LZMA_STREAM_ENCODER_MT 1)
SET(HAVE_LZMADEC_H 1)
SET(HAVE_LIBLZMADEC 1)
option(ENABLE_OPENSSL OFF)
option(ENABLE_TAR OFF)
option(ENABLE_CPIO OFF)
option(ENABLE_CAT OFF)
option(ENABLE_UNZIP OFF)
option(ENABLE_TEST OFF)
# Configure libarchive link's static lib
SET(LIBARCHIVE_CUSTOM_LIBS "nettle" "liblzma")
set(LIBARCHIVE_PATCH
${CMAKE_CURRENT_LIST_DIR}/0001-Insert-link-libs.patch
${CMAKE_CURRENT_LIST_DIR}/0002-Fix-zip_time-performance.patch
${CMAKE_CURRENT_LIST_DIR}/0003-Use-UTF-8-as-default-charset-on-bionic.patch
)
FetchContent_Declare(
libarchive
GIT_REPOSITORY https://github.com/libarchive/libarchive.git
GIT_TAG v3.8.1
GIT_SHALLOW 1
PATCH_COMMAND git apply --check -R ${LIBARCHIVE_PATCH} || git apply ${LIBARCHIVE_PATCH}
)
FetchContent_MakeAvailable(libarchive)
include_directories(${libarchive_SOURCE_DIR}/libarchive)
# Build and link our app's native lib
add_library(${PROJECT_NAME} SHARED archive.c image.c gifutils.c hash.c natsort/strnatcmp.c)
target_link_libraries(${PROJECT_NAME} archive_static log jnigraphics GLESv3 -Wl,--exclude-libs,ALL)
================================================
FILE: app/src/main/cpp/archive.c
================================================
/*
* Copyright 2022-2024 Tarsin Norbin
*
* This file is part of EhViewer
*
* EhViewer is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* EhViewer is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* EhViewer. If not, see <https://www.gnu.org/licenses/>.
*/
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <sys/mman.h>
#include <jni.h>
#include <android/log.h>
#include <archive.h>
#include <archive_entry.h>
#define LOG_TAG "libarchive_wrapper"
#include "natsort/strnatcmp.h"
#include "ehviewer.h"
typedef struct {
int using;
int next_index;
struct archive *arc;
struct archive_entry *entry;
} archive_ctx;
typedef struct {
const char *filename;
int index;
ssize_t size;
void *addr;
} entry;
#define CTX_POOL_SIZE 20
#define MAX_PARALLEL_DECOMP 4
#define max(a, b) ((a) > (b) ? (a) : (b))
static pthread_mutex_t ctx_pool_mutex = PTHREAD_MUTEX_INITIALIZER;
static archive_ctx **ctx_pool = NULL;
static pthread_mutex_t buffer_mutex = PTHREAD_MUTEX_INITIALIZER;
static void *decode_buffer[MAX_PARALLEL_DECOMP];
static bool need_encrypt = false;
static char *passwd = NULL;
static void *archiveAddr = MAP_FAILED;
static size_t archiveSize = 0;
static entry *entries = NULL;
static size_t entryCount = 0;
static ssize_t max_file_size = 0;
#define SUPPORT_EXT_COUNT 11
const char supportExt[SUPPORT_EXT_COUNT][5] = {
"jpeg",
"jpg",
"png",
"gif",
"webp",
"bmp",
"ico",
"wbmp",
"heic",
"heif",
"avif"
};
static inline int filename_is_playable_file(const char *name) {
if (!name)
return false;
const char *dotptr = strrchr(name, '.');
if (!dotptr++)
return false;
int i;
for (i = 0; i < SUPPORT_EXT_COUNT; i++)
if (strcmp(dotptr, supportExt[i]) == 0)
return true;
return false;
}
static inline bool archive_entry_is_file(struct archive_entry *entry) {
return archive_entry_filetype(entry) == AE_IFREG;
}
static inline bool archive_entry_is_playable(struct archive_entry *entry) {
return archive_entry_is_file(entry) &&
filename_is_playable_file(archive_entry_pathname(entry));
}
static inline int compare_entries(const void *a, const void *b) {
const char *fa = ((entry *) a)->filename;
const char *fb = ((entry *) b)->filename;
return strnatcmp(fa, fb);
}
#define ADDR_IN_FILE_MAPPING(addr) (addr >= archiveAddr && addr < archiveAddr + archiveSize)
static bool fill_entry_zero_copy(struct archive *arc, entry *entry) {
void *buffer = NULL;
size_t buffer_size = 0;
la_int64_t output_ofs = 0;
archive_read_data_block(arc, (const void **) &buffer, &buffer_size, &output_ofs);
bool zero_copy = ADDR_IN_FILE_MAPPING(buffer) && !output_ofs && buffer_size == entry->size;
entry->addr = zero_copy ? buffer : NULL;
return zero_copy;
}
static void archive_map_entries_index(archive_ctx *ctx, bool sort) {
int count = 0;
bool zero_copy = true;
while (archive_read_next_header(ctx->arc, &ctx->entry) == ARCHIVE_OK) {
const char *name = archive_entry_pathname(ctx->entry);
if (archive_entry_is_file(ctx->entry) && filename_is_playable_file(name)) {
entries[count].filename = strdup(name);
entries[count].index = count;
ssize_t size = archive_entry_size(ctx->entry);
max_file_size = max(size, max_file_size);
entries[count].size = size;
// We don't expect zero copy if first content can't do zero copy
if (zero_copy) zero_copy = fill_entry_zero_copy(ctx->arc, &entries[count]);
count++;
}
}
if (sort) qsort(entries, entryCount, sizeof(entry), compare_entries);
}
static void *acquire_decode_buffer() {
void *addr = NULL;
pthread_mutex_lock(&buffer_mutex);
for (int i = 0; i < MAX_PARALLEL_DECOMP; ++i) {
addr = decode_buffer[i];
if (addr) {
decode_buffer[i] = NULL;
break;
}
}
pthread_mutex_unlock(&buffer_mutex);
if (!addr) addr = malloc(max_file_size);
return addr;
}
static void release_decode_buffer(void *buffer) {
pthread_mutex_lock(&buffer_mutex);
for (int i = 0; i < MAX_PARALLEL_DECOMP; ++i) {
void *addr = decode_buffer[i];
if (!addr) {
decode_buffer[i] = buffer;
pthread_mutex_unlock(&buffer_mutex);
return;
}
}
pthread_mutex_unlock(&buffer_mutex);
free(buffer);
}
static int archive_list_all_entries(archive_ctx *ctx) {
int count = 0;
while (archive_read_next_header(ctx->arc, &ctx->entry) == ARCHIVE_OK)
if (archive_entry_is_playable(ctx->entry))
count++;
return count;
}
static void archive_release_ctx(archive_ctx *ctx) {
if (ctx) {
archive_read_close(ctx->arc);
archive_read_free(ctx->arc);
free(ctx);
}
}
static archive_ctx *archive_alloc_ctx() {
archive_ctx *ctx = calloc(1, sizeof(archive_ctx));
ctx->arc = archive_read_new();
ctx->using = 1;
archive_read_support_format_tar(ctx->arc);
archive_read_support_format_7zip(ctx->arc);
archive_read_support_format_rar5(ctx->arc);
archive_read_support_format_zip(ctx->arc);
archive_read_support_filter_gzip(ctx->arc);
archive_read_support_filter_xz(ctx->arc);
archive_read_set_option(ctx->arc, "zip", "ignorecrc32", "1");
if (passwd)
archive_read_add_passphrase(ctx->arc, passwd);
int err = archive_read_open_memory(ctx->arc, archiveAddr, archiveSize);
if (err < ARCHIVE_OK) {
LOGE("%s%s", "Open archive failed: ", archive_error_string(ctx->arc));
archive_read_free(ctx->arc);
free(ctx);
return NULL;
}
return ctx;
}
static int archive_skip_to_index(archive_ctx *ctx, int index) {
while (archive_read_next_header(ctx->arc, &ctx->entry) == ARCHIVE_OK) {
if (!archive_entry_is_playable(ctx->entry))
continue;
if (ctx->next_index++ == index) {
return ctx->next_index - 1;
}
}
return ARCHIVE_FATAL;
}
static int archive_get_ctx(archive_ctx **ctxptr, int idx) {
int ret;
archive_ctx *ctx = NULL;
pthread_mutex_lock(&ctx_pool_mutex);
for (int i = 0; i < CTX_POOL_SIZE; i++) {
if (!ctx_pool[i])
continue;
if (ctx_pool[i]->using)
continue;
if (ctx_pool[i]->next_index > idx)
continue;
if (!ctx || ctx_pool[i]->next_index > ctx->next_index)
ctx = ctx_pool[i];
if (ctx->next_index == idx)
break;
}
if (ctx)
ctx->using = 1;
pthread_mutex_unlock(&ctx_pool_mutex);
if (!ctx) {
archive_ctx *victimCtx = NULL;
int victimIdx = 0;
int replace = 1;
ctx = archive_alloc_ctx();
pthread_mutex_lock(&ctx_pool_mutex);
for (int i = 0; i < CTX_POOL_SIZE; i++) {
if (!ctx_pool[i]) {
ctx_pool[i] = ctx;
replace = 0;
break;
}
if (ctx_pool[i]->using)
continue;
if (!victimCtx || ctx_pool[i]->next_index > victimCtx->next_index) {
victimCtx = ctx_pool[i];
victimIdx = i;
}
}
if (replace) ctx_pool[victimIdx] = ctx;
pthread_mutex_unlock(&ctx_pool_mutex);
if (replace) archive_release_ctx(victimCtx);
}
ret = archive_skip_to_index(ctx, idx);
if (ret != idx) {
ret = archive_errno(ctx->arc);
LOGE("Skip to index failed: %s", archive_error_string(ctx->arc));
archive_release_ctx(ctx);
return ret;
}
*ctxptr = ctx;
return 0;
}
JNIEXPORT jint JNICALL
Java_com_hippo_ehviewer_jni_ArchiveKt_openArchive(JNIEnv *env, jclass thiz, jint fd, jlong size, jboolean sort_entries) {
EH_UNUSED(env);
EH_UNUSED(thiz);
archive_ctx *ctx = NULL;
archiveAddr = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0);
if (archiveAddr == MAP_FAILED) {
LOGE("%s%s", "mmap failed with error ", strerror(errno));
return 0;
}
archiveSize = size;
ctx_pool = calloc(CTX_POOL_SIZE, sizeof(archive_ctx **));
ctx = archive_alloc_ctx();
if (!ctx) return 0;
entryCount = archive_list_all_entries(ctx);
LOGI("%s%zu%s", "Found ", entryCount, " images in archive");
if (!entryCount) {
LOGE("%s%s", "Archive read failed: ", archive_error_string(ctx->arc));
archive_release_ctx(ctx);
return 0;
}
// We must read through the file|vm then we can know whether it is encrypted
int encryptRet = archive_read_has_encrypted_entries(ctx->arc);
switch (encryptRet) {
case 1: // At lease 1 encrypted entry
need_encrypt = true;
break;
case 0: // format supports but no encrypted entry found
default:
need_encrypt = false;
}
int format = archive_format(ctx->arc);
switch (format) {
case ARCHIVE_FORMAT_ZIP:
case ARCHIVE_FORMAT_RAR_V5:
madvise_log_if_error(archiveAddr, archiveSize, MADV_SEQUENTIAL);
break;
case ARCHIVE_FORMAT_7ZIP: // Seek is bad
madvise_log_if_error(archiveAddr, archiveSize, MADV_RANDOM);
break;
default:;
}
archive_release_ctx(ctx);
ctx = archive_alloc_ctx();
if (!ctx) return 0;
entries = calloc(entryCount, sizeof(entry));
archive_map_entries_index(ctx, sort_entries);
archive_release_ctx(ctx);
return (int) entryCount;
}
JNIEXPORT jobject JNICALL
Java_com_hippo_ehviewer_jni_ArchiveKt_extractToByteBuffer(JNIEnv *env, jclass thiz, jint index) {
EH_UNUSED(env);
EH_UNUSED(thiz);
entry *entry = &entries[index];
ssize_t size = entry->size;
if (entry->addr) {
return (*env)->NewDirectByteBuffer(env, entry->addr, size);
} else {
archive_ctx *ctx = NULL;
if (!archive_get_ctx(&ctx, entry->index)) {
void *addr = acquire_decode_buffer();
ssize_t bytes = archive_read_data(ctx->arc, addr, size);
ctx->using = 0;
if (bytes == size) {
return (*env)->NewDirectByteBuffer(env, addr, size);
} else {
if (bytes < 0) {
LOGE("%s%s", "Archive read failed: ", archive_error_string(ctx->arc));
} else {
LOGE("%s", "No enough data read, WTF?");
}
}
release_decode_buffer(addr);
}
}
return 0;
}
JNIEXPORT void JNICALL
Java_com_hippo_ehviewer_jni_ArchiveKt_closeArchive(JNIEnv *env, jclass thiz) {
EH_UNUSED(env);
EH_UNUSED(thiz);
if (ctx_pool) {
for (int i = 0; i < CTX_POOL_SIZE; i++)
archive_release_ctx(ctx_pool[i]);
free(ctx_pool);
ctx_pool = NULL;
}
free(passwd);
passwd = NULL;
need_encrypt = false;
if (archiveAddr != MAP_FAILED) {
munmap(archiveAddr, archiveSize);
archiveAddr = MAP_FAILED;
}
for (int i = 0; i < MAX_PARALLEL_DECOMP; ++i) {
free(decode_buffer[i]);
decode_buffer[i] = NULL;
}
max_file_size = 0;
if (entries) {
for (int i = 0; i < entryCount; ++i) {
free((void *) entries[i].filename);
}
free(entries);
entries = NULL;
}
}
JNIEXPORT jboolean JNICALL
Java_com_hippo_ehviewer_jni_ArchiveKt_needPassword(JNIEnv *env, jclass thiz) {
EH_UNUSED(env);
EH_UNUSED(thiz);
return need_encrypt;
}
JNIEXPORT jboolean JNICALL
Java_com_hippo_ehviewer_jni_ArchiveKt_providePassword(JNIEnv *env, jclass thiz, jstring str) {
EH_UNUSED(thiz);
struct archive_entry *entry;
archive_ctx *ctx;
jboolean ret = true;
int len = (*env)->GetStringUTFLength(env, str);
passwd = realloc(passwd, len + 1);
(*env)->GetStringUTFRegion(env, str, 0, len, passwd);
passwd[len] = 0;
ctx = archive_alloc_ctx();
char tmpBuf[4096];
while (archive_read_next_header(ctx->arc, &entry) == ARCHIVE_OK) {
if (!archive_entry_is_playable(entry))
continue;
if (!archive_entry_is_encrypted(entry))
continue;
if (archive_read_data(ctx->arc, tmpBuf, 4096) < ARCHIVE_OK) {
LOGE("%s%s", "Archive read failed: ", archive_error_string(ctx->arc));
ret = false;
}
break;
}
archive_release_ctx(ctx);
return ret;
}
JNIEXPORT jstring JNICALL
Java_com_hippo_ehviewer_jni_ArchiveKt_getFilename(JNIEnv *env, jclass thiz, jint index) {
EH_UNUSED(env);
EH_UNUSED(thiz);
index = entries[index].index;
archive_ctx *ctx = NULL;
int ret;
ret = archive_get_ctx(&ctx, index);
if (ret)
return NULL;
jstring str = (*env)->NewStringUTF(env, archive_entry_pathname(ctx->entry));
ctx->using = 0;
return str;
}
JNIEXPORT jboolean JNICALL
Java_com_hippo_ehviewer_jni_ArchiveKt_extractToFd(JNIEnv *env, jclass thiz, jint index, jint fd) {
EH_UNUSED(env);
EH_UNUSED(thiz);
index = entries[index].index;
archive_ctx *ctx = NULL;
int ret;
ret = archive_get_ctx(&ctx, index);
if (!ret) {
ret = archive_read_data_into_fd(ctx->arc, fd);
ctx->using = 0;
}
return ret == ARCHIVE_OK;
}
JNIEXPORT void JNICALL
Java_com_hippo_ehviewer_jni_ArchiveKt_releaseByteBuffer(JNIEnv *env, jclass thiz, jobject buffer) {
EH_UNUSED(thiz);
void *addr = (*env)->GetDirectBufferAddress(env, buffer);
if (!ADDR_IN_FILE_MAPPING(addr)) {
release_decode_buffer(addr);
}
}
================================================
FILE: app/src/main/cpp/ehviewer.h
================================================
/*
* Copyright 2022 Tarsin Norbin
*
* This file is part of EhViewer
*
* EhViewer is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* EhViewer is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* EhViewer. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef EHVIEWER_EHVIEWER_H
#define EHVIEWER_EHVIEWER_H
#define EH_UNUSED(x) (void)x
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG ,__VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG ,__VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG ,__VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG ,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG ,__VA_ARGS__)
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL, LOG_TAG ,__VA_ARGS__)
#define madvise_log_if_error(addr, len, advice) \
if (madvise(addr, len, advice)) \
LOGE("%s%p%s%zu%s%d%s%s%s", "madvise addr:", addr, "len:", len, "with advice ", advice, " failed with error: ", strerror(errno), ", Ignored")
#endif /* EHVIEWER_EHVIEWER_H */
================================================
FILE: app/src/main/cpp/gifutils.c
================================================
/*
* Copyright 2023 Tarsin Norbin
*
* This file is part of EhViewer
*
* EhViewer is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* EhViewer is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* EhViewer. If not, see <https://www.gnu.org/licenses/>.
*/
#include <jni.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
#include <android/log.h>
#include <sys/stat.h>
#include <sys/mman.h>
#define LOG_TAG "gifUtils"
#include "ehviewer.h"
#define GIF_HEADER_87A "GIF87a"
#define GIF_HEADER_89A "GIF89a"
#define GIF_HEADER_LENGTH 6
static int FRAME_DELAY_START_MARKER = 0x0021F904;
typedef signed char byte;
#define FRAME_DELAY_START_MARKER ((byte*)(&FRAME_DELAY_START_MARKER))
#define MINIMUM_FRAME_DELAY 2
#define DEFAULT_FRAME_DELAY 10
static inline bool isGif(void *addr) {
return !memcmp(addr, GIF_HEADER_87A, GIF_HEADER_LENGTH) ||
!memcmp(addr, GIF_HEADER_89A, GIF_HEADER_LENGTH);
}
static void doRewrite(byte *addr, size_t size) {
if (size < 7 || !isGif(addr)) return;
for (size_t i = 0; i < size - 8; i++) {
// TODO: Optimize this hex find with SIMD?
if (addr[i] == FRAME_DELAY_START_MARKER[3] && addr[i + 1] == FRAME_DELAY_START_MARKER[2] &&
addr[i + 2] == FRAME_DELAY_START_MARKER[1] &&
addr[i + 3] == FRAME_DELAY_START_MARKER[0]) {
byte *end = addr + i + 4;
if (end[4] != 0) continue;
int frameDelay = end[2] << 8 | end[1];
if (frameDelay >= MINIMUM_FRAME_DELAY)
break; // Quit if the first block looks normal, for performance
end[1] = DEFAULT_FRAME_DELAY;
end[2] = 0;
}
}
}
JNIEXPORT jboolean JNICALL
Java_com_hippo_ehviewer_jni_GifUtilsKt_isGif(JNIEnv *env, jclass clazz, jint fd) {
byte buffer[GIF_HEADER_LENGTH];
return read(fd, buffer, GIF_HEADER_LENGTH) == GIF_HEADER_LENGTH &&
isGif(buffer);
}
JNIEXPORT void JNICALL
Java_com_hippo_ehviewer_jni_GifUtilsKt_rewriteGifSource(JNIEnv *env, jclass clazz, jobject buffer) {
byte *addr = (*env)->GetDirectBufferAddress(env, buffer);
size_t size = (*env)->GetDirectBufferCapacity(env, buffer);
doRewrite(addr, size);
}
JNIEXPORT jobject JNICALL
Java_com_hippo_ehviewer_jni_GifUtilsKt_mmap(JNIEnv *env, jclass clazz, jint fd) {
struct stat64 st;
fstat64(fd, &st);
size_t size = st.st_size;
byte *addr = mmap64(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (addr == MAP_FAILED) return NULL;
return (*env)->NewDirectByteBuffer(env, addr, size);
}
JNIEXPORT void JNICALL
Java_com_hippo_ehviewer_jni_GifUtilsKt_munmap(JNIEnv *env, jclass clazz, jobject buffer) {
byte *addr = (*env)->GetDirectBufferAddress(env, buffer);
size_t size = (*env)->GetDirectBufferCapacity(env, buffer);
munmap(addr, size);
}
================================================
FILE: app/src/main/cpp/hash.c
================================================
/*
* Copyright 2022-2024 Tarsin Norbin
*
* This file is part of EhViewer
*
* EhViewer is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* EhViewer is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* EhViewer. If not, see <https://www.gnu.org/licenses/>.
*/
#include <unistd.h>
#include <jni.h>
#include <nettle/sha1.h>
#include "ehviewer.h"
#define BUFFER_SIZE 8192
typedef uint8_t byte;
const char hex_digits[] = "0123456789abcdef";
JNIEXPORT jstring JNICALL
Java_com_hippo_ehviewer_jni_HashKt_sha1(JNIEnv *env, jclass clazz, jint fd) {
EH_UNUSED(clazz);
struct sha1_ctx ctx;
sha1_init(&ctx);
size_t bytes_read;
byte buffer[BUFFER_SIZE];
while ((bytes_read = read(fd, buffer, BUFFER_SIZE)) > 0) {
sha1_update(&ctx, bytes_read, buffer);
}
byte digest[SHA1_DIGEST_SIZE];
sha1_digest(&ctx, SHA1_DIGEST_SIZE, digest);
byte byte;
char hex_digest[2 * SHA1_DIGEST_SIZE + 1];
for (int i = 0; i < SHA1_DIGEST_SIZE; i++) {
byte = digest[i];
hex_digest[2 * i] = hex_digits[byte >> 4 & 0xF];
hex_digest[2 * i + 1] = hex_digits[byte & 0xF];
}
hex_digest[2 * SHA1_DIGEST_SIZE] = '\0';
return (*env)->NewStringUTF(env, hex_digest);
}
================================================
FILE: app/src/main/cpp/image.c
================================================
/*
* Copyright 2022 Tarsin Norbin
*
* This file is part of EhViewer
*
* EhViewer is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* EhViewer is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* EhViewer. If not, see <https://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <android/bitmap.h>
#include <android/data_space.h>
#include <android/log.h>
#include <GLES3/gl3.h>
#include <jni.h>
#define TAG "ImageDecoder_wrapper"
#include "ehviewer.h"
#define IMAGE_TILE_MAX_SIZE (512 * 512)
static char tile_buffer[IMAGE_TILE_MAX_SIZE * 8];
bool copy_pixels(const void *src, int src_w, int src_h, int src_x, int src_y,
void *dst, int dst_w, int dst_h, int dst_x, int dst_y,
int width, int height, int stride) {
int left;
int line;
size_t line_stride;
int src_stride;
int src_pos;
int dst_pos;
size_t dst_blank_length;
// Sanitize
if (src_x < 0) {
width -= src_x;
dst_x -= src_x;
src_x = 0;
}
if (dst_x < 0) {
width -= dst_x;
src_x -= dst_x;
dst_x = 0;
}
if (width <= 0) {
return false;
}
if (src_y < 0) {
height -= src_y;
dst_y -= src_y;
src_y = 0;
}
if (dst_y < 0) {
height -= dst_y;
src_y -= dst_y;
dst_y = 0;
}
if (height <= 0) {
return false;
}
left = src_x + width - src_w;
if (left > 0) {
width -= left;
}
left = dst_x + width - dst_w;
if (left > 0) {
width -= left;
}
if (width <= 0) {
return false;
}
left = src_y + height - src_h;
if (left > 0) {
height -= left;
}
left = dst_y + height - dst_h;
if (left > 0) {
height -= left;
}
if (height <= 0) {
return false;
}
// Init
line_stride = (size_t) (width * stride);
src_stride = src_w * stride;
src_pos = src_y * src_stride + src_x * stride;
dst_pos = 0;
dst_blank_length = (size_t) (dst_y * dst_w + dst_x) * stride;
// First line
dst_pos += (int) dst_blank_length;
memcpy(dst + dst_pos, src + src_pos, line_stride);
dst_pos += (int) line_stride;
src_pos += src_stride;
// Other lines
dst_blank_length = (size_t) ((dst_w - width) * stride);
for (line = 1; line < height; line++) {
dst_pos += (int) dst_blank_length;
memcpy(dst + dst_pos, src + src_pos, line_stride);
dst_pos += (int) line_stride;
src_pos += src_stride;
}
return true;
}
JNIEXPORT void JNICALL
Java_com_hippo_ehviewer_jni_ImageKt_nativeTexImage(JNIEnv *env, jclass clazz, jobject bitmap, jboolean init,
jint offset_x, jint offset_y, jint width, jint height) {
if (width * height > IMAGE_TILE_MAX_SIZE)
return;
AndroidBitmapInfo info;
void *pixels = NULL;
AndroidBitmap_lockPixels(env, bitmap, &pixels);
AndroidBitmap_getInfo(env, bitmap, &info);
bool is_f16 = info.format == ANDROID_BITMAP_FORMAT_RGBA_F16;
copy_pixels(pixels, info.width, info.height, offset_x, offset_y, tile_buffer, width, height, 0, 0, width, height, is_f16 ? 8 : 4);
AndroidBitmap_unlockPixels(env, bitmap);
if (init) {
glTexImage2D(GL_TEXTURE_2D, 0, is_f16 ? GL_RGBA16F : GL_RGBA8, width, height, 0, GL_RGBA,
is_f16 ? GL_HALF_FLOAT : GL_UNSIGNED_BYTE, tile_buffer);
} else {
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA,
is_f16 ? GL_HALF_FLOAT : GL_UNSIGNED_BYTE, tile_buffer);
}
}
================================================
FILE: app/src/main/cpp/natsort/strnatcmp.c
================================================
/* -*- mode: c; c-file-style: "k&r" -*-
strnatcmp.c -- Perform 'natural order' comparisons of strings in C.
Copyright (C) 2000, 2004 by Martin Pool <mbp sourcefrog net>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/* partial change history:
*
* 2004-10-10 mbp: Lift out character type dependencies into macros.
*
* Eric Sosman pointed out that ctype functions take a parameter whose
* value must be that of an unsigned int, even on platforms that have
* negative chars in their default char type.
*/
#include <ctype.h>
#include "strnatcmp.h"
/* These are defined as macros to make it easier to adapt this code to
* different characters types or comparison functions. */
static inline int
nat_isdigit(const char *a)
{
return isdigit((unsigned char) *a);
}
static inline int
nat_isspace(const char *a)
{
return isspace((unsigned char) *a) || *a == '0' && nat_isdigit(a + 1);
}
static int
compare_right(const char *a, const char *b)
{
int bias = 0;
/* The longest run of digits wins. That aside, the greatest
value wins, but we can't know that it will until we've scanned
both numbers to know that they have the same magnitude, so we
remember it in BIAS. */
for (;; a++, b++) {
if (!nat_isdigit(a) && !nat_isdigit(b))
return bias;
if (!nat_isdigit(a))
return -1;
if (!nat_isdigit(b))
return +1;
if (*a < *b) {
if (!bias)
bias = -1;
} else if (*a > *b) {
if (!bias)
bias = +1;
} else if (!*a && !*b)
return bias;
}
}
int
strnatcmp(const char *a, const char *b)
{
int result;
while (1) {
/* skip over leading spaces or zeros */
while (nat_isspace(a))
a++;
while (nat_isspace(b))
b++;
/* process run of digits */
if (nat_isdigit(a) && nat_isdigit(b)) {
if ((result = compare_right(a, b)) != 0)
return result;
}
if (!*a && !*b) {
/* The strings compare the same. Perhaps the caller
will want to call strcmp to break the tie. */
return 0;
}
if (*a < *b)
return -1;
if (*a > *b)
return +1;
a++; b++;
}
}
================================================
FILE: app/src/main/cpp/natsort/strnatcmp.h
================================================
/* -*- mode: c; c-file-style: "k&r" -*-
strnatcmp.c -- Perform 'natural order' comparisons of strings in C.
Copyright (C) 2000, 2004 by Martin Pool <mbp sourcefrog net>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifdef __cplusplus
extern "C" {
#endif
int strnatcmp(const char *a, const char *b);
#ifdef __cplusplus
}
#endif
================================================
FILE: app/src/main/cpp/nettle/.gitignore
================================================
/nettle
================================================
FILE: app/src/main/cpp/nettle/CMakeLists.txt
================================================
cmake_minimum_required(VERSION 3.4.1)
project(nettle C)
set(LIBNETTLE_DEFINITIONS
-DHAVE_CONFIG_H)
set(LIBNETTLE_SOURCES
nettle/aes-decrypt-internal.c
nettle/aes-decrypt.c
nettle/aes-decrypt-table.c
nettle/aes128-decrypt.c
nettle/aes192-decrypt.c
nettle/aes256-decrypt.c
nettle/aes-encrypt-internal.c
nettle/aes-encrypt.c
nettle/aes-encrypt-table.c
nettle/aes128-encrypt.c
nettle/aes192-encrypt.c
nettle/aes256-encrypt.c
nettle/aes-invert-internal.c
nettle/aes-set-key-internal.c
nettle/aes-set-encrypt-key.c
nettle/aes-set-decrypt-key.c
nettle/aes128-set-encrypt-key.c
nettle/aes128-set-decrypt-key.c
nettle/aes128-meta.c
nettle/aes192-set-encrypt-key.c
nettle/aes192-set-decrypt-key.c
nettle/aes192-meta.c
nettle/aes256-set-encrypt-key.c
nettle/aes256-set-decrypt-key.c
nettle/aes256-meta.c
nettle/nist-keywrap.c
nettle/arcfour.c
nettle/arctwo.c
nettle/arctwo-meta.c
nettle/blowfish.c
nettle/blowfish-bcrypt.c
nettle/base16-encode.c
nettle/base16-decode.c
nettle/base16-meta.c
nettle/base64-encode.c
nettle/base64-decode.c
nettle/base64-meta.c
nettle/base64url-encode.c
nettle/base64url-decode.c
nettle/base64url-meta.c
nettle/buffer.c
nettle/buffer-init.c
nettle/camellia-crypt-internal.c
nettle/camellia-table.c
nettle/camellia-absorb.c
nettle/camellia-invert-key.c
nettle/camellia128-set-encrypt-key.c
nettle/camellia128-crypt.c
nettle/camellia128-set-decrypt-key.c
nettle/camellia128-meta.c
nettle/camellia192-meta.c
nettle/camellia256-set-encrypt-key.c
nettle/camellia256-crypt.c
nettle/camellia256-set-decrypt-key.c
nettle/camellia256-meta.c
nettle/cast128.c
nettle/cast128-meta.c
nettle/cbc.c
nettle/cbc-aes128-encrypt.c
nettle/cbc-aes192-encrypt.c
nettle/cbc-aes256-encrypt.c
nettle/ccm.c
nettle/ccm-aes128.c
nettle/ccm-aes192.c
nettle/ccm-aes256.c
nettle/cfb.c
nettle/siv-cmac.c
nettle/siv-cmac-aes128.c
nettle/siv-cmac-aes256.c
nettle/cnd-memcpy.c
nettle/chacha-crypt.c
nettle/chacha-core-internal.c
nettle/chacha-poly1305.c
nettle/chacha-poly1305-meta.c
nettle/chacha-set-key.c
nettle/chacha-set-nonce.c
nettle/ctr.c
nettle/ctr16.c
nettle/des.c
nettle/des3.c
nettle/eax.c
nettle/eax-aes128.c
nettle/eax-aes128-meta.c
nettle/ghash-set-key.c
nettle/ghash-update.c
nettle/gcm.c
nettle/gcm-aes.c
nettle/gcm-aes128.c
nettle/gcm-aes128-meta.c
nettle/gcm-aes192.c
nettle/gcm-aes192-meta.c
nettle/gcm-aes256.c
nettle/gcm-aes256-meta.c
nettle/gcm-camellia128.c
nettle/gcm-camellia128-meta.c
nettle/gcm-camellia256.c
nettle/gcm-camellia256-meta.c
nettle/cmac.c
nettle/cmac64.c
nettle/cmac-aes128.c
nettle/cmac-aes256.c
nettle/cmac-des3.c
nettle/cmac-aes128-meta.c
nettle/cmac-aes256-meta.c
nettle/cmac-des3-meta.c
nettle/gost28147.c
nettle/gosthash94.c
nettle/gosthash94-meta.c
nettle/hmac.c
nettle/hmac-gosthash94.c
nettle/hmac-md5.c
nettle/hmac-ripemd160.c
nettle/hmac-sha1.c
nettle/hmac-sha224.c
nettle/hmac-sha256.c
nettle/hmac-sha384.c
nettle/hmac-sha512.c
nettle/hmac-streebog.c
nettle/hmac-sm3.c
nettle/hmac-gosthash94-meta.c
nettle/hmac-md5-meta.c
nettle/hmac-ripemd160-meta.c
nettle/hmac-sha1-meta.c
nettle/hmac-sha224-meta.c
nettle/hmac-sha256-meta.c
nettle/hmac-sha384-meta.c
nettle/hmac-sha512-meta.c
nettle/hmac-streebog-meta.c
nettle/hmac-sm3-meta.c
nettle/knuth-lfib.c
nettle/hkdf.c
nettle/md2.c
nettle/md2-meta.c
nettle/md4.c
nettle/md4-meta.c
nettle/md5.c
nettle/md5-compat.c
nettle/md5-meta.c
nettle/memeql-sec.c
nettle/memxor.c
nettle/memxor3.c
nettle/nettle-lookup-hash.c
nettle/nettle-meta-aeads.c
nettle/nettle-meta-armors.c
nettle/nettle-meta-ciphers.c
nettle/nettle-meta-hashes.c
nettle/nettle-meta-macs.c
nettle/pbkdf2.c
nettle/pbkdf2-hmac-gosthash94.c
nettle/pbkdf2-hmac-sha1.c
nettle/pbkdf2-hmac-sha256.c
nettle/pbkdf2-hmac-sha384.c
nettle/pbkdf2-hmac-sha512.c
nettle/poly1305-aes.c
nettle/poly1305-internal.c
nettle/realloc.c
nettle/ripemd160.c
nettle/ripemd160-compress.c
nettle/ripemd160-meta.c
nettle/salsa20-core-internal.c
nettle/salsa20-crypt-internal.c
nettle/salsa20-crypt.c
nettle/salsa20r12-crypt.c
nettle/salsa20-set-key.c
nettle/salsa20-set-nonce.c
nettle/salsa20-128-set-key.c
nettle/salsa20-256-set-key.c
nettle/sha1.c
nettle/sha1-compress.c
nettle/sha1-meta.c
nettle/sha256.c
nettle/sha256-compress-n.c
nettle/sha224-meta.c
nettle/sha256-meta.c
nettle/sha512.c
nettle/sha512-compress.c
nettle/sha384-meta.c
nettle/sha512-meta.c
nettle/sha512-224-meta.c
nettle/sha512-256-meta.c
nettle/sha3.c
nettle/sha3-permute.c
nettle/sha3-shake.c
nettle/sha3-224.c
nettle/sha3-224-meta.c
nettle/sha3-256.c
nettle/sha3-256-meta.c
nettle/sha3-384.c
nettle/sha3-384-meta.c
nettle/sha3-512.c
nettle/sha3-512-meta.c
nettle/shake128.c
nettle/shake256.c
nettle/sm3.c
nettle/sm3-meta.c
nettle/serpent-set-key.c
nettle/serpent-encrypt.c
nettle/serpent-decrypt.c
nettle/serpent-meta.c
nettle/streebog.c
nettle/streebog-meta.c
nettle/twofish.c
nettle/twofish-meta.c
nettle/umac-nh.c
nettle/umac-nh-n.c
nettle/umac-l2.c
nettle/umac-l3.c
nettle/umac-poly64.c
nettle/umac-poly128.c
nettle/umac-set-key.c
nettle/umac32.c
nettle/umac64.c
nettle/umac96.c
nettle/umac128.c
nettle/version.c
nettle/write-be32.c
nettle/write-le32.c
nettle/write-le64.c
nettle/yarrow256.c
nettle/yarrow_key_event.c
nettle/xts.c
nettle/xts-aes128.c
nettle/xts-aes256.c
)
set(LIBNETTLE_INCLUDES
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/nettle
)
add_library(nettle STATIC ${LIBNETTLE_SOURCES})
target_include_directories(nettle PUBLIC ${LIBNETTLE_INCLUDES})
target_compile_definitions(nettle PRIVATE ${LIBNETTLE_DEFINITIONS})
================================================
FILE: app/src/main/cpp/nettle/config.h
================================================
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */
/* Define to 1 if using 'alloca.c'. */
/* #undef C_ALLOCA */
/* Define to 1 if you have 'alloca', as a function or macro. */
#define HAVE_ALLOCA 1
/* Define to 1 if <alloca.h> works. */
#define HAVE_ALLOCA_H 1
/* Define if __builtin_bswap64 is available */
#define HAVE_BUILTIN_BSWAP64 1
/* Define if clock_gettime is available */
#define HAVE_CLOCK_GETTIME 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if you have the `elf_aux_info' function. */
/* #undef HAVE_ELF_AUX_INFO */
/* Define if fcntl file locking is available */
#define HAVE_FCNTL_LOCKING 1
/* Define if the compiler understands __attribute__ */
#define HAVE_GCC_ATTRIBUTE 1
/* Define to 1 if you have the `getline' function. */
#define HAVE_GETLINE 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have dlopen (with -ldl). */
#define HAVE_LIBDL 1
/* Define to 1 if you have the `gmp' library (-lgmp). */
/* #undef HAVE_LIBGMP */
/* Define if compiler and linker supports __attribute__ ifunc */
#define HAVE_LINK_IFUNC 1
/* Define to 1 if you have the <malloc.h> header file. */
#define HAVE_MALLOC_H 1
/* Define to 1 each of the following for which a native (ie. CPU specific)
implementation of the corresponding routine exists. */
/* #undef HAVE_NATIVE_memxor3 */
/* #undef HAVE_NATIVE_aes_decrypt */
/* #undef HAVE_NATIVE_aes_encrypt */
/* #undef HAVE_NATIVE_aes_invert */
/* #undef HAVE_NATIVE_aes128_decrypt */
/* #undef HAVE_NATIVE_aes128_encrypt */
/* #undef HAVE_NATIVE_aes128_invert_key */
/* #undef HAVE_NATIVE_aes128_set_decrypt_key */
/* #undef HAVE_NATIVE_aes128_set_encrypt_key */
/* #undef HAVE_NATIVE_aes192_decrypt */
/* #undef HAVE_NATIVE_aes192_encrypt */
/* #undef HAVE_NATIVE_aes192_invert_key */
/* #undef HAVE_NATIVE_aes192_set_decrypt_key */
/* #undef HAVE_NATIVE_aes192_set_encrypt_key */
/* #undef HAVE_NATIVE_aes256_decrypt */
/* #undef HAVE_NATIVE_aes256_encrypt */
/* #undef HAVE_NATIVE_aes256_invert_key */
/* #undef HAVE_NATIVE_aes256_set_decrypt_key */
/* #undef HAVE_NATIVE_aes256_set_encrypt_key */
/* #undef HAVE_NATIVE_cbc_aes128_encrypt */
/* #undef HAVE_NATIVE_cbc_aes192_encrypt */
/* #undef HAVE_NATIVE_cbc_aes256_encrypt */
/* #undef HAVE_NATIVE_chacha_core */
/* #undef HAVE_NATIVE_chacha_2core */
#define HAVE_NATIVE_chacha_3core 1
/* #undef HAVE_NATIVE_chacha_4core */
/* #undef HAVE_NATIVE_fat_chacha_2core */
/* #undef HAVE_NATIVE_fat_chacha_3core */
/* #undef HAVE_NATIVE_fat_chacha_4core */
/* #undef HAVE_NATIVE_ecc_curve25519_modp */
/* #undef HAVE_NATIVE_ecc_curve448_modp */
/* #undef HAVE_NATIVE_ecc_secp192r1_modp */
/* #undef HAVE_NATIVE_ecc_secp192r1_redc */
/* #undef HAVE_NATIVE_ecc_secp224r1_modp */
/* #undef HAVE_NATIVE_ecc_secp224r1_redc */
/* #undef HAVE_NATIVE_ecc_secp256r1_modp */
/* #undef HAVE_NATIVE_ecc_secp256r1_redc */
/* #undef HAVE_NATIVE_ecc_secp384r1_modp */
/* #undef HAVE_NATIVE_ecc_secp384r1_redc */
/* #undef HAVE_NATIVE_ecc_secp521r1_modp */
/* #undef HAVE_NATIVE_ecc_secp521r1_redc */
/* #undef HAVE_NATIVE_poly1305_set_key */
/* #undef HAVE_NATIVE_poly1305_block */
/* #undef HAVE_NATIVE_poly1305_digest */
/* #undef HAVE_NATIVE_poly1305_blocks */
/* #undef HAVE_NATIVE_fat_poly1305_blocks */
/* #undef HAVE_NATIVE_ghash_set_key */
/* #undef HAVE_NATIVE_ghash_update */
/* #undef HAVE_NATIVE_gcm_aes_encrypt */
/* #undef HAVE_NATIVE_gcm_aes_decrypt */
/* #undef HAVE_NATIVE_salsa20_core */
#define HAVE_NATIVE_salsa20_2core 1
/* #undef HAVE_NATIVE_fat_salsa20_2core */
/* #undef HAVE_NATIVE_sha1_compress */
/* #undef HAVE_NATIVE_sha256_compress_n */
/* #undef HAVE_NATIVE_sha512_compress */
/* #undef HAVE_NATIVE_sha3_permute */
/* #undef HAVE_NATIVE_umac_nh */
/* #undef HAVE_NATIVE_umac_nh_n */
/* Define to 1 if you have the <openssl/ec.h> header file. */
/* #undef HAVE_OPENSSL_EC_H */
/* Define to 1 if you have the <openssl/evp.h> header file. */
/* #undef HAVE_OPENSSL_EVP_H */
/* Define to 1 if you have the <openssl/rsa.h> header file. */
/* #undef HAVE_OPENSSL_RSA_H */
/* Define to 1 if you have the `secure_getenv' function. */
#define HAVE_SECURE_GETENV 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if you have the <valgrind/memcheck.h> header file. */
/* #undef HAVE_VALGRIND_MEMCHECK_H */
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "nettle-bugs@lists.lysator.liu.se"
/* Define to the full name of this package. */
#define PACKAGE_NAME "nettle"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "nettle 3.10.2"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "nettle"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "3.10.2"
/* The size of `long', as computed by sizeof. */
#define SIZEOF_LONG __SIZEOF_LONG__
/* The size of `size_t', as computed by sizeof. */
#define SIZEOF_SIZE_T __SIZEOF_SIZE_T__
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at runtime.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
/* #undef STACK_DIRECTION */
/* Define to 1 if all of the C90 standard headers exist (not just the ones
required in a freestanding environment). This macro is provided for
backward compatibility; new code need not use it. */
#define STDC_HEADERS 1
/* Defined to enable additional asserts */
/* #undef WITH_EXTRA_ASSERTS */
/* Defined if public key features are enabled */
/* #undef WITH_HOGWEED */
/* Define if you have openssl libcrypto (used for benchmarking) */
/* #undef WITH_OPENSSL */
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* # undef WORDS_BIGENDIAN */
# endif
#endif
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
/* Define to `int' if <sys/types.h> doesn't define. */
/* #undef gid_t */
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
/* #undef inline */
#endif
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
/* Define to `int' if <sys/types.h> doesn't define. */
/* #undef uid_t */
/* AIX requires this to be the first thing in the file. */
#ifndef __GNUC__
# if HAVE_ALLOCA_H
# include <alloca.h>
# else
# ifdef _AIX
#pragma alloca
# else
# ifndef alloca /* predefined by HP cc +Olibcalls */
char *alloca ();
# endif
# endif
/* Needed for alloca on windows */
# if HAVE_MALLOC_H
# include <malloc.h>
# endif
# endif
#else /* defined __GNUC__ */
# if HAVE_ALLOCA_H
# include <alloca.h>
# else
/* Needed for alloca on windows, also with gcc */
# if HAVE_MALLOC_H
# include <malloc.h>
# endif
# endif
#endif
#if __GNUC__ && HAVE_GCC_ATTRIBUTE
# define NORETURN __attribute__ ((__noreturn__))
# define PRINTF_STYLE(f, a) __attribute__ ((__format__ (__printf__, f, a)))
# define UNUSED __attribute__ ((__unused__))
#else
# define NORETURN
# define PRINTF_STYLE(f, a)
# define UNUSED
#endif
#if defined(__x86_64__) || defined(__arch64__)
# define HAVE_NATIVE_64_BIT 1
#else
/* Needs include of <limits.h> before use. */
# define HAVE_NATIVE_64_BIT (SIZEOF_LONG * CHAR_BIT >= 64)
#endif
================================================
FILE: app/src/main/cpp/nettle/keymap.h
================================================
================================================
FILE: app/src/main/cpp/nettle/rotors.h
================================================
================================================
FILE: app/src/main/cpp/nettle/version.h
================================================
/* version.h
Information about library version.
Copyright (C) 2015 Red Hat, Inc.
Copyright (C) 2015 Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#ifndef NETTLE_VERSION_H_INCLUDED
#define NETTLE_VERSION_H_INCLUDED
#ifdef __cplusplus
extern "C" {
#endif
/* Individual version numbers in decimal */
#define NETTLE_VERSION_MAJOR 3
#define NETTLE_VERSION_MINOR 10
#define NETTLE_USE_MINI_GMP 0
/* We need a preprocessor constant for GMP_NUMB_BITS, simply using
sizeof(mp_limb_t) * CHAR_BIT is not good enough. */
#if NETTLE_USE_MINI_GMP
# define GMP_NUMB_BITS n/a
#endif
int
nettle_version_major (void);
int
nettle_version_minor (void);
#ifdef __cplusplus
}
#endif
#endif /* NETTLE_VERSION_H_INCLUDED */
================================================
FILE: app/src/main/java/com/hippo/app/CheckBoxDialogBuilder.kt
================================================
/*
* Copyright 2016 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.app
import android.annotation.SuppressLint
import android.content.Context
import android.view.LayoutInflater
import android.widget.CheckBox
import androidx.appcompat.app.AlertDialog
import com.hippo.ehviewer.R
@SuppressLint("InflateParams")
class CheckBoxDialogBuilder(
context: Context,
message: String?,
checkText: String?,
checked: Boolean,
) : AlertDialog.Builder(
context,
) {
private val mCheckBox: CheckBox
val isChecked: Boolean
get() = mCheckBox.isChecked
init {
val view = LayoutInflater.from(getContext()).inflate(R.layout.dialog_checkbox_builder, null)
setView(view)
setMessage(message)
mCheckBox = view.findViewById(R.id.checkbox)
mCheckBox.text = checkText
mCheckBox.isChecked = checked
view.setOnClickListener { mCheckBox.toggle() }
}
}
================================================
FILE: app/src/main/java/com/hippo/app/EditTextCheckBoxDialogBuilder.kt
================================================
/*
* Copyright 2022 Moedog
*
* This file is part of EhViewer
*
* EhViewer is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* EhViewer is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with EhViewer.
* If not, see <https://www.gnu.org/licenses/>.
*/
package com.hippo.app
import android.annotation.SuppressLint
import android.content.Context
import android.content.DialogInterface
import android.view.KeyEvent
import android.view.LayoutInflater
import android.widget.CheckBox
import android.widget.EditText
import android.widget.TextView
import android.widget.TextView.OnEditorActionListener
import androidx.appcompat.app.AlertDialog
import com.google.android.material.textfield.TextInputLayout
import com.hippo.ehviewer.R
@SuppressLint("InflateParams")
class EditTextCheckBoxDialogBuilder(
context: Context,
text: String?,
hint: String?,
checkText: String?,
checked: Boolean,
) : AlertDialog.Builder(
context,
),
OnEditorActionListener {
private val mCheckBox: CheckBox
val isChecked: Boolean
get() = mCheckBox.isChecked
private val mTextInputLayout: TextInputLayout
private val editText: EditText
private var mDialog: AlertDialog? = null
val text: String
get() = editText.text.toString()
fun setError(error: CharSequence?) {
mTextInputLayout.error = error
}
override fun create(): AlertDialog {
mDialog = super.create()
return mDialog as AlertDialog
}
override fun onEditorAction(v: TextView?, p1: Int, event: KeyEvent?): Boolean = if (mDialog != null) {
val button = mDialog!!.getButton(DialogInterface.BUTTON_POSITIVE)
button?.performClick()
true
} else {
false
}
init {
val view = LayoutInflater.from(getContext()).inflate(R.layout.dialog_edittextcheckbox_builder, null)
setView(view)
mCheckBox = view.findViewById(R.id.checkbox)
mCheckBox.text = checkText
mCheckBox.isChecked = checked
view.setOnClickListener { mCheckBox.toggle() }
editText = view.findViewById(R.id.edit_text)
editText.setText(text)
editText.setSelection(editText.text.length)
editText.setOnEditorActionListener(this)
mTextInputLayout = view.findViewById(R.id.text_input_layout)
mTextInputLayout.hint = hint
}
}
================================================
FILE: app/src/main/java/com/hippo/app/EditTextDialogBuilder.kt
================================================
/*
* Copyright 2016 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.app
import android.annotation.SuppressLint
import android.content.Context
import android.content.DialogInterface
import android.view.KeyEvent
import android.view.LayoutInflater
import android.widget.EditText
import android.widget.TextView
import android.widget.TextView.OnEditorActionListener
import androidx.appcompat.app.AlertDialog
import com.google.android.material.textfield.TextInputLayout
import com.hippo.ehviewer.R
@SuppressLint("InflateParams")
class EditTextDialogBuilder(
context: Context,
text: String?,
hint: String?,
) : AlertDialog.Builder(
context,
),
OnEditorActionListener {
private val mTextInputLayout: TextInputLayout
val editText: EditText
private var mDialog: AlertDialog? = null
val text: String
get() = editText.text.toString()
fun setError(error: CharSequence?) {
mTextInputLayout.error = error
}
override fun create(): AlertDialog {
mDialog = super.create()
return mDialog as AlertDialog
}
override fun onEditorAction(v: TextView?, p1: Int, event: KeyEvent?): Boolean = if (mDialog != null) {
val button = mDialog!!.getButton(DialogInterface.BUTTON_POSITIVE)
button?.performClick()
true
} else {
false
}
init {
val view = LayoutInflater.from(getContext()).inflate(R.layout.dialog_edittext_builder, null)
setView(view)
mTextInputLayout = view as TextInputLayout
editText = view.findViewById(R.id.edit_text)
editText.setText(text)
editText.setSelection(editText.text.length)
editText.setOnEditorActionListener(this)
mTextInputLayout.hint = hint
}
}
================================================
FILE: app/src/main/java/com/hippo/app/ListCheckBoxDialogBuilder.kt
================================================
/*
* Copyright 2016 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.app
import android.annotation.SuppressLint
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.CheckBox
import android.widget.ListView
import androidx.appcompat.app.AlertDialog
import com.hippo.ehviewer.R
import com.hippo.yorozuya.ViewUtils
@SuppressLint("InflateParams")
class ListCheckBoxDialogBuilder(
context: Context,
items: List<CharSequence>,
listener: (ListCheckBoxDialogBuilder?, AlertDialog?, Int) -> Unit,
checkText: String?,
checked: Boolean,
) : AlertDialog.Builder(
context,
) {
private val mCheckBox: CheckBox
private var mDialog: AlertDialog? = null
val isChecked: Boolean
get() = mCheckBox.isChecked
override fun create(): AlertDialog {
mDialog = super.create()
return mDialog as AlertDialog
}
init {
val view =
LayoutInflater.from(getContext()).inflate(R.layout.dialog_list_checkbox_builder, null)
setView(view)
val listView = ViewUtils.`$$`(view, R.id.list_view) as ListView
mCheckBox = ViewUtils.`$$`(view, R.id.checkbox) as CheckBox
listView.adapter = ArrayAdapter(getContext(), R.layout.item_select_dialog, items)
listView.onItemClickListener =
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, position: Int, _: Long ->
listener(this@ListCheckBoxDialogBuilder, mDialog, position)
mDialog?.dismiss()
}
mCheckBox.text = checkText
mCheckBox.isChecked = checked
}
}
================================================
FILE: app/src/main/java/com/hippo/database/MSQLiteBuilder.kt
================================================
/*
* Copyright 2017 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.database
import android.content.Context
import android.database.sqlite.SQLiteOpenHelper
import android.util.SparseArray
class MSQLiteBuilder {
companion object {
const val COLUMN_ID = "_id"
private val JAVA_TYPE_TO_SQLITE_TYPE: MutableMap<Class<*>?, String> = HashMap()
private fun javaTypeToSQLiteType(clazz: Class<*>?): String = JAVA_TYPE_TO_SQLITE_TYPE[clazz]
?: throw IllegalStateException("Unknown type: $clazz")
init {
JAVA_TYPE_TO_SQLITE_TYPE[Boolean::class.javaPrimitiveType] =
"INTEGER NOT NULL DEFAULT 0"
JAVA_TYPE_TO_SQLITE_TYPE[Byte::class.javaPrimitiveType] =
"INTEGER NOT NULL DEFAULT 0"
JAVA_TYPE_TO_SQLITE_TYPE[Short::class.javaPrimitiveType] =
"INTEGER NOT NULL DEFAULT 0"
JAVA_TYPE_TO_SQLITE_TYPE[Int::class.javaPrimitiveType] = "INTEGER NOT NULL DEFAULT 0"
JAVA_TYPE_TO_SQLITE_TYPE[Long::class.javaPrimitiveType] =
"INTEGER NOT NULL DEFAULT 0"
JAVA_TYPE_TO_SQLITE_TYPE[Float::class.javaPrimitiveType] =
"REAL NOT NULL DEFAULT 0"
JAVA_TYPE_TO_SQLITE_TYPE[Double::class.javaPrimitiveType] = "REAL NOT NULL DEFAULT 0"
JAVA_TYPE_TO_SQLITE_TYPE[String::class.java] = "TEXT"
}
}
private val statementsMap = SparseArray<List<String>?>()
private var version = 0
private var statements: MutableList<String>? = null
/**
* Bump database version.
*/
fun version(version: Int): MSQLiteBuilder {
check(version > this.version) {
(
"New version must be bigger than current version. " +
"current version: " + this.version + ", new version: " + version + "."
)
}
this.version = version
statements = ArrayList()
statementsMap.put(version, statements)
return this
}
/**
* Creates a table with int [.COLUMN_ID] primary key.
*/
fun createTable(
table: String,
column: String = COLUMN_ID,
clazz: Class<*>? = Int::class.javaPrimitiveType,
): MSQLiteBuilder = statement("CREATE TABLE " + table + " (" + column + " " + javaTypeToSQLiteType(clazz) + " PRIMARY KEY);")
/**
* Drops a table.
*/
fun dropTable(table: String): MSQLiteBuilder = statement("DROP TABLE $table;")
/**
* Inserts a column to the table.
*/
fun insertColumn(table: String, column: String, clazz: Class<*>?): MSQLiteBuilder = statement(
"ALTER TABLE $table ADD COLUMN $column " + javaTypeToSQLiteType(
clazz,
) + ";",
)
/**
* Add a statement.
*/
fun statement(statement: String): MSQLiteBuilder {
check(!(version == 0 || statements == null)) { "Call version() first!" }
statements!!.add(statement)
return this
}
/**
* Build a SQLiteOpenHelper from it.
*/
fun build(context: Context?, name: String?, version: Int): SQLiteOpenHelper = MSQLiteOpenHelper(context, name, version, this)
fun getStatements(oldVersion: Int, newVersion: Int): List<String> {
val result: MutableList<String> = ArrayList()
for (i in oldVersion + 1..newVersion) {
val list = statementsMap[i]
if (list != null) {
result.addAll(list)
}
}
return result
}
}
================================================
FILE: app/src/main/java/com/hippo/database/MSQLiteOpenHelper.kt
================================================
/*
* Copyright 2017 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.database
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import com.hippo.util.SqlUtils
internal class MSQLiteOpenHelper(
context: Context?,
name: String?,
private val version: Int,
private val builder: MSQLiteBuilder,
) : SQLiteOpenHelper(context, name, null, version) {
override fun onCreate(db: SQLiteDatabase) {
onUpgrade(db, 0, version)
}
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
for (command in builder.getStatements(oldVersion, newVersion)) {
db.execSQL(command)
}
}
override fun onDowngrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
SqlUtils.dropAllTable(db)
onCreate(db)
}
}
================================================
FILE: app/src/main/java/com/hippo/drawable/AddDeleteDrawable.kt
================================================
/*
* Copyright (C) 2015 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.drawable
import android.animation.ObjectAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.ColorFilter
import android.graphics.Paint
import android.graphics.Path
import android.graphics.PixelFormat
import android.graphics.drawable.Drawable
import androidx.annotation.Keep
import androidx.core.graphics.withTranslation
import com.hippo.ehviewer.R
import com.hippo.yorozuya.MathUtils
import kotlin.math.roundToInt
/**
* @param context used to get the configuration for the drawable from
*/
class AddDeleteDrawable(context: Context, color: Int) : Drawable() {
private val mPaint = Paint()
private val mPath = Path()
private val mSize: Int
private var mProgress = 0f
private var mAutoUpdateMirror = false
private var mVerticalMirror = false
init {
val resources = context.resources
mSize = resources.getDimensionPixelSize(R.dimen.add_size)
val barThickness = resources.getDimension(R.dimen.add_thickness).roundToInt().toFloat()
mPaint.setColor(color)
mPaint.style = Paint.Style.STROKE
mPaint.strokeJoin = Paint.Join.MITER
mPaint.strokeCap = Paint.Cap.BUTT
mPaint.strokeWidth = barThickness
val halfSize = (mSize / 2).toFloat()
mPath.moveTo(0f, -halfSize)
mPath.lineTo(0f, halfSize)
mPath.moveTo(-halfSize, 0f)
mPath.lineTo(halfSize, 0f)
}
override fun draw(canvas: Canvas) {
val bounds = getBounds()
val canvasRotate: Float = if (mVerticalMirror) {
MathUtils.lerp(270f, 135f, mProgress)
} else {
MathUtils.lerp(0f, 135f, mProgress)
}
canvas.withTranslation(bounds.centerX().toFloat(), bounds.centerY().toFloat()) {
rotate(canvasRotate)
drawPath(mPath, mPaint)
}
}
fun setColor(color: Int) {
mPaint.setColor(color)
invalidateSelf()
}
override fun setAlpha(alpha: Int) {
mPaint.setAlpha(alpha)
}
override fun setColorFilter(cf: ColorFilter?) {
mPaint.setColorFilter(cf)
}
override fun getIntrinsicHeight(): Int = mSize * 6 / 5
override fun getIntrinsicWidth(): Int = mSize * 6 / 5
/**
* If set, canvas is flipped when progress reached to end and going back to start.
*/
private fun setVerticalMirror(verticalMirror: Boolean) {
mVerticalMirror = verticalMirror
}
@get:Keep
@set:Keep
var progress: Float
get() = mProgress
set(progress) {
if (mAutoUpdateMirror) {
if (progress == 1f) {
setVerticalMirror(true)
} else if (progress == 0f) {
setVerticalMirror(false)
}
}
mProgress = progress
invalidateSelf()
}
fun setAdd(duration: Long) {
setShape(false, duration)
}
fun setDelete(duration: Long) {
setShape(true, duration)
}
private fun setShape(delete: Boolean, duration: Long) {
if (!(!delete && mProgress == 0f || delete && mProgress == 1f)) {
val endProgress = if (delete) 1f else 0f
if (duration <= 0) {
progress = endProgress
} else {
val oa = ObjectAnimator.ofFloat(this, "progress", endProgress)
oa.setDuration(duration)
oa.setAutoCancel(true)
oa.start()
}
}
}
@Deprecated(
"Deprecated in Java",
ReplaceWith("PixelFormat.TRANSLUCENT", "android.graphics.PixelFormat"),
)
override fun getOpacity(): Int = PixelFormat.TRANSLUCENT
}
================================================
FILE: app/src/main/java/com/hippo/drawable/BatteryDrawable.kt
================================================
/*
* Copyright (C) 2014 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.drawable
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.ColorFilter
import android.graphics.Paint
import android.graphics.PixelFormat
import android.graphics.Rect
import android.graphics.drawable.Drawable
import com.hippo.yorozuya.MathUtils
import kotlin.math.sqrt
class BatteryDrawable : Drawable() {
private val mPaint: Paint = Paint(Paint.ANTI_ALIAS_FLAG or Paint.DITHER_FLAG)
private val mTopRect: Rect
private val mBottomRect: Rect
private val mRightRect: Rect
private val mHeadRect: Rect
private val mElectRect: Rect
private var mColor = Color.WHITE
private var mWarningColor = Color.RED
private var mElect = -1
private var mStart = 0
private var mStop = 0
init {
mPaint.style = Paint.Style.FILL
mTopRect = Rect()
mBottomRect = Rect()
mRightRect = Rect()
mHeadRect = Rect()
mElectRect = Rect()
updatePaint()
}
override fun onBoundsChange(bounds: Rect) {
val width = bounds.width()
val height = bounds.height()
val strokeWidth = (sqrt((width * width + height * height).toDouble()) * 0.06f).toInt()
val turn1 = width * 6 / 7
val turn2 = height / 3
val secBottom = height - strokeWidth
mStart = strokeWidth
mStop = turn1 - strokeWidth
mTopRect[0, 0, turn1] = strokeWidth
mBottomRect[0, secBottom, turn1] = height
mRightRect[turn1 - strokeWidth, strokeWidth, turn1] = secBottom
mHeadRect[turn1, turn2, width] = height - turn2
mElectRect[0, strokeWidth, mStop] = secBottom
}
/**
* How to draw:
* |------------------------------|
* |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\|
* |------------------------------|---|
* |/////////////////| |//|\\\|
* |/////////////////| |//|\\\|
* |------------------------------|---|
* |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\|
* |------------------------------|
*/
override fun draw(canvas: Canvas) {
if (mElect == -1) {
return
}
mElectRect.right = MathUtils.lerp(mStart, mStop, mElect / 100.0f)
canvas.drawRect(mTopRect, mPaint)
canvas.drawRect(mBottomRect, mPaint)
canvas.drawRect(mRightRect, mPaint)
canvas.drawRect(mHeadRect, mPaint)
canvas.drawRect(mElectRect, mPaint)
}
private val isWarn: Boolean
get() = mElect <= WARN_LIMIT
fun setColor(color: Int) {
if (mColor == color) {
return
}
mColor = color
if (!isWarn) {
mPaint.setColor(mColor)
invalidateSelf()
}
}
fun setWarningColor(color: Int) {
if (mWarningColor == color) {
return
}
mWarningColor = color
if (isWarn) {
mPaint.setColor(mWarningColor)
invalidateSelf()
}
}
fun setElect(elect: Int) {
if (mElect == elect) {
return
}
mElect = elect
updatePaint()
}
fun setElect(elect: Int, warn: Boolean) {
if (mElect == elect) {
return
}
mElect = elect
updatePaint(warn)
}
private fun updatePaint(warn: Boolean = isWarn) {
if (warn) {
mPaint.setColor(mWarningColor)
} else {
mPaint.setColor(mColor)
}
invalidateSelf()
}
override fun setAlpha(alpha: Int) {
mPaint.setAlpha(alpha)
}
override fun setColorFilter(cf: ColorFilter?) {
mPaint.setColorFilter(cf)
}
@Deprecated(
"Deprecated in Java",
ReplaceWith("PixelFormat.TRANSLUCENT", "android.graphics.PixelFormat"),
)
override fun getOpacity(): Int = PixelFormat.TRANSLUCENT
companion object {
const val WARN_LIMIT = 15
}
}
================================================
FILE: app/src/main/java/com/hippo/drawable/DrawerArrowDrawable.kt
================================================
/*
* Copyright (C) 2015 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.drawable
import android.animation.ObjectAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.ColorFilter
import android.graphics.Paint
import android.graphics.Path
import android.graphics.PixelFormat
import android.graphics.drawable.Drawable
import androidx.annotation.ColorInt
import androidx.annotation.Keep
import androidx.core.graphics.withTranslation
import com.hippo.ehviewer.R
import com.hippo.yorozuya.MathUtils
import kotlin.math.cos
import kotlin.math.roundToInt
import kotlin.math.sin
/**
* A drawable that can draw a "Drawer hamburger" menu or an Arrow and animate between them.
* @param context used to get the configuration for the drawable from
*/
class DrawerArrowDrawable(context: Context, color: Int) : Drawable() {
private val mPaint = Paint()
private val mBarThickness: Float
// The length of top and bottom bars when they merge into an arrow
private val mTopBottomArrowSize: Float
// The length of middle bar
private val mBarSize: Float
// The length of the middle bar when arrow is shaped
private val mMiddleArrowSize: Float
// The space between bars when they are parallel
private val mBarGap: Float
// Whether bars should spin or not during progress
private val mSpin: Boolean
// Use Path instead of canvas operations so that if color has transparency, overlapping sections
// wont look different
private val mPath = Path()
// The reported intrinsic size of the drawable.
private val mSize: Int
// the amount that overlaps w/ bar size when rotation is max
private val mMaxCutForBarSize: Float
// Whether we should mirror animation when animation is reversed.
private var mVerticalMirror = false
// The interpolated version of the original progress
private var mProgress = 0f
init {
val resources = context.resources
mPaint.isAntiAlias = true
mPaint.setColor(color)
mSize = resources.getDimensionPixelSize(R.dimen.dad_drawable_size)
// round this because having this floating may cause bad measurements
mBarSize = resources.getDimension(R.dimen.dad_bar_size).roundToInt().toFloat()
// round this because having this floating may cause bad measurements
mTopBottomArrowSize =
resources.getDimension(R.dimen.dad_top_bottom_bar_arrow_size).roundToInt().toFloat()
mBarThickness = resources.getDimension(R.dimen.dad_thickness)
// round this because having this floating may cause bad measurements
mBarGap = resources.getDimension(R.dimen.dad_gap_between_bars).roundToInt().toFloat()
mSpin = resources.getBoolean(R.bool.dad_spin_bars)
mMiddleArrowSize = resources.getDimension(R.dimen.dad_middle_bar_arrow_size)
mPaint.style = Paint.Style.STROKE
mPaint.strokeJoin = Paint.Join.MITER
mPaint.strokeCap = Paint.Cap.BUTT
mPaint.strokeWidth = mBarThickness
mMaxCutForBarSize = (mBarThickness / 2 * cos(ARROW_HEAD_ANGLE.toDouble())).toFloat()
}
/**
* If set, canvas is flipped when progress reached to end and going back to start.
*/
private fun setVerticalMirror(verticalMirror: Boolean) {
mVerticalMirror = verticalMirror
}
override fun draw(canvas: Canvas) {
val bounds = getBounds()
// Interpolated widths of arrow bars
val arrowSize = MathUtils.lerp(mBarSize, mTopBottomArrowSize, mProgress)
val middleBarSize = MathUtils.lerp(mBarSize, mMiddleArrowSize, mProgress)
// Interpolated size of middle bar
val middleBarCut = MathUtils.lerp(0f, mMaxCutForBarSize, mProgress).roundToInt().toFloat()
// The rotation of the top and bottom bars (that make the arrow head)
val rotation = MathUtils.lerp(0f, ARROW_HEAD_ANGLE, mProgress)
// The whole canvas rotates as the transition happens
val canvasRotate = MathUtils.lerp(-180, 0, mProgress).toFloat()
val arrowWidth = (arrowSize * cos(rotation.toDouble())).roundToInt().toFloat()
val arrowHeight = (arrowSize * sin(rotation.toDouble())).roundToInt().toFloat()
mPath.rewind()
val topBottomBarOffset = MathUtils.lerp(
mBarGap + mBarThickness,
-mMaxCutForBarSize,
mProgress,
)
val arrowEdge = -middleBarSize / 2
// draw middle bar
mPath.moveTo(arrowEdge + middleBarCut, 0f)
mPath.rLineTo(middleBarSize - middleBarCut * 2, 0f)
// bottom bar
mPath.moveTo(arrowEdge, topBottomBarOffset)
mPath.rLineTo(arrowWidth, arrowHeight)
// top bar
mPath.moveTo(arrowEdge, -topBottomBarOffset)
mPath.rLineTo(arrowWidth, -arrowHeight)
mPath.close()
canvas.withTranslation(bounds.centerX().toFloat(), bounds.centerY().toFloat()) {
// Rotate the whole canvas if spinning, if not, rotate it 180 to get
// the arrow pointing the other way for RTL.
if (mSpin) {
rotate(canvasRotate * if (mVerticalMirror) -1 else 1)
}
drawPath(mPath, mPaint)
}
}
fun setColor(@ColorInt color: Int) {
mPaint.setColor(color)
invalidateSelf()
}
override fun setAlpha(i: Int) {
mPaint.setAlpha(i)
}
override fun setColorFilter(colorFilter: ColorFilter?) {
mPaint.setColorFilter(colorFilter)
}
override fun getIntrinsicHeight(): Int = mSize
override fun getIntrinsicWidth(): Int = mSize
@Deprecated(
"Deprecated in Java",
ReplaceWith("PixelFormat.TRANSLUCENT", "android.graphics.PixelFormat"),
)
override fun getOpacity(): Int = PixelFormat.TRANSLUCENT
@get:Keep
@set:Keep
var progress: Float
get() = mProgress
set(progress) {
if (progress == 1f) {
setVerticalMirror(true)
} else if (progress == 0f) {
setVerticalMirror(false)
}
mProgress = progress
invalidateSelf()
}
fun setMenu(duration: Long) {
setShape(false, duration)
}
fun setArrow(duration: Long) {
setShape(true, duration)
}
private fun setShape(arrow: Boolean, duration: Long) {
if (!(!arrow && mProgress == 0f || arrow && mProgress == 1f)) {
val endProgress = if (arrow) 1f else 0f
if (duration <= 0) {
progress = endProgress
} else {
val oa = ObjectAnimator.ofFloat(this, "progress", endProgress)
oa.setDuration(duration)
oa.setAutoCancel(true)
oa.start()
}
}
}
companion object {
// The angle in degrees that the arrow head is inclined at.
private val ARROW_HEAD_ANGLE = Math.toRadians(45.0).toFloat()
}
}
================================================
FILE: app/src/main/java/com/hippo/drawable/PreciselyClipDrawable.kt
================================================
/*
* Copyright 2016 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.drawable
import android.graphics.Canvas
import android.graphics.Rect
import android.graphics.RectF
import android.graphics.drawable.Drawable
import android.graphics.drawable.DrawableWrapper
import androidx.core.graphics.withClip
/**
* Show a part of the original drawable
*/
class PreciselyClipDrawable(
drawable: Drawable,
offsetX: Int,
offsetY: Int,
width: Int,
height: Int,
) : DrawableWrapper(drawable) {
private val mScale: RectF
private val mTemp = Rect()
init {
val originWidth = drawable.intrinsicWidth.toFloat()
val originHeight = drawable.intrinsicHeight.toFloat()
mScale = RectF(
(offsetX / originWidth).coerceIn(0.0f, 1.0f),
(offsetY / originHeight).coerceIn(0.0f, 1.0f),
((offsetX + width) / originWidth).coerceIn(0.0f, 1.0f),
((offsetY + height) / originHeight).coerceIn(0.0f, 1.0f),
)
}
override fun onBoundsChange(bounds: Rect) {
mTemp.left = ((mScale.left * bounds.right - mScale.right * bounds.left) / (mScale.left * (1 - mScale.right) - mScale.right * (1 - mScale.left))).toInt()
mTemp.right = (((1 - mScale.right) * bounds.left - (1 - mScale.left) * bounds.right) / (mScale.left * (1 - mScale.right) - mScale.right * (1 - mScale.left))).toInt()
mTemp.top = ((mScale.top * bounds.bottom - mScale.bottom * bounds.top) / (mScale.top * (1 - mScale.bottom) - mScale.bottom * (1 - mScale.top))).toInt()
mTemp.bottom = (((1 - mScale.bottom) * bounds.top - (1 - mScale.top) * bounds.bottom) / (mScale.top * (1 - mScale.bottom) - mScale.bottom * (1 - mScale.top))).toInt()
super.onBoundsChange(mTemp)
}
override fun getIntrinsicWidth(): Int = (super.intrinsicWidth * mScale.width()).toInt()
override fun getIntrinsicHeight(): Int = (super.intrinsicHeight * mScale.height()).toInt()
override fun draw(canvas: Canvas) {
canvas.withClip(bounds) { super.draw(canvas) }
}
}
================================================
FILE: app/src/main/java/com/hippo/drawable/TriangleDrawable.kt
================================================
/*
* Copyright 2016 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.drawable
import android.graphics.Canvas
import android.graphics.ColorFilter
import android.graphics.Paint
import android.graphics.Path
import android.graphics.PixelFormat
import android.graphics.Rect
import android.graphics.drawable.Drawable
class TriangleDrawable(color: Int) : Drawable() {
private val mPaint: Paint = Paint(Paint.ANTI_ALIAS_FLAG or Paint.DITHER_FLAG)
private val mPath: Path
init {
mPaint.setColor(color)
mPath = Path()
}
fun setColor(color: Int) {
mPaint.setColor(color)
invalidateSelf()
}
override fun onBoundsChange(bounds: Rect) {
super.onBoundsChange(bounds)
mPath.reset()
mPath.moveTo(bounds.left.toFloat(), bounds.top.toFloat())
mPath.lineTo(bounds.right.toFloat(), bounds.top.toFloat())
mPath.lineTo(bounds.right.toFloat(), bounds.bottom.toFloat())
mPath.close()
}
override fun draw(canvas: Canvas) {
canvas.drawPath(mPath, mPaint)
}
override fun setAlpha(alpha: Int) {
mPaint.setAlpha(alpha)
}
override fun setColorFilter(colorFilter: ColorFilter?) {
mPaint.setColorFilter(colorFilter)
}
@Deprecated(
"Deprecated in Java",
ReplaceWith("PixelFormat.OPAQUE", "android.graphics.PixelFormat"),
)
override fun getOpacity(): Int = PixelFormat.OPAQUE
}
================================================
FILE: app/src/main/java/com/hippo/drawable/UnikeryDrawable.kt
================================================
/*
* Copyright 2015 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.drawable
import android.graphics.drawable.Animatable
import android.graphics.drawable.Drawable
import coil3.Image
import coil3.asDrawable
import coil3.imageLoader
import coil3.request.Disposable
import coil3.request.ImageRequest
import com.hippo.widget.ObservedTextView
class UnikeryDrawable(private val mTextView: ObservedTextView) :
WrapDrawable(),
ObservedTextView.OnWindowAttachListener {
private var mUrl: String? = null
private var task: Disposable? = null
init {
mTextView.setOnWindowAttachListener(this)
}
override fun onAttachedToWindow() {
load(mUrl)
}
override fun onDetachedFromWindow() {
if (task != null && !task!!.isDisposed) task!!.dispose()
clearDrawable()
}
fun load(url: String?) {
if (url != null) {
mUrl = url
val request =
ImageRequest.Builder(mTextView.context).data(url)
.memoryCacheKey(url)
.diskCacheKey(url)
.target(onSuccess = ::onGetValue)
.build()
task = mTextView.context.imageLoader.enqueue(request)
}
}
private fun clearDrawable() {
drawable = null
}
override var drawable: Drawable?
get() = super.drawable
set(newDrawable) {
// Remove old callback
val oldDrawable = drawable
oldDrawable?.callback = null
super.drawable = newDrawable
newDrawable?.callback = mTextView
updateBounds()
if (newDrawable != null) {
invalidateSelf()
}
}
override fun invalidateSelf() {
val cs = mTextView.getText()
mTextView.text = cs
}
private fun onGetValue(image: Image) {
clearDrawable()
drawable = image.asDrawable(mTextView.resources)
(drawable as? Animatable)?.start()
}
}
================================================
FILE: app/src/main/java/com/hippo/drawable/WrapDrawable.kt
================================================
/*
* Copyright 2015 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.drawable
import android.graphics.Canvas
import android.graphics.ColorFilter
import android.graphics.PixelFormat
import android.graphics.Rect
import android.graphics.drawable.Drawable
open class WrapDrawable : Drawable() {
open var drawable: Drawable? = null
fun updateBounds() {
setBounds(0, 0, intrinsicWidth, intrinsicHeight)
}
override fun draw(canvas: Canvas) {
drawable?.draw(canvas)
}
override fun setBounds(left: Int, top: Int, right: Int, bottom: Int) {
super.setBounds(left, top, right, bottom)
drawable?.setBounds(left, top, right, bottom)
}
override fun setBounds(bounds: Rect) {
super.bounds = bounds
drawable?.bounds = bounds
}
override fun getChangingConfigurations(): Int = drawable?.changingConfigurations ?: super.changingConfigurations
override fun setChangingConfigurations(configs: Int) {
super.changingConfigurations = configs
drawable?.changingConfigurations = configs
}
override fun setFilterBitmap(filter: Boolean) {
super.setFilterBitmap(filter)
drawable?.setFilterBitmap(filter)
}
override fun setAlpha(alpha: Int) {
drawable?.alpha = alpha
}
override fun setColorFilter(cf: ColorFilter?) {
drawable?.colorFilter = cf
}
@Deprecated(
"Deprecated in Java",
ReplaceWith("PixelFormat.TRANSLUCENT", "android.graphics.PixelFormat"),
)
override fun getOpacity(): Int = PixelFormat.TRANSLUCENT
override fun getIntrinsicWidth(): Int = drawable?.intrinsicWidth ?: super.intrinsicWidth
override fun getIntrinsicHeight(): Int = drawable?.intrinsicHeight ?: super.intrinsicHeight
}
================================================
FILE: app/src/main/java/com/hippo/easyrecyclerview/EasyRecyclerView.kt
================================================
/*
* Copyright (C) 2015 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.easyrecyclerview
import android.content.Context
import android.os.Parcel
import android.os.Parcelable
import android.util.AttributeSet
import android.util.SparseBooleanArray
import android.view.ActionMode
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.Checkable
import androidx.collection.LongSparseArray
import androidx.core.util.isEmpty
import androidx.core.util.size
import androidx.recyclerview.widget.RecyclerView
import com.hippo.util.readParcelableCompat
import com.hippo.yorozuya.NumberUtils
/**
* Add setChoiceMode for RecyclerView
*/
// Get some code from twoway-view and AbsListView.
open class EasyRecyclerView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0,
) : RecyclerView(
context,
attrs,
defStyle,
) {
/**
* Wrapper for the multiple choice mode callback; AbsListView needs to perform
* a few extra actions around what application code does.
*/
private var mMultiChoiceModeCallback: MultiChoiceModeWrapper? = null
/**
* Controls if/how the user may choose/check items in the list
*/
private var mChoiceMode = CHOICE_MODE_NONE
/**
* Controls CHOICE_MODE_MULTIPLE_MODAL. null when inactive.
*/
private var mChoiceActionMode: ActionMode? = null
/**
* Listener for custom multiple choices
*/
private var mCustomChoiceListener: CustomChoiceListener? = null
var isInCustomChoice = false
private set
/**
* A lock, avoid OutOfCustomChoiceMode when doing OutOfCustomChoiceMode
*/
private var mOutOfCustomChoiceModing = false
private var mTempCheckStates: SparseBooleanArray? = null
/**
* Running count of how many items are currently checked
*/
var checkedItemCount = 0
private set
/**
* Running state of which positions are currently checked
*/
private var mCheckStates: SparseBooleanArray? = null
/**
* Running state of which IDs are currently checked.
* If there is a value for a given key, the checked state for that ID is true
* and the value holds the last known position in the adapter for that id.
*/
private var mCheckedIdStates: LongSparseArray<Int>? = null
private var mAdapter: Adapter<*>? = null
/**
* {@inheritDoc}
*/
override fun setAdapter(adapter: Adapter<*>?) {
super.setAdapter(adapter)
mAdapter = adapter
if (adapter != null &&
adapter.hasStableIds() &&
mChoiceMode != CHOICE_MODE_NONE &&
mCheckedIdStates == null
) {
mCheckedIdStates = LongSparseArray()
}
mCheckStates?.clear()
mCheckedIdStates?.clear()
}
override fun onChildAttachedToWindow(child: View) {
super.onChildAttachedToWindow(child)
if (mCheckStates != null) {
val position = getChildAdapterPosition(child)
if (position >= 0) {
setViewChecked(child, mCheckStates!![position])
}
}
}
/**
* Returns the checked state of the specified position. The result is only
* valid if the choice mode has been set to [.CHOICE_MODE_SINGLE]
* or [.CHOICE_MODE_MULTIPLE].
*
* @param position The item whose checked state to return
* @return The item's checked state or `false` if choice mode
* is invalid
* @see .setChoiceMode
*/
private fun isItemChecked(position: Int): Boolean = if (mChoiceMode != CHOICE_MODE_NONE && mCheckStates != null) {
mCheckStates!![position]
} else {
false
}
/**
* Returns the set of checked items in the list. The result is only valid if
* the choice mode has not been set to [.CHOICE_MODE_NONE].
*
* @return A SparseBooleanArray which will return true for each call to
* get(int position) where position is a checked position in the
* list and false otherwise, or `null` if the choice
* mode is set to [.CHOICE_MODE_NONE].
*/
val checkedItemPositions: SparseBooleanArray?
get() = if (mChoiceMode != CHOICE_MODE_NONE) {
mCheckStates
} else {
null
}
fun intoCustomChoiceMode() {
if (mChoiceMode == CHOICE_MODE_MULTIPLE_CUSTOM && !isInCustomChoice) {
isInCustomChoice = true
mCustomChoiceListener!!.onIntoCustomChoice(this)
}
}
fun outOfCustomChoiceMode() {
if (mChoiceMode == CHOICE_MODE_MULTIPLE_CUSTOM && isInCustomChoice && !mOutOfCustomChoiceModing) {
mOutOfCustomChoiceModing = true
// Copy mCheckStates
mTempCheckStates!!.clear()
run {
for (i in 0 until mCheckStates!!.size) {
mTempCheckStates!!.put(mCheckStates!!.keyAt(i), mCheckStates!!.valueAt(i))
}
}
// Uncheck remain checked items
for (i in 0 until mTempCheckStates!!.size) {
if (mTempCheckStates!!.valueAt(i)) {
setItemChecked(mTempCheckStates!!.keyAt(i), false)
}
}
isInCustomChoice = false
mCustomChoiceListener!!.onOutOfCustomChoice(this)
mOutOfCustomChoiceModing = false
}
}
/**
* Clear any choices previously set
*/
private fun clearChoices() {
mCheckStates?.clear()
mCheckedIdStates?.clear()
checkedItemCount = 0
updateOnScreenCheckedViews()
}
/**
* Sets all items checked.
*/
fun checkAll() {
if (mChoiceMode == CHOICE_MODE_NONE || mChoiceMode == CHOICE_MODE_SINGLE) {
return
}
// Check is intoCheckMode
check(!(mChoiceMode == CHOICE_MODE_MULTIPLE_CUSTOM && !isInCustomChoice)) { "Call intoCheckMode first" }
// Start selection mode if needed. We don't need to if we're unchecking something.
if (mChoiceMode == CHOICE_MODE_MULTIPLE_MODAL && mChoiceActionMode == null) {
check(
!(
mMultiChoiceModeCallback == null ||
!mMultiChoiceModeCallback!!.hasWrappedCallback()
),
) {
"EasyRecyclerView: attempted to start selection mode " +
"for CHOICE_MODE_MULTIPLE_MODAL but no choice mode callback was " +
"supplied. Call setMultiChoiceModeListener to set a callback."
}
mChoiceActionMode = startActionMode(mMultiChoiceModeCallback)
}
for (i in 0 until mAdapter!!.itemCount) {
val oldValue = mCheckStates!![i]
mCheckStates!!.put(i, true)
if (mCheckedIdStates != null && mAdapter!!.hasStableIds()) {
mCheckedIdStates!!.put(mAdapter!!.getItemId(i), i)
}
if (!oldValue) {
checkedItemCount++
}
if (mChoiceActionMode != null) {
val id = mAdapter!!.getItemId(i)
mMultiChoiceModeCallback!!.onItemCheckedStateChanged(
mChoiceActionMode!!,
i,
id,
true,
)
}
if (mChoiceMode == CHOICE_MODE_MULTIPLE_CUSTOM) {
val id = mAdapter!!.getItemId(i)
mCustomChoiceListener!!.onItemCheckedStateChanged(this, i, id, true)
}
}
updateOnScreenCheckedViews()
}
fun toggleItemChecked(position: Int) {
if (mCheckStates != null) {
setItemChecked(position, !mCheckStates!![position])
}
}
/**
* Sets the checked state of the specified position. The is only valid if
* the choice mode has been set to [.CHOICE_MODE_SINGLE] or
* [.CHOICE_MODE_MULTIPLE].
*
* @param position The item whose checked state is to be checked
* @param value The new checked state for the item
*/
private fun setItemChecked(position: Int, value: Boolean) {
if (mChoiceMode == CHOICE_MODE_NONE) {
return
}
// Check is intoCheckMode
check(!(mChoiceMode == CHOICE_MODE_MULTIPLE_CUSTOM && !isInCustomChoice)) { "Call intoCheckMode first" }
// Start selection mode if needed. We don't need to if we're unchecking something.
if (value && mChoiceMode == CHOICE_MODE_MULTIPLE_MODAL && mChoiceActionMode == null) {
check(
!(
mMultiChoiceModeCallback == null ||
!mMultiChoiceModeCallback!!.hasWrappedCallback()
),
) {
"EasyRecyclerView: attempted to start selection mode " +
"for CHOICE_MODE_MULTIPLE_MODAL but no choice mode callback was " +
"supplied. Call setMultiChoiceModeListener to set a callback."
}
mChoiceActionMode = startActionMode(mMultiChoiceModeCallback)
}
if (mChoiceMode == CHOICE_MODE_MULTIPLE || mChoiceMode == CHOICE_MODE_MULTIPLE_MODAL || mChoiceMode == CHOICE_MODE_MULTIPLE_CUSTOM) {
val oldValue = mCheckStates!![position]
mCheckStates!!.put(position, value)
if (mCheckedIdStates != null && mAdapter!!.hasStableIds()) {
if (value) {
mCheckedIdStates!!.put(mAdapter!!.getItemId(position), position)
} else {
mCheckedIdStates!!.remove(mAdapter!!.getItemId(position))
}
}
if (oldValue != value) {
if (value) {
checkedItemCount++
} else {
checkedItemCount--
}
}
if (mChoiceActionMode != null) {
val id = mAdapter!!.getItemId(position)
mMultiChoiceModeCallback!!.onItemCheckedStateChanged(
mChoiceActionMode!!,
position,
id,
value,
)
}
if (mChoiceMode == CHOICE_MODE_MULTIPLE_CUSTOM) {
val id = mAdapter!!.getItemId(position)
mCustomChoiceListener!!.onItemCheckedStateChanged(this, position, id, value)
}
} else {
val updateIds = mCheckedIdStates != null && mAdapter!!.hasStableIds()
// Clear all values if we're checking something, or unchecking the currently
// selected item
if (value || isItemChecked(position)) {
mCheckStates!!.clear()
if (updateIds) {
mCheckedIdStates!!.clear()
}
}
// this may end up selecting the value we just cleared but this way
// we ensure length of mCheckStates is 1, a fact getCheckedItemPosition relies on
if (value) {
mCheckStates!!.put(position, true)
if (updateIds) {
mCheckedIdStates!!.put(mAdapter!!.getItemId(position), position)
}
checkedItemCount = 1
} else if (mCheckStates!!.isEmpty() || !mCheckStates!!.valueAt(0)) {
checkedItemCount = 0
}
}
updateOnScreenCheckedViews()
}
/**
* Defines the choice behavior for the List. By default, Lists do not have any choice behavior
* ([.CHOICE_MODE_NONE]). By setting the choiceMode to [.CHOICE_MODE_SINGLE], the
* List allows up to one item to be in a chosen state. By setting the choiceMode to
* [.CHOICE_MODE_MULTIPLE], the list allows any number of items to be chosen.
*
* @param choiceMode One of [.CHOICE_MODE_NONE], [.CHOICE_MODE_SINGLE], or
* [.CHOICE_MODE_MULTIPLE]
*/
fun setChoiceMode(choiceMode: Int) {
mChoiceMode = choiceMode
if (mChoiceActionMode != null) {
mChoiceActionMode!!.finish()
mChoiceActionMode = null
}
if (mChoiceMode != CHOICE_MODE_NONE) {
if (mCheckStates == null) {
mCheckStates = SparseBooleanArray(0)
}
if (mCheckedIdStates == null && mAdapter != null && mAdapter!!.hasStableIds()) {
mCheckedIdStates = LongSparseArray(0)
}
// Modal multi-choice mode only has choices when the mode is active. Clear them.
if (mChoiceMode == CHOICE_MODE_MULTIPLE_MODAL) {
clearChoices()
isLongClickable = true
} else if (mChoiceMode == CHOICE_MODE_MULTIPLE_CUSTOM) {
if (mTempCheckStates == null) {
mTempCheckStates = SparseBooleanArray(0)
}
clearChoices()
}
}
}
fun setCustomCheckedListener(listener: CustomChoiceListener?) {
mCustomChoiceListener = listener
}
/**
* Perform a quick, in-place update of the checked or activated state
* on all visible item views. This should only be called when a valid
* choice mode is active.
*/
private fun updateOnScreenCheckedViews() {
for (i in 0 until childCount) {
val child = getChildAt(i)
val position = getChildAdapterPosition(child)
setViewChecked(child, mCheckStates!![position])
}
}
public override fun onSaveInstanceState(): Parcelable {
val ss = SavedState(super.onSaveInstanceState())
ss.choiceMode = mChoiceMode
ss.customChoice = isInCustomChoice
ss.checkedItemCount = checkedItemCount
ss.checkState = mCheckStates
ss.checkIdState = mCheckedIdStates
return ss
}
public override fun onRestoreInstanceState(state: Parcelable) {
val ss = state as SavedState
super.onRestoreInstanceState(ss.superState)
setChoiceMode(ss.choiceMode)
isInCustomChoice = ss.customChoice
checkedItemCount = ss.checkedItemCount
if (ss.checkState != null) {
mCheckStates = ss.checkState
}
if (ss.checkIdState != null) {
mCheckedIdStates = ss.checkIdState
}
if (mChoiceMode == CHOICE_MODE_MULTIPLE_MODAL && checkedItemCount > 0) {
mChoiceActionMode = startActionMode(mMultiChoiceModeCallback)
}
updateOnScreenCheckedViews()
}
/**
* A MultiChoiceModeListener receives events for [android.widget.AbsListView.CHOICE_MODE_MULTIPLE_MODAL].
* It acts as the [android.view.ActionMode.Callback] for the selection mode and also receives
* [.onItemCheckedStateChanged] events when the user
* selects and deselects list items.
*/
interface MultiChoiceModeListener : ActionMode.Callback {
/**
* Called when an item is checked or unchecked during selection mode.
*
* @param mode The [android.view.ActionMode] providing the selection mode
* @param position Adapter position of the item that was checked or unchecked
* @param id Adapter ID of the item that was checked or unchecked
* @param checked `true` if the item is now checked, `false`
* if the item is now unchecked.
*/
fun onItemCheckedStateChanged(
mode: ActionMode,
position: Int,
id: Long,
checked: Boolean,
)
}
/**
* Custom checked
*/
interface CustomChoiceListener {
fun onIntoCustomChoice(view: EasyRecyclerView)
fun onOutOfCustomChoice(view: EasyRecyclerView)
fun onItemCheckedStateChanged(
view: EasyRecyclerView,
position: Int,
id: Long,
checked: Boolean,
)
}
/**
* This saved state class is a Parcelable and should not extend
* [android.view.View.BaseSavedState] nor [android.view.AbsSavedState]
* because its super class AbsSavedState's constructor
* currently passes null
* as a class loader to read its superstate from Parcelable.
* This causes [android.os.BadParcelableException] when restoring saved states.
*
*
* The super class "RecyclerView" is a part of the support library,
* and restoring its saved state requires the class loader that loaded the RecyclerView.
* It seems that the class loader is not required when restoring from RecyclerView itself,
* but it is required when restoring from RecyclerView's subclasses.
*/
internal open class SavedState : Parcelable {
var choiceMode = 0
var customChoice = false
var checkedItemCount = 0
var checkState: SparseBooleanArray? = null
var checkIdState: LongSparseArray<Int>? = null
// This keeps the parent(RecyclerView)'s state
var superState: Parcelable?
constructor() {
superState = null
}
/**
* Constructor called from [.onSaveInstanceState]
*/
constructor(superState: Parcelable?) {
this.superState = if (superState !== EMPTY_STATE) superState else null
}
/**
* Constructor called from [.CREATOR]
*/
private constructor(`in`: Parcel) {
// Parcel 'in' has its parent(RecyclerView)'s saved state.
// To restore it, class loader that loaded RecyclerView is required.
val superState =
`in`.readParcelableCompat<Parcelable>(RecyclerView::class.java.getClassLoader())
this.superState = superState ?: EMPTY_STATE
choiceMode = `in`.readInt()
customChoice = NumberUtils.int2boolean(`in`.readInt())
checkedItemCount = `in`.readInt()
checkState = `in`.readSparseBooleanArray()
val n = `in`.readInt()
if (n > 0) {
checkIdState = LongSparseArray()
(0 until n).forEach { i ->
val key = `in`.readLong()
val value = `in`.readInt()
checkIdState!!.put(key, value)
}
}
}
override fun describeContents(): Int = 0
override fun writeToParcel(out: Parcel, flags: Int) {
out.writeParcelable(superState, flags)
out.writeInt(choiceMode)
out.writeInt(NumberUtils.boolean2int(customChoice))
out.writeInt(checkedItemCount)
out.writeSparseBooleanArray(checkState)
val n = if (checkIdState != null) checkIdState!!.size() else 0
out.writeInt(n)
for (i in 0 until n) {
out.writeLong(checkIdState!!.keyAt(i))
out.writeInt(checkIdState!!.valueAt(i))
}
}
companion object CREATOR : Parcelable.Creator<SavedState> {
override fun createFromParcel(`in`: Parcel): SavedState = SavedState(`in`)
override fun newArray(size: Int): Array<SavedState?> = arrayOfNulls(size)
}
}
inner class MultiChoiceModeWrapper : MultiChoiceModeListener {
private val mWrapped: MultiChoiceModeListener? = null
fun hasWrappedCallback(): Boolean = mWrapped != null
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
if (mWrapped!!.onCreateActionMode(mode, menu)) {
// Initialize checked graphic state?
isLongClickable = false
return true
}
return false
}
override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean = mWrapped!!.onPrepareActionMode(mode, menu)
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean = mWrapped!!.onActionItemClicked(mode, item)
override fun onDestroyActionMode(mode: ActionMode) {
mWrapped!!.onDestroyActionMode(mode)
mChoiceActionMode = null
// Ending selection mode means deselecting everything.
clearChoices()
requestLayout()
isLongClickable = true
}
override fun onItemCheckedStateChanged(
mode: ActionMode,
position: Int,
id: Long,
checked: Boolean,
) {
mWrapped!!.onItemCheckedStateChanged(mode, position, id, checked)
// If there are no items selected we no longer need the selection mode.
if (checkedItemCount == 0) {
mode.finish()
}
}
}
companion object {
/**
* Normal list that does not indicate choices
*/
const val CHOICE_MODE_NONE = 0
/**
* The list allows up to one choice
*/
const val CHOICE_MODE_SINGLE = 1
/**
* The list allows multiple choices
*/
const val CHOICE_MODE_MULTIPLE = 2
/**
* The list allows multiple choices in a modal selection mode
*/
const val CHOICE_MODE_MULTIPLE_MODAL = 3
/**
* The list allows multiple choices in custom action
*/
const val CHOICE_MODE_MULTIPLE_CUSTOM = 4
private val EMPTY_STATE: SavedState = object : SavedState() {}
private fun setViewChecked(view: View, checked: Boolean) {
if (view is Checkable) {
(view as Checkable).isChecked = checked
} else {
view.isActivated = checked
}
}
}
}
================================================
FILE: app/src/main/java/com/hippo/easyrecyclerview/FastScroller.kt
================================================
/*
* Copyright 2015 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.easyrecyclerview
import android.animation.Animator
import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Canvas
import android.graphics.drawable.Drawable
import android.os.Handler
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import androidx.core.content.withStyledAttributes
import androidx.core.graphics.withTranslation
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver
import com.hippo.ehviewer.R
import com.hippo.yorozuya.AnimationUtils
import com.hippo.yorozuya.LayoutUtils
import com.hippo.yorozuya.MathUtils
import com.hippo.yorozuya.SimpleAnimatorListener
import com.hippo.yorozuya.SimpleHandler
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min
class FastScroller @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
) : View(
context,
attrs,
defStyleAttr,
) {
private var mSimpleHandler: Handler? = null
private var mDraggable = false
private var mMinHandlerHeight = 0
private var mRecyclerView: RecyclerView? = null
private var mOnScrollChangeListener: RecyclerView.OnScrollListener? = null
private var mAdapter: RecyclerView.Adapter<*>? = null
private var mAdapterDataObserver: AdapterDataObserver? = null
private var mHandler: Drawable? = null
private var mHandlerOffset = INVALID
private var mHandlerHeight = INVALID
private var mDownX = INVALID.toFloat()
private var mDownY = INVALID.toFloat()
private var mLastMotionY = INVALID.toFloat()
private var mDragged = false
private var mCantDrag = false
private var mTouchSlop = 0
private var mListener: OnDragHandlerListener? = null
private var mShowAnimator: ObjectAnimator? = null
private var mHideAnimator: ObjectAnimator? = null
private val mHideRunnable = Runnable { mHideAnimator!!.start() }
init {
init(context, attrs, defStyleAttr)
}
private fun init(context: Context, attrs: AttributeSet?, defStyleAttr: Int) {
mSimpleHandler = SimpleHandler.getInstance()
context.withStyledAttributes(attrs, R.styleable.FastScroller, defStyleAttr, 0) {
mHandler = getDrawable(R.styleable.FastScroller_handler)
mDraggable = getBoolean(R.styleable.FastScroller_draggable, true)
}
setAlpha(0.0f)
visibility = INVISIBLE
mMinHandlerHeight = LayoutUtils.dp2pix(context, MIN_HANDLER_HEIGHT_DP.toFloat())
mTouchSlop = ViewConfiguration.get(context).scaledTouchSlop
mShowAnimator = ObjectAnimator.ofFloat(this, "alpha", 1.0f)
mShowAnimator!!.interpolator = AnimationUtils.FAST_SLOW_INTERPOLATOR
mShowAnimator!!.setDuration(SCROLL_BAR_FADE_DURATION.toLong())
mHideAnimator = ObjectAnimator.ofFloat(this, "alpha", 0.0f)
mHideAnimator!!.interpolator = AnimationUtils.SLOW_FAST_INTERPOLATOR
mHideAnimator!!.setDuration(SCROLL_BAR_FADE_DURATION.toLong())
mHideAnimator!!.addListener(object : SimpleAnimatorListener() {
private var mCancel = false
override fun onAnimationCancel(animation: Animator) {
mCancel = true
}
override fun onAnimationEnd(animation: Animator) {
if (mCancel) {
mCancel = false
} else {
visibility = INVISIBLE
}
}
})
}
fun setOnDragHandlerListener(listener: OnDragHandlerListener?) {
mListener = listener
}
private fun updatePosition(show: Boolean) {
if (mRecyclerView == null) {
return
}
val paddingTop = paddingTop
val paddingBottom = paddingBottom
val height = height - paddingTop - paddingBottom
val offset = mRecyclerView!!.computeVerticalScrollOffset()
val extent = mRecyclerView!!.computeVerticalScrollExtent()
val range = mRecyclerView!!.computeVerticalScrollRange()
if (height <= 0 || extent >= range || extent <= 0) {
return
}
var endOffset = height.toLong() * offset / range
var endHeight = height * extent / range
endHeight = max(endHeight.toDouble(), mMinHandlerHeight.toDouble()).toInt()
endOffset = min(endOffset.toDouble(), (height - endHeight).toDouble()).toLong()
mHandlerOffset = (endOffset + paddingTop).toInt()
mHandlerHeight = endHeight
if (show) {
if (mHideAnimator!!.isRunning) {
mHideAnimator!!.cancel()
mShowAnimator!!.start()
} else if (visibility != VISIBLE && !mShowAnimator!!.isRunning) {
visibility = VISIBLE
mShowAnimator!!.start()
}
val handler = mSimpleHandler
handler!!.removeCallbacks(mHideRunnable)
if (!mDragged) {
handler.postDelayed(mHideRunnable, SCROLL_BAR_DELAY.toLong())
}
}
}
fun setHandlerDrawable(drawable: Drawable?) {
mHandler = drawable
invalidate()
}
var isDraggable: Boolean
get() = mDraggable
set(draggable) {
mDraggable = draggable
if (mDragged) {
mDragged = false
}
mSimpleHandler!!.removeCallbacks(mHideRunnable)
mHideRunnable.run()
}
val isAttached: Boolean
get() = mRecyclerView != null
fun attachToRecyclerView(recyclerView: RecyclerView?) {
if (recyclerView == null) {
return
}
check(mRecyclerView == null) {
"The FastScroller is already attached to a RecyclerView, " +
"call detachedFromRecyclerView first"
}
mRecyclerView = recyclerView
mOnScrollChangeListener = object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
updatePosition(true)
invalidate()
}
}
recyclerView.addOnScrollListener(mOnScrollChangeListener!!)
mAdapter = recyclerView.adapter
if (mAdapter != null) {
mAdapterDataObserver = object : AdapterDataObserver() {
override fun onItemRangeChanged(positionStart: Int, itemCount: Int) {
super.onItemRangeChanged(positionStart, itemCount)
updatePosition(false)
invalidate()
}
override fun onItemRangeChanged(positionStart: Int, itemCount: Int, payload: Any?) {
super.onItemRangeChanged(positionStart, itemCount, payload)
updatePosition(false)
invalidate()
}
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
super.onItemRangeInserted(positionStart, itemCount)
updatePosition(false)
invalidate()
}
override fun onItemRangeRemoved(positionStart: Int, itemCount: Int) {
super.onItemRangeRemoved(positionStart, itemCount)
updatePosition(false)
invalidate()
}
override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) {
super.onItemRangeMoved(fromPosition, toPosition, itemCount)
updatePosition(false)
invalidate()
}
}
mAdapter!!.registerAdapterDataObserver(mAdapterDataObserver!!)
}
}
fun detachedFromRecyclerView() {
if (mRecyclerView != null && mOnScrollChangeListener != null) {
mRecyclerView!!.removeOnScrollListener(mOnScrollChangeListener!!)
}
mRecyclerView = null
mOnScrollChangeListener = null
if (mAdapter != null && mAdapterDataObserver != null) {
mAdapter!!.unregisterAdapterDataObserver(mAdapterDataObserver!!)
}
mAdapter = null
mAdapterDataObserver = null
setAlpha(0.0f)
visibility = INVISIBLE
}
override fun onDraw(canvas: Canvas) {
if (mRecyclerView == null || mHandler == null) {
return
}
if (mHandlerHeight == INVALID) {
updatePosition(false)
}
if (mHandlerHeight == INVALID) {
return
}
val paddingLeft = getPaddingLeft()
canvas.withTranslation(paddingLeft.toFloat(), mHandlerOffset.toFloat()) {
mHandler!!.setBounds(0, 0, width - paddingLeft - getPaddingRight(), mHandlerHeight)
mHandler!!.draw(canvas)
}
}
@SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(event: MotionEvent): Boolean {
if (!mDraggable || visibility != VISIBLE || mRecyclerView == null || mHandlerHeight == INVALID) {
return false
}
val action = event.action
if (action == MotionEvent.ACTION_DOWN) {
mCantDrag = false
}
if (mCantDrag) {
return false
}
when (action) {
MotionEvent.A
gitextract_k4e444b1/ ├── .editorconfig ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug-report.yml │ │ └── config.yml │ └── workflows/ │ ├── ci.yml │ └── releases.yml ├── .gitignore ├── LICENSE ├── NOTICE ├── README.md ├── app/ │ ├── .gitignore │ ├── build.gradle.kts │ ├── keystore/ │ │ └── androidkey.jks │ ├── proguard-rules.pro │ ├── schemas/ │ │ └── com.hippo.network.CookiesDatabase/ │ │ ├── 1.json │ │ └── 2.json │ └── src/ │ ├── debug/ │ │ └── res/ │ │ └── values/ │ │ └── strings.xml │ └── main/ │ ├── AndroidManifest.xml │ ├── cpp/ │ │ ├── 0001-Insert-link-libs.patch │ │ ├── 0002-Fix-zip_time-performance.patch │ │ ├── 0003-Use-UTF-8-as-default-charset-on-bionic.patch │ │ ├── CMakeLists.txt │ │ ├── archive.c │ │ ├── ehviewer.h │ │ ├── gifutils.c │ │ ├── hash.c │ │ ├── image.c │ │ ├── natsort/ │ │ │ ├── strnatcmp.c │ │ │ └── strnatcmp.h │ │ └── nettle/ │ │ ├── .gitignore │ │ ├── CMakeLists.txt │ │ ├── config.h │ │ ├── keymap.h │ │ ├── rotors.h │ │ └── version.h │ ├── java/ │ │ ├── com/ │ │ │ └── hippo/ │ │ │ ├── app/ │ │ │ │ ├── CheckBoxDialogBuilder.kt │ │ │ │ ├── EditTextCheckBoxDialogBuilder.kt │ │ │ │ ├── EditTextDialogBuilder.kt │ │ │ │ └── ListCheckBoxDialogBuilder.kt │ │ │ ├── database/ │ │ │ │ ├── MSQLiteBuilder.kt │ │ │ │ └── MSQLiteOpenHelper.kt │ │ │ ├── drawable/ │ │ │ │ ├── AddDeleteDrawable.kt │ │ │ │ ├── BatteryDrawable.kt │ │ │ │ ├── DrawerArrowDrawable.kt │ │ │ │ ├── PreciselyClipDrawable.kt │ │ │ │ ├── TriangleDrawable.kt │ │ │ │ ├── UnikeryDrawable.kt │ │ │ │ └── WrapDrawable.kt │ │ │ ├── easyrecyclerview/ │ │ │ │ ├── EasyRecyclerView.kt │ │ │ │ ├── FastScroller.kt │ │ │ │ ├── HandlerDrawable.kt │ │ │ │ ├── LayoutManagerUtils.kt │ │ │ │ ├── LinearDividerItemDecoration.kt │ │ │ │ ├── MarginItemDecoration.kt │ │ │ │ ├── SimpleHolder.kt │ │ │ │ └── SimpleSmoothScroller.kt │ │ │ ├── ehviewer/ │ │ │ │ ├── AppConfig.java │ │ │ │ ├── Crash.kt │ │ │ │ ├── EhApplication.kt │ │ │ │ ├── EhDB.kt │ │ │ │ ├── EhProxySelector.kt │ │ │ │ ├── FavouriteStatusRouter.java │ │ │ │ ├── GetText.kt │ │ │ │ ├── Settings.kt │ │ │ │ ├── UrlOpener.kt │ │ │ │ ├── WindowInsetsAnimationHelper.java │ │ │ │ ├── client/ │ │ │ │ │ ├── EhCacheKeyFactory.kt │ │ │ │ │ ├── EhClient.kt │ │ │ │ │ ├── EhCookieStore.kt │ │ │ │ │ ├── EhEngine.kt │ │ │ │ │ ├── EhFilter.kt │ │ │ │ │ ├── EhRequest.kt │ │ │ │ │ ├── EhRequestBuilder.kt │ │ │ │ │ ├── EhTagDatabase.kt │ │ │ │ │ ├── EhUrl.kt │ │ │ │ │ ├── EhUrlOpener.kt │ │ │ │ │ ├── EhUtils.kt │ │ │ │ │ ├── data/ │ │ │ │ │ │ ├── AbstractGalleryInfo.kt │ │ │ │ │ │ ├── BaseGalleryInfo.kt │ │ │ │ │ │ ├── FavListUrlBuilder.kt │ │ │ │ │ │ ├── GalleryComment.kt │ │ │ │ │ │ ├── GalleryCommentList.kt │ │ │ │ │ │ ├── GalleryDetail.kt │ │ │ │ │ │ ├── GalleryInfo.kt │ │ │ │ │ │ ├── GalleryPreview.kt │ │ │ │ │ │ ├── GalleryTagGroup.kt │ │ │ │ │ │ ├── LargePreviewSet.kt │ │ │ │ │ │ ├── ListUrlBuilder.kt │ │ │ │ │ │ ├── NormalPreviewSet.kt │ │ │ │ │ │ └── PreviewSet.kt │ │ │ │ │ ├── exception/ │ │ │ │ │ │ ├── CloudflareBypassException.kt │ │ │ │ │ │ ├── EhException.kt │ │ │ │ │ │ ├── InsufficientFundsException.kt │ │ │ │ │ │ ├── NoHAtHClientException.kt │ │ │ │ │ │ ├── NotLoggedInException.kt │ │ │ │ │ │ ├── OffensiveException.kt │ │ │ │ │ │ ├── ParseException.kt │ │ │ │ │ │ ├── PiningException.kt │ │ │ │ │ │ └── QuotaExceededException.kt │ │ │ │ │ └── parser/ │ │ │ │ │ ├── ArchiveParser.kt │ │ │ │ │ ├── EventPaneParser.kt │ │ │ │ │ ├── FavoritesParser.kt │ │ │ │ │ ├── ForumsParser.kt │ │ │ │ │ ├── GalleryApiParser.kt │ │ │ │ │ ├── GalleryDetailParser.kt │ │ │ │ │ ├── GalleryDetailUrlParser.kt │ │ │ │ │ ├── GalleryListParser.kt │ │ │ │ │ ├── GalleryListUrlParser.kt │ │ │ │ │ ├── GalleryMultiPageViewerParser.kt │ │ │ │ │ ├── GalleryNotAvailableParser.kt │ │ │ │ │ ├── GalleryPageApiParser.kt │ │ │ │ │ ├── GalleryPageParser.kt │ │ │ │ │ ├── GalleryPageUrlParser.kt │ │ │ │ │ ├── GalleryTokenApiParser.kt │ │ │ │ │ ├── HomeParser.kt │ │ │ │ │ ├── ParserUtils.kt │ │ │ │ │ ├── ProfileParser.kt │ │ │ │ │ ├── RateGalleryParser.kt │ │ │ │ │ ├── SignInParser.kt │ │ │ │ │ ├── TorrentParser.kt │ │ │ │ │ ├── UserConfigParser.kt │ │ │ │ │ ├── VoteCommentParser.kt │ │ │ │ │ └── VoteTagParser.kt │ │ │ │ ├── coil/ │ │ │ │ │ ├── DiskCache.kt │ │ │ │ │ ├── DownloadThumbInterceptor.kt │ │ │ │ │ ├── LockPool.kt │ │ │ │ │ ├── MergeInterceptor.kt │ │ │ │ │ └── NamedMutex.kt │ │ │ │ ├── dao/ │ │ │ │ │ ├── BasicDao.kt │ │ │ │ │ ├── BookmarkInfo.kt │ │ │ │ │ ├── BookmarksDao.kt │ │ │ │ │ ├── DownloadDirname.kt │ │ │ │ │ ├── DownloadDirnameDao.kt │ │ │ │ │ ├── DownloadInfo.kt │ │ │ │ │ ├── DownloadLabel.kt │ │ │ │ │ ├── DownloadLabelDao.kt │ │ │ │ │ ├── DownloadsDao.kt │ │ │ │ │ ├── EhDatabase.kt │ │ │ │ │ ├── Filter.kt │ │ │ │ │ ├── FilterDao.kt │ │ │ │ │ ├── HistoryDao.kt │ │ │ │ │ ├── HistoryInfo.kt │ │ │ │ │ ├── LocalFavoriteInfo.kt │ │ │ │ │ ├── LocalFavoritesDao.kt │ │ │ │ │ ├── QuickSearch.kt │ │ │ │ │ └── QuickSearchDao.kt │ │ │ │ ├── download/ │ │ │ │ │ ├── DownloadManager.kt │ │ │ │ │ └── DownloadService.kt │ │ │ │ ├── gallery/ │ │ │ │ │ ├── ArchiveGalleryProvider.kt │ │ │ │ │ ├── EhGalleryProvider.kt │ │ │ │ │ └── GalleryProvider2.kt │ │ │ │ ├── jni/ │ │ │ │ │ ├── Archive.kt │ │ │ │ │ ├── GifUtils.kt │ │ │ │ │ ├── Hash.kt │ │ │ │ │ └── Image.kt │ │ │ │ ├── preference/ │ │ │ │ │ ├── AccountPreference.kt │ │ │ │ │ ├── CleanRedundancyPreference.kt │ │ │ │ │ ├── ClearSearchHistoryPreference.kt │ │ │ │ │ ├── ImageLimitsPreference.kt │ │ │ │ │ ├── ProxyPreference.kt │ │ │ │ │ ├── RestoreDownloadPreference.kt │ │ │ │ │ ├── TaskPreference.kt │ │ │ │ │ ├── UserAgentPreference.kt │ │ │ │ │ └── VersionPreference.kt │ │ │ │ ├── shortcuts/ │ │ │ │ │ └── ShortcutsActivity.kt │ │ │ │ ├── spider/ │ │ │ │ │ ├── DownloadInfoMagics.kt │ │ │ │ │ ├── SpiderDen.kt │ │ │ │ │ ├── SpiderInfo.kt │ │ │ │ │ └── SpiderQueen.kt │ │ │ │ ├── ui/ │ │ │ │ │ ├── CommonOperations.kt │ │ │ │ │ ├── EhActivity.kt │ │ │ │ │ ├── GalleryActivity.kt │ │ │ │ │ ├── MainActivity.kt │ │ │ │ │ ├── SettingsActivity.kt │ │ │ │ │ ├── WebViewActivity.kt │ │ │ │ │ ├── dialog/ │ │ │ │ │ │ └── SelectItemWithIconAdapter.kt │ │ │ │ │ ├── fragment/ │ │ │ │ │ │ ├── AboutFragment.kt │ │ │ │ │ │ ├── AdvancedFragment.kt │ │ │ │ │ │ ├── BaseFragment.kt │ │ │ │ │ │ ├── BasePreferenceFragment.kt │ │ │ │ │ │ ├── DownloadFragment.kt │ │ │ │ │ │ ├── EhFragment.kt │ │ │ │ │ │ ├── FilterFragment.kt │ │ │ │ │ │ ├── MyTagsFragment.kt │ │ │ │ │ │ ├── PrivacyFragment.kt │ │ │ │ │ │ ├── ReadFragment.kt │ │ │ │ │ │ ├── SetSecurityFragment.kt │ │ │ │ │ │ ├── SettingsFragment.kt │ │ │ │ │ │ └── UConfigFragment.kt │ │ │ │ │ └── scene/ │ │ │ │ │ ├── BaseScene.kt │ │ │ │ │ ├── CookieSignInScene.kt │ │ │ │ │ ├── DownloadsScene.kt │ │ │ │ │ ├── EhCallback.kt │ │ │ │ │ ├── EnterGalleryDetailTransaction.kt │ │ │ │ │ ├── FavoritesScene.kt │ │ │ │ │ ├── GalleryAdapter.kt │ │ │ │ │ ├── GalleryCommentsScene.kt │ │ │ │ │ ├── GalleryDetailScene.kt │ │ │ │ │ ├── GalleryHolder.kt │ │ │ │ │ ├── GalleryInfoScene.kt │ │ │ │ │ ├── GalleryListScene.kt │ │ │ │ │ ├── GalleryPreviewsScene.kt │ │ │ │ │ ├── HistoryScene.kt │ │ │ │ │ ├── ProgressScene.kt │ │ │ │ │ ├── SecurityScene.kt │ │ │ │ │ ├── SelectSiteScene.kt │ │ │ │ │ ├── SignInScene.kt │ │ │ │ │ ├── SolidScene.kt │ │ │ │ │ ├── ToolbarScene.kt │ │ │ │ │ ├── TransitionNameFactory.kt │ │ │ │ │ └── WebViewSignInScene.kt │ │ │ │ ├── util/ │ │ │ │ │ └── WebViewExtensions.kt │ │ │ │ └── widget/ │ │ │ │ ├── AdvanceSearchTable.kt │ │ │ │ ├── CategoryTable.kt │ │ │ │ ├── DialogWebChromeClient.java │ │ │ │ ├── EhStageLayout.kt │ │ │ │ ├── FixedThumb.kt │ │ │ │ ├── GalleryGuideView.java │ │ │ │ ├── GalleryHeader.java │ │ │ │ ├── GalleryInfoContentHelper.kt │ │ │ │ ├── GalleryRatingBar.java │ │ │ │ ├── ImageSearchLayout.kt │ │ │ │ ├── ResizeableFixedThumb.kt │ │ │ │ ├── ReversibleSeekBar.java │ │ │ │ ├── SearchBar.kt │ │ │ │ ├── SearchDatabase.java │ │ │ │ ├── SearchEditText.java │ │ │ │ ├── SearchLayout.kt │ │ │ │ ├── SeekBarPanel.kt │ │ │ │ ├── SimpleRatingView.java │ │ │ │ └── TileThumb.java │ │ │ ├── glgallery/ │ │ │ │ ├── DownUpDetector.java │ │ │ │ ├── Fling.java │ │ │ │ ├── GalleryPageView.java │ │ │ │ ├── GalleryProvider.kt │ │ │ │ ├── GalleryView.java │ │ │ │ ├── GestureRecognizer.java │ │ │ │ ├── ImageView.java │ │ │ │ ├── PagerLayoutManager.java │ │ │ │ ├── ScrollLayoutManager.java │ │ │ │ └── SimpleAdapter.java │ │ │ ├── glview/ │ │ │ │ ├── anim/ │ │ │ │ │ ├── AlphaAnimation.java │ │ │ │ │ ├── Animation.java │ │ │ │ │ ├── CanvasAnimation.java │ │ │ │ │ └── FloatAnimation.java │ │ │ │ ├── glrenderer/ │ │ │ │ │ ├── BasicTexture.java │ │ │ │ │ ├── CanvasTexture.java │ │ │ │ │ ├── GLCanvas.java │ │ │ │ │ ├── GLES11Canvas.java │ │ │ │ │ ├── GLES11IdImpl.java │ │ │ │ │ ├── GLES20Canvas.java │ │ │ │ │ ├── GLES20IdImpl.java │ │ │ │ │ ├── GLId.java │ │ │ │ │ ├── GLPaint.java │ │ │ │ │ ├── MovableTextTexture.java │ │ │ │ │ ├── NativeTexture.java │ │ │ │ │ ├── RawTexture.java │ │ │ │ │ ├── SpriteTexture.java │ │ │ │ │ ├── StringTexture.java │ │ │ │ │ ├── Texture.java │ │ │ │ │ ├── TiledTexture.java │ │ │ │ │ └── UploadedTexture.java │ │ │ │ ├── image/ │ │ │ │ │ ├── GLImageMovableTextView.java │ │ │ │ │ ├── ImageMovableTextTexture.java │ │ │ │ │ ├── ImageSpriteTexture.java │ │ │ │ │ ├── ImageTexture.java │ │ │ │ │ └── ImageWrapper.java │ │ │ │ ├── util/ │ │ │ │ │ └── GalleryUtils.java │ │ │ │ ├── view/ │ │ │ │ │ ├── AnimationTime.java │ │ │ │ │ ├── GLRoot.java │ │ │ │ │ ├── GLRootView.java │ │ │ │ │ ├── GLView.java │ │ │ │ │ ├── Gravity.java │ │ │ │ │ ├── OrientationSource.java │ │ │ │ │ ├── TouchHelper.java │ │ │ │ │ └── TouchOwner.java │ │ │ │ └── widget/ │ │ │ │ ├── GLFrameLayout.java │ │ │ │ ├── GLLinearLayout.java │ │ │ │ ├── GLProgressView.java │ │ │ │ └── GLTextureView.java │ │ │ ├── image/ │ │ │ │ └── Image.kt │ │ │ ├── network/ │ │ │ │ ├── CookieDatabase.kt │ │ │ │ ├── CookieSet.kt │ │ │ │ ├── InetValidator.kt │ │ │ │ ├── StatusCodeException.kt │ │ │ │ └── UrlBuilder.kt │ │ │ ├── okhttp/ │ │ │ │ └── ChromeRequestBuilder.kt │ │ │ ├── preference/ │ │ │ │ ├── DialogPreference.kt │ │ │ │ └── UrlPreference.kt │ │ │ ├── scene/ │ │ │ │ ├── Announcer.kt │ │ │ │ ├── SceneApplication.kt │ │ │ │ ├── SceneFragment.kt │ │ │ │ ├── StageActivity.kt │ │ │ │ ├── StageLayout.kt │ │ │ │ └── TransitionHelper.kt │ │ │ ├── text/ │ │ │ │ └── URLImageGetter.kt │ │ │ ├── unifile/ │ │ │ │ ├── Contracts.kt │ │ │ │ ├── DocumentsContractApi19.kt │ │ │ │ ├── DocumentsContractApi21.kt │ │ │ │ ├── FilenameFilter.kt │ │ │ │ ├── MediaContract.kt │ │ │ │ ├── MediaFile.kt │ │ │ │ ├── RawFile.kt │ │ │ │ ├── SingleDocumentFile.kt │ │ │ │ ├── TreeDocumentFile.kt │ │ │ │ ├── UniFile.kt │ │ │ │ ├── UniFileExtensions.kt │ │ │ │ ├── UriHandler.kt │ │ │ │ └── Utils.kt │ │ │ ├── util/ │ │ │ │ ├── AppHelper.kt │ │ │ │ ├── BBCode.kt │ │ │ │ ├── ClipboardUtil.kt │ │ │ │ ├── CoroutinesExtensions.kt │ │ │ │ ├── DateTimeUtil.kt │ │ │ │ ├── ExceptionUtils.kt │ │ │ │ ├── FDUtils.kt │ │ │ │ ├── HtmlCompat.kt │ │ │ │ ├── JsoupUtils.java │ │ │ │ ├── LogCat.java │ │ │ │ ├── ParcelableCompat.kt │ │ │ │ ├── ReadableTime.kt │ │ │ │ ├── SDKUtils.kt │ │ │ │ ├── SqlUtils.java │ │ │ │ ├── TextUrl.java │ │ │ │ └── URLEncoderCompat.kt │ │ │ ├── view/ │ │ │ │ ├── BringOutTransition.java │ │ │ │ └── ViewTransition.java │ │ │ ├── widget/ │ │ │ │ ├── AutoWrapLayout.java │ │ │ │ ├── BatteryView.kt │ │ │ │ ├── CheckTextView.kt │ │ │ │ ├── ColorView.java │ │ │ │ ├── ContentLayout.kt │ │ │ │ ├── CuteSpinner.java │ │ │ │ ├── DateUtils.java │ │ │ │ ├── DrawerView.java │ │ │ │ ├── FabLayout.kt │ │ │ │ ├── FixedAspectImageView.kt │ │ │ │ ├── IgnoreFitsSystemWindowsFullyDraggableDrawerContentLayout.kt │ │ │ │ ├── IndicatingListView.java │ │ │ │ ├── LinkifyTextView.java │ │ │ │ ├── LoadImageView.kt │ │ │ │ ├── MaxSizeContainer.java │ │ │ │ ├── ObservedTextView.java │ │ │ │ ├── RadioGridGroup.java │ │ │ │ ├── SearchBarMover.java │ │ │ │ ├── SimpleGridAutoSpanLayout.java │ │ │ │ ├── SimpleGridLayout.java │ │ │ │ ├── Slider.java │ │ │ │ ├── TextClock.java │ │ │ │ ├── lockpattern/ │ │ │ │ │ ├── LockPatternUtils.java │ │ │ │ │ └── LockPatternView.java │ │ │ │ └── recyclerview/ │ │ │ │ ├── AutoGridLayoutManager.java │ │ │ │ └── AutoStaggeredGridLayoutManager.java │ │ │ └── yorozuya/ │ │ │ ├── AnimationUtils.java │ │ │ ├── AssertError.java │ │ │ ├── AssertException.java │ │ │ ├── AssertUtils.java │ │ │ ├── ConcurrentPool.java │ │ │ ├── FileUtils.java │ │ │ ├── IOUtils.java │ │ │ ├── IOUtils.kt │ │ │ ├── IntIdGenerator.java │ │ │ ├── LayoutUtils.java │ │ │ ├── MathUtils.java │ │ │ ├── NumberUtils.java │ │ │ ├── OSUtils.java │ │ │ ├── ObjectUtils.java │ │ │ ├── Pool.java │ │ │ ├── ResourcesUtils.java │ │ │ ├── SimpleAnimatorListener.java │ │ │ ├── SimpleHandler.java │ │ │ ├── StringUtils.java │ │ │ ├── StringUtils.kt │ │ │ ├── Utilities.java │ │ │ ├── ViewUtils.java │ │ │ ├── collect/ │ │ │ │ ├── IntList.kt │ │ │ │ └── LongList.kt │ │ │ └── thread/ │ │ │ ├── InfiniteThreadExecutor.java │ │ │ ├── PriorityThread.java │ │ │ └── PriorityThreadFactory.java │ │ └── eu/ │ │ └── kanade/ │ │ └── tachiyomi/ │ │ └── network/ │ │ └── interceptor/ │ │ ├── CloudflareInterceptor.kt │ │ └── WebViewInterceptor.kt │ └── res/ │ ├── anim/ │ │ ├── accelerate_quart.xml │ │ ├── decelerate_quart.xml │ │ ├── decelerate_quint.xml │ │ ├── scene_close_exit.xml │ │ ├── scene_open_enter.xml │ │ ├── scene_open_enter_horizontal.xml │ │ └── scene_open_exit.xml │ ├── color/ │ │ ├── content_reactive.xml │ │ ├── content_reactive_black.xml │ │ └── primary_text_material_black.xml │ ├── drawable/ │ │ ├── big_download.xml │ │ ├── big_filter.xml │ │ ├── big_history.xml │ │ ├── big_sad_pandroid.xml │ │ ├── category_background.xml │ │ ├── check_text_view_foreground.xml │ │ ├── default_avatar.xml │ │ ├── divider_gallery_detail.xml │ │ ├── divider_gallery_detail_dark.xml │ │ ├── ic_baseline_dark_mode_24.xml │ │ ├── ic_baseline_format_list_numbered_24.xml │ │ ├── ic_baseline_menu_24.xml │ │ ├── ic_baseline_reorder_24.xml │ │ ├── ic_baseline_warning_24.xml │ │ ├── ic_launcher_foreground.xml │ │ ├── ic_launcher_monochrome.xml │ │ ├── ic_pause_108dp.xml │ │ ├── ic_play_arrow_108dp.xml │ │ ├── image_failed.xml │ │ ├── round_side_rect.xml │ │ ├── spacer_keyline.xml │ │ ├── spacer_x6.xml │ │ ├── tile_background.xml │ │ ├── v_adb_primary_x24.xml │ │ ├── v_archive_primary_x48.xml │ │ ├── v_arrow_left_dark_x24.xml │ │ ├── v_book_open_primary_x24.xml │ │ ├── v_book_open_x24.xml │ │ ├── v_check_all_dark_x24.xml │ │ ├── v_check_dark_x24.xml │ │ ├── v_clear_all_dark_x24.xml │ │ ├── v_close_dark_x24.xml │ │ ├── v_cookie_brown_x48.xml │ │ ├── v_delete_x24.xml │ │ ├── v_dots_vertical_secondary_dark_x24.xml │ │ ├── v_download_box_dark_x24.xml │ │ ├── v_download_primary_x24.xml │ │ ├── v_download_x16.xml │ │ ├── v_download_x24.xml │ │ ├── v_eh_subscription_black_x24.xml │ │ ├── v_filter_dark_x24.xml │ │ ├── v_fire_black_x24.xml │ │ ├── v_folder_move_x24.xml │ │ ├── v_go_to_dark_x24.xml │ │ ├── v_heart_box_dark_x24.xml │ │ ├── v_heart_broken_x24.xml │ │ ├── v_heart_outline_primary_x48.xml │ │ ├── v_heart_primary_x48.xml │ │ ├── v_heart_x16.xml │ │ ├── v_heart_x24.xml │ │ ├── v_help_circle_x24.xml │ │ ├── v_history_black_x24.xml │ │ ├── v_homepage_black_x24.xml │ │ ├── v_info_outline_dark_x24.xml │ │ ├── v_info_primary_x24.xml │ │ ├── v_last_page_x24.xml │ │ ├── v_magnify_x24.xml │ │ ├── v_pause_x24.xml │ │ ├── v_pencil_dark_x24.xml │ │ ├── v_pin_top_24.xml │ │ ├── v_play_x24.xml │ │ ├── v_plus_dark_x24.xml │ │ ├── v_refresh_dark_x24.xml │ │ ├── v_reply_dark_x24.xml │ │ ├── v_sad_panda_primary_x24.xml │ │ ├── v_sec_primary_x24.xml │ │ ├── v_send_dark_x24.xml │ │ ├── v_settings_black_x24.xml │ │ ├── v_share_primary_x48.xml │ │ ├── v_similar_primary_x48.xml │ │ ├── v_slider_bubble.xml │ │ ├── v_star_half_x16.xml │ │ ├── v_star_outline_x16.xml │ │ ├── v_star_x16.xml │ │ └── v_utorrent_primary_x48.xml │ ├── drawable-v25/ │ │ ├── ic_shortcut_start.xml │ │ └── ic_shortcut_stop.xml │ ├── drawable-v26/ │ │ ├── ic_shortcut_start.xml │ │ └── ic_shortcut_stop.xml │ ├── layout/ │ │ ├── activity_filter.xml │ │ ├── activity_gallery.xml │ │ ├── activity_main.xml │ │ ├── activity_preference.xml │ │ ├── activity_set_security.xml │ │ ├── activity_webview.xml │ │ ├── dialog_add_filter.xml │ │ ├── dialog_archive_list.xml │ │ ├── dialog_checkbox_builder.xml │ │ ├── dialog_edittext_builder.xml │ │ ├── dialog_edittextcheckbox_builder.xml │ │ ├── dialog_gallery_menu.xml │ │ ├── dialog_go_to.xml │ │ ├── dialog_item_select_with_icon.xml │ │ ├── dialog_js_prompt.xml │ │ ├── dialog_list_checkbox_builder.xml │ │ ├── dialog_rate.xml │ │ ├── dialog_recycler_view.xml │ │ ├── dialog_torrent_list.xml │ │ ├── drawer_list_rv.xml │ │ ├── gallery_detail_actions.xml │ │ ├── gallery_detail_comments.xml │ │ ├── gallery_detail_content.xml │ │ ├── gallery_detail_header.xml │ │ ├── gallery_detail_info.xml │ │ ├── gallery_detail_previews.xml │ │ ├── gallery_detail_tags.xml │ │ ├── gallery_tag_group.xml │ │ ├── item_cute_spinner_item.xml │ │ ├── item_download.xml │ │ ├── item_drawer_favorites.xml │ │ ├── item_drawer_list.xml │ │ ├── item_filter.xml │ │ ├── item_filter_header.xml │ │ ├── item_gallery_comment.xml │ │ ├── item_gallery_comment_more.xml │ │ ├── item_gallery_comment_progress.xml │ │ ├── item_gallery_grid.xml │ │ ├── item_gallery_info_data.xml │ │ ├── item_gallery_info_header.xml │ │ ├── item_gallery_list.xml │ │ ├── item_gallery_list_thumb_height.xml │ │ ├── item_gallery_preview.xml │ │ ├── item_gallery_tag.xml │ │ ├── item_history.xml │ │ ├── item_hosts.xml │ │ ├── item_select_dialog.xml │ │ ├── item_simple_list_2.xml │ │ ├── nav_header_main.xml │ │ ├── preference_dialog_proxy.xml │ │ ├── preference_dialog_task.xml │ │ ├── preference_recyclerview.xml │ │ ├── scene_cookie_sign_in.xml │ │ ├── scene_download.xml │ │ ├── scene_favorites.xml │ │ ├── scene_gallery_comments.xml │ │ ├── scene_gallery_detail.xml │ │ ├── scene_gallery_info.xml │ │ ├── scene_gallery_list.xml │ │ ├── scene_gallery_previews.xml │ │ ├── scene_history.xml │ │ ├── scene_login.xml │ │ ├── scene_progress.xml │ │ ├── scene_security.xml │ │ ├── scene_select_site.xml │ │ ├── scene_toolbar.xml │ │ ├── search_action.xml │ │ ├── search_advance.xml │ │ ├── search_category.xml │ │ ├── search_image.xml │ │ ├── search_normal.xml │ │ ├── widget_advance_search_table.xml │ │ ├── widget_category_table.xml │ │ ├── widget_content_layout.xml │ │ ├── widget_gallery_guide_1.xml │ │ ├── widget_gallery_guide_2.xml │ │ ├── widget_image_search.xml │ │ └── widget_search_bar.xml │ ├── layout-land/ │ │ └── activity_set_security.xml │ ├── menu/ │ │ ├── activity_filter.xml │ │ ├── activity_u_config.xml │ │ ├── context_comment.xml │ │ ├── download_label_option.xml │ │ ├── drawer_download.xml │ │ ├── drawer_favorites.xml │ │ ├── drawer_gallery_list.xml │ │ ├── nav_drawer_main.xml │ │ ├── quicksearch_option.xml │ │ ├── scene_download.xml │ │ ├── scene_gallery_detail.xml │ │ ├── scene_gallery_previews.xml │ │ └── scene_history.xml │ ├── mipmap-anydpi-v26/ │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ ├── raw/ │ │ └── isrgrootx1 │ ├── transition/ │ │ ├── trans_fade.xml │ │ └── trans_move.xml │ ├── values/ │ │ ├── arrays.xml │ │ ├── attrs.xml │ │ ├── bools.xml │ │ ├── color_launcher.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── drawables.xml │ │ ├── ids.xml │ │ ├── pathdata.xml │ │ ├── strings.xml │ │ ├── styles.xml │ │ ├── themes.xml │ │ └── themes_override.xml │ ├── values-ja/ │ │ └── strings.xml │ ├── values-night/ │ │ ├── color_launcher.xml │ │ ├── colors.xml │ │ └── styles.xml │ ├── values-sw600dp/ │ │ └── dimens.xml │ ├── values-sw720dp-land/ │ │ └── dimens.xml │ ├── values-v24/ │ │ └── arrays.xml │ ├── values-zh-rCN/ │ │ ├── bools.xml │ │ └── strings.xml │ ├── values-zh-rHK/ │ │ ├── bools.xml │ │ └── strings.xml │ ├── values-zh-rTW/ │ │ ├── bools.xml │ │ └── strings.xml │ ├── xml/ │ │ ├── about_settings.xml │ │ ├── advanced_settings.xml │ │ ├── backup_scheme.xml │ │ ├── data_extraction_rules.xml │ │ ├── download_settings.xml │ │ ├── eh_settings.xml │ │ ├── filepaths.xml │ │ ├── locale_config.xml │ │ ├── privacy_settings.xml │ │ ├── read_settings.xml │ │ └── settings_headers.xml │ └── xml-v25/ │ └── shortcuts.xml ├── build.gradle.kts ├── docs/ │ ├── CHANGELOG/ │ │ └── zh-cn.md │ └── README/ │ └── zh-cn.md ├── gradle/ │ ├── libs.versions.toml │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat └── settings.gradle.kts
SYMBOL INDEX (1767 symbols across 113 files)
FILE: app/src/main/cpp/archive.c
type archive_ctx (line 38) | typedef struct {
type entry (line 45) | typedef struct {
function filename_is_playable_file (line 84) | static inline int filename_is_playable_file(const char *name) {
function archive_entry_is_file (line 97) | static inline bool archive_entry_is_file(struct archive_entry *entry) {
function archive_entry_is_playable (line 101) | static inline bool archive_entry_is_playable(struct archive_entry *entry) {
function compare_entries (line 106) | static inline int compare_entries(const void *a, const void *b) {
function fill_entry_zero_copy (line 114) | static bool fill_entry_zero_copy(struct archive *arc, entry *entry) {
function archive_map_entries_index (line 124) | static void archive_map_entries_index(archive_ctx *ctx, bool sort) {
function release_decode_buffer (line 158) | static void release_decode_buffer(void *buffer) {
function archive_list_all_entries (line 172) | static int archive_list_all_entries(archive_ctx *ctx) {
function archive_release_ctx (line 180) | static void archive_release_ctx(archive_ctx *ctx) {
function archive_ctx (line 188) | static archive_ctx *archive_alloc_ctx() {
function archive_skip_to_index (line 211) | static int archive_skip_to_index(archive_ctx *ctx, int index) {
function archive_get_ctx (line 222) | static int archive_get_ctx(archive_ctx **ctxptr, int idx) {
function JNICALL (line 276) | JNICALL
function JNICALL (line 331) | JNICALL
function JNICALL (line 360) | JNICALL
function JNICALL (line 391) | JNICALL
function JNICALL (line 398) | JNICALL
function JNICALL (line 425) | JNICALL
function JNICALL (line 440) | JNICALL
function JNICALL (line 455) | JNICALL
FILE: app/src/main/cpp/gifutils.c
type byte (line 38) | typedef signed char byte;
function isGif (line 44) | static inline bool isGif(void *addr) {
function doRewrite (line 49) | static void doRewrite(byte *addr, size_t size) {
function JNICALL (line 67) | JNICALL
function JNICALL (line 74) | JNICALL
function JNICALL (line 81) | JNICALL
function JNICALL (line 91) | JNICALL
FILE: app/src/main/cpp/hash.c
type byte (line 29) | typedef uint8_t byte;
function JNICALL (line 33) | JNICALL
FILE: app/src/main/cpp/image.c
function copy_pixels (line 38) | bool copy_pixels(const void *src, int src_w, int src_h, int src_x, int s...
function JNICALL (line 125) | JNICALL
FILE: app/src/main/cpp/natsort/strnatcmp.c
function nat_isdigit (line 40) | static inline int
function nat_isspace (line 47) | static inline int
function compare_right (line 54) | static int
function strnatcmp (line 82) | int
FILE: app/src/main/java/com/hippo/ehviewer/AppConfig.java
class AppConfig (line 36) | public class AppConfig {
method initialize (line 47) | public static void initialize(Context context) {
method getExternalAppDir (line 51) | @Nullable
method getDirInExternalAppDir (line 63) | @Nullable
method getFileInExternalAppDir (line 73) | @Nullable
method getDefaultDownloadDir (line 83) | @Nullable
method getExternalTempDir (line 88) | @Nullable
method getExternalCopyTempDir (line 99) | @Nullable
method getExternalParseErrorDir (line 110) | @Nullable
method getExternalCrashDir (line 115) | @Nullable
method getTempDir (line 120) | @Nullable
method createTempFile (line 131) | @Nullable
method saveParseErrorBody (line 136) | public static void saveParseErrorBody(ParseException e, String body) {
method getFilesDir (line 162) | @Nullable
FILE: app/src/main/java/com/hippo/ehviewer/FavouriteStatusRouter.java
class FavouriteStatusRouter (line 29) | public class FavouriteStatusRouter {
method saveDataMap (line 38) | public int saveDataMap(Map<Long, GalleryInfo> map) {
method restoreDataMap (line 45) | public Map<Long, GalleryInfo> restoreDataMap(int id) {
method modifyFavourites (line 49) | public void modifyFavourites(long gid, int slot) {
method addListener (line 62) | public void addListener(Listener listener) {
method removeListener (line 66) | public void removeListener(Listener listener) {
type Listener (line 70) | public interface Listener {
method onModifyFavourites (line 71) | void onModifyFavourites(long gid, int slot);
FILE: app/src/main/java/com/hippo/ehviewer/WindowInsetsAnimationHelper.java
class WindowInsetsAnimationHelper (line 32) | public class WindowInsetsAnimationHelper extends WindowInsetsAnimationCo...
method WindowInsetsAnimationHelper (line 38) | public WindowInsetsAnimationHelper(int dispatchMode, View... views) {
method onPrepare (line 43) | @Override
method onStart (line 55) | @NonNull
method onProgress (line 71) | @NonNull
method onEnd (line 99) | @Override
FILE: app/src/main/java/com/hippo/ehviewer/widget/DialogWebChromeClient.java
class DialogWebChromeClient (line 33) | public class DialogWebChromeClient extends WebChromeClient {
method DialogWebChromeClient (line 36) | public DialogWebChromeClient(Context context) {
method onJsAlert (line 40) | @Override
method onJsConfirm (line 50) | @Override
method onJsPrompt (line 61) | @Override
FILE: app/src/main/java/com/hippo/ehviewer/widget/GalleryGuideView.java
class GalleryGuideView (line 36) | public class GalleryGuideView extends ViewGroup implements View.OnClickL...
method GalleryGuideView (line 48) | public GalleryGuideView(Context context) {
method GalleryGuideView (line 53) | public GalleryGuideView(Context context, AttributeSet attrs) {
method GalleryGuideView (line 58) | public GalleryGuideView(Context context, AttributeSet attrs, int defSt...
method init (line 63) | private void init(Context context) {
method bind (line 74) | private void bind() {
method bind1 (line 94) | private void bind1() {
method bind2 (line 103) | private void bind2() {
method onMeasure (line 109) | @Override
method onLayout (line 140) | @Override
method onSizeChanged (line 159) | @Override
method onDraw (line 181) | @Override
method onClick (line 190) | @Override
FILE: app/src/main/java/com/hippo/ehviewer/widget/GalleryHeader.java
class GalleryHeader (line 33) | public class GalleryHeader extends ViewGroup {
method GalleryHeader (line 46) | public GalleryHeader(Context context, AttributeSet attrs) {
method setDisplayCutout (line 50) | public void setDisplayCutout(@Nullable DisplayCutoutCompat displayCuto...
method setTopInsets (line 57) | public void setTopInsets(int topInsets) {
method onFinishInflate (line 64) | @Override
method measureChild (line 73) | private void measureChild(Rect rect, View view, int width, int padding...
method offsetVertically (line 86) | @RequiresApi(api = Build.VERSION_CODES.P)
method getOffsetLeft (line 108) | @RequiresApi(api = Build.VERSION_CODES.P)
method getOffsetRight (line 124) | @RequiresApi(api = Build.VERSION_CODES.P)
method onMeasure (line 140) | @Override
method onLayout (line 178) | @Override
method generateLayoutParams (line 192) | @Override
method checkLayoutParams (line 197) | @Override
method generateLayoutParams (line 202) | @Override
FILE: app/src/main/java/com/hippo/ehviewer/widget/GalleryRatingBar.java
class GalleryRatingBar (line 26) | public class GalleryRatingBar extends AppCompatRatingBar
method GalleryRatingBar (line 30) | public GalleryRatingBar(Context context) {
method GalleryRatingBar (line 35) | public GalleryRatingBar(Context context, AttributeSet attrs) {
method GalleryRatingBar (line 40) | public GalleryRatingBar(Context context, AttributeSet attrs,
method init (line 46) | private void init() {
method onDraw (line 50) | @Override
method setOnUserRateListener (line 59) | public void setOnUserRateListener(OnUserRateListener l) {
method onRatingChanged (line 63) | @Override
type OnUserRateListener (line 70) | public interface OnUserRateListener {
method onUserRate (line 71) | void onUserRate(float rating);
FILE: app/src/main/java/com/hippo/ehviewer/widget/ReversibleSeekBar.java
class ReversibleSeekBar (line 28) | public class ReversibleSeekBar extends AppCompatSeekBar {
method ReversibleSeekBar (line 31) | public ReversibleSeekBar(Context context) {
method ReversibleSeekBar (line 35) | public ReversibleSeekBar(Context context, AttributeSet attrs) {
method ReversibleSeekBar (line 39) | public ReversibleSeekBar(Context context, AttributeSet attrs, int defS...
method setReverse (line 43) | public void setReverse(boolean reverse) {
method draw (line 48) | @Override
method onTouchEvent (line 64) | @SuppressLint("ClickableViewAccessibility")
FILE: app/src/main/java/com/hippo/ehviewer/widget/SearchDatabase.java
class SearchDatabase (line 33) | public final class SearchDatabase {
method SearchDatabase (line 44) | @SuppressWarnings("resource")
method getInstance (line 50) | public static SearchDatabase getInstance(Context context) {
method getSuggestions (line 57) | public String[] getSuggestions(String prefix, int limit) {
method addQuery (line 89) | public void addQuery(final String query) {
method deleteQuery (line 103) | public void deleteQuery(final String query) {
method clearQuery (line 107) | public void clearQuery() {
method truncateHistory (line 116) | private void truncateHistory(int maxEntries) {
class DatabaseHelper (line 141) | private static class DatabaseHelper extends SQLiteOpenHelper {
method DatabaseHelper (line 142) | public DatabaseHelper(Context context) {
method onCreate (line 146) | @Override
method onUpgrade (line 155) | @Override
FILE: app/src/main/java/com/hippo/ehviewer/widget/SearchEditText.java
class SearchEditText (line 36) | public class SearchEditText extends AppCompatEditText {
method SearchEditText (line 39) | public SearchEditText(Context context) {
method SearchEditText (line 43) | public SearchEditText(Context context, AttributeSet attrs) {
method SearchEditText (line 47) | public SearchEditText(Context context, AttributeSet attrs, int defStyl...
method setSearchEditTextListener (line 51) | public void setSearchEditTextListener(SearchEditTextListener listener) {
method onKeyPreIme (line 55) | @Override
method onTouchEvent (line 83) | @SuppressLint("ClickableViewAccessibility")
method onReceiveContent (line 99) | @RequiresApi(api = Build.VERSION_CODES.S)
type SearchEditTextListener (line 112) | public interface SearchEditTextListener {
method onClick (line 113) | void onClick();
method onBackPressed (line 115) | void onBackPressed();
method onReceiveContent (line 117) | void onReceiveContent(Uri uri);
FILE: app/src/main/java/com/hippo/ehviewer/widget/SimpleRatingView.java
class SimpleRatingView (line 34) | public class SimpleRatingView extends View {
method SimpleRatingView (line 44) | public SimpleRatingView(Context context) {
method SimpleRatingView (line 49) | public SimpleRatingView(Context context, AttributeSet attrs) {
method SimpleRatingView (line 54) | public SimpleRatingView(Context context, AttributeSet attrs, int defSt...
method init (line 59) | private void init(Context context) {
method onMeasure (line 72) | @Override
method onDraw (line 77) | @Override
method getRating (line 100) | public float getRating() {
method setRating (line 104) | public void setRating(float rating) {
FILE: app/src/main/java/com/hippo/ehviewer/widget/TileThumb.java
class TileThumb (line 25) | public class TileThumb extends LoadImageView {
method TileThumb (line 30) | public TileThumb(Context context) {
method TileThumb (line 34) | public TileThumb(Context context, AttributeSet attrs) {
method TileThumb (line 38) | public TileThumb(Context context, AttributeSet attrs, int defStyleAttr) {
method setThumbSize (line 42) | public void setThumbSize(int thumbWidth, int thumbHeight) {
FILE: app/src/main/java/com/hippo/glgallery/DownUpDetector.java
class DownUpDetector (line 21) | class DownUpDetector {
method DownUpDetector (line 25) | public DownUpDetector(DownUpListener listener) {
method setState (line 29) | private void setState(boolean down, MotionEvent e) {
method onTouchEvent (line 39) | public void onTouchEvent(MotionEvent ev) {
method isDown (line 51) | public boolean isDown() {
type DownUpListener (line 55) | public interface DownUpListener {
method onDown (line 56) | void onDown(MotionEvent e);
method onUp (line 58) | void onUp(MotionEvent e);
method onPointerDown (line 60) | void onPointerDown(MotionEvent e);
method onPointerUp (line 62) | void onPointerUp(MotionEvent e);
FILE: app/src/main/java/com/hippo/glgallery/Fling.java
class Fling (line 26) | abstract class Fling extends Animation {
method Fling (line 88) | public Fling(Context context) {
method getSplineDeceleration (line 97) | private double getSplineDeceleration(int velocity) {
method getSplineFlingDuration (line 102) | protected int getSplineFlingDuration(int velocity) {
method getSplineFlingDistance (line 108) | protected double getSplineFlingDistance(int velocity) {
method adjustDuration (line 118) | protected int adjustDuration(int oldFinal, int newFinal, int duration) {
FILE: app/src/main/java/com/hippo/glgallery/GalleryPageView.java
class GalleryPageView (line 30) | public class GalleryPageView extends GLFrameLayout {
method GalleryPageView (line 46) | public GalleryPageView(ImageMovableTextTexture pageTextTexture,
method getSuggestedMinimumHeight (line 93) | @Override
method getIndex (line 105) | int getIndex() {
method setIndex (line 109) | void setIndex(int index) {
method showImage (line 113) | public void showImage() {
method showInfo (line 118) | public void showInfo() {
method unbindImage (line 124) | private void unbindImage() {
method setImage (line 132) | public void setImage(ImageTexture imageTexture) {
method setPage (line 139) | public void setPage(int page) {
method setProgress (line 144) | public void setProgress(float progress) {
method unbindError (line 157) | private void unbindError() {
method setError (line 167) | public void setError(String error, GalleryView galleryView) {
method getImageView (line 177) | ImageView getImageView() {
method isLoaded (line 181) | boolean isLoaded() {
method isError (line 185) | boolean isError() {
method isUnderInfo (line 189) | boolean isUnderInfo(float x, float y) {
FILE: app/src/main/java/com/hippo/glgallery/GalleryView.java
class GalleryView (line 48) | public final class GalleryView extends GLView implements GestureRecogniz...
method GalleryView (line 134) | private GalleryView(Builder build) {
method sanitizeLayoutMode (line 164) | @LayoutMode
method sanitizeScaleMode (line 175) | @ScaleMode
method sanitizeStartPosition (line 188) | @StartPosition
method ensurePagerLayoutManager (line 201) | private void ensurePagerLayoutManager() {
method ensureScrollLayoutManager (line 208) | private void ensureScrollLayoutManager() {
method attachLayoutManager (line 214) | private void attachLayoutManager() {
method detachLayoutManager (line 248) | private void detachLayoutManager() {
method onAttachToRootInternal (line 258) | private void onAttachToRootInternal() {
method setPagerIntervalInternal (line 267) | private void setPagerIntervalInternal(int interval) {
method setScrollIntervalInternal (line 274) | private void setScrollIntervalInternal(int interval) {
method onAttachToRoot (line 281) | @Override
method onDetachFromRoot (line 287) | @Override
method getLayoutMode (line 299) | public int getLayoutMode() {
method setLayoutMode (line 303) | public void setLayoutMode(@LayoutMode int layoutMode) {
method requestLayout (line 307) | @Override
method requestFill (line 313) | public void requestFill() {
method dispatchTouchEvent (line 322) | @Override
method getEmptyStr (line 329) | String getEmptyStr() {
method isFirstScroll (line 333) | boolean isFirstScroll() {
method postMethod (line 340) | private void postMethod(int method, Object... args) {
method setCurrentPage (line 349) | public void setCurrentPage(int page) {
method pageLeft (line 353) | public void pageLeft() {
method pageRight (line 357) | public void pageRight() {
method setScaleMode (line 361) | public void setScaleMode(int scaleMode) {
method setStartPosition (line 365) | public void setStartPosition(int startPosition) {
method setPagerInterval (line 369) | public void setPagerInterval(int interval) {
method setScrollInterval (line 373) | public void setScrollInterval(int interval) {
method onSingleTapUp (line 377) | @Override
method onSingleTapConfirmed (line 383) | @Override
method onDoubleTap (line 389) | @Override
method onDoubleTapConfirmed (line 395) | @Override
method onLongPress (line 401) | @Override
method onScroll (line 410) | @Override
method onFling (line 416) | @Override
method onScaleBegin (line 422) | @Override
method onScale (line 428) | @Override
method onScaleEnd (line 434) | @Override
method onDown (line 439) | @Override
method onUp (line 444) | @Override
method onPointerDown (line 449) | @Override
method onPointerUp (line 454) | @Override
method onLayout (line 459) | @Override
method onDataChanged (line 476) | public void onDataChanged() {
method onSingleTapUpInternal (line 484) | private void onSingleTapUpInternal() {
method findPageUnder (line 487) | private GalleryPageView findPageUnder(float x, float y) {
method onSingleTapConfirmedInternal (line 497) | private void onSingleTapConfirmedInternal(float x, float y) {
method onDoubleTapInternal (line 525) | private void onDoubleTapInternal() {
method onDoubleTapConfirmedInternal (line 528) | private void onDoubleTapConfirmedInternal(float x, float y) {
method onLongPressInternal (line 538) | private void onLongPressInternal(float x, float y) {
method onScrollInternal (line 557) | private void onScrollInternal(float dx, float dy, float totalX, float ...
method onFlingInternal (line 568) | private void onFlingInternal(float velocityX, float velocityY) {
method onScaleBeginInternal (line 574) | private void onScaleBeginInternal(float focusX, float focusY) {
method onScaleInternal (line 578) | private void onScaleInternal(float focusX, float focusY, float scale) {
method onScaleEndInternal (line 589) | private void onScaleEndInternal() {
method onDownInternal (line 592) | private void onDownInternal() {
method onUpInternal (line 601) | private void onUpInternal() {
method onPointerDownInternal (line 607) | private void onPointerDownInternal() {
method onPointerUpInternal (line 613) | private void onPointerUpInternal() {
method setLayoutModeInternal (line 616) | private void setLayoutModeInternal(int layoutMode) {
method setCurrentPageInternal (line 665) | private void setCurrentPageInternal(int page) {
method pageLeftInternal (line 673) | private void pageLeftInternal() {
method pageRightInternal (line 679) | private void pageRightInternal() {
method setScaleModeInternal (line 685) | private void setScaleModeInternal(int scaleMode) {
method setStartPositionInternal (line 692) | private void setStartPositionInternal(int startPosition) {
method forceFill (line 699) | void forceFill() {
method fill (line 704) | private void fill() {
method dispatchMethod (line 720) | private void dispatchMethod() {
method render (line 776) | @Override
method findPageByIndex (line 807) | public GalleryPageView findPageByIndex(int id) {
method obtainPage (line 815) | GalleryPageView obtainPage() {
method releasePage (line 825) | void releasePage(GalleryPageView page) {
method obtainErrorView (line 829) | GLTextureView obtainErrorView() {
method unbindErrorView (line 840) | void unbindErrorView(GLTextureView errorView) {
method bindErrorView (line 850) | void bindErrorView(GLTextureView errorView, String error) {
method releaseErrorView (line 857) | void releaseErrorView(GLTextureView errorView) {
type Listener (line 878) | public interface Listener {
method onUpdateCurrentIndex (line 879) | void onUpdateCurrentIndex(int index);
method onTapSliderArea (line 881) | void onTapSliderArea();
method onTapMenuArea (line 883) | void onTapMenuArea();
method onTapErrorText (line 885) | void onTapErrorText(int index);
method onLongPressPage (line 887) | void onLongPressPage(int index);
class Builder (line 890) | public static class Builder {
method Builder (line 912) | public Builder(@NonNull Context context, @NonNull Adapter adapter) {
method setListener (line 917) | public Builder setListener(Listener listener) {
method setLayoutMode (line 922) | public Builder setLayoutMode(@LayoutMode int layoutMode) {
method setScaleMode (line 927) | public Builder setScaleMode(@ScaleMode int scaleMode) {
method setStartPosition (line 932) | public Builder setStartPosition(@StartPosition int startPosition) {
method setStartPage (line 937) | public Builder setStartPage(int startPage) {
method setBackgroundColor (line 942) | public Builder setBackgroundColor(int backgroundColor) {
method setPagerInterval (line 947) | public Builder setPagerInterval(int pagerInterval) {
method setScrollInterval (line 952) | public Builder setScrollInterval(int scrollInterval) {
method setPageMinHeight (line 957) | public Builder setPageMinHeight(int pageMinHeight) {
method setPageInfoInterval (line 962) | public Builder setPageInfoInterval(int pageInfoInterval) {
method setProgressColor (line 967) | public Builder setProgressColor(int progressColor) {
method setProgressSize (line 972) | public Builder setProgressSize(int progressSize) {
method setPageTextColor (line 977) | public Builder setPageTextColor(int pageTextColor) {
method setPageTextSize (line 982) | public Builder setPageTextSize(int pageTextSize) {
method setPageTextTypeface (line 987) | public Builder setPageTextTypeface(Typeface pageTextTypeface) {
method setErrorTextColor (line 992) | public Builder setErrorTextColor(int errorTextColor) {
method setErrorTextSize (line 997) | public Builder setErrorTextSize(int errorTextSize) {
method setEmptyString (line 1002) | public Builder setEmptyString(String emptyString) {
method build (line 1007) | public GalleryView build() {
class Adapter (line 1012) | public static abstract class Adapter {
method setGalleryView (line 1015) | private void setGalleryView(@NonNull GalleryView galleryView) {
method bind (line 1019) | public void bind(GalleryPageView view, int index) {
method unbind (line 1024) | public void unbind(GalleryPageView view) {
method onBind (line 1029) | public abstract void onBind(GalleryPageView view, int index);
method onUnbind (line 1031) | public abstract void onUnbind(GalleryPageView view, int index);
method size (line 1033) | public abstract int size();
class LayoutManager (line 1036) | public static abstract class LayoutManager {
method LayoutManager (line 1039) | public LayoutManager(@NonNull GalleryView galleryView) {
method onAttach (line 1043) | public abstract void onAttach(Adapter iterator);
method onDetach (line 1045) | public abstract Adapter onDetach();
method onFill (line 1047) | public abstract void onFill();
method onDown (line 1049) | public abstract void onDown();
method onUp (line 1051) | public abstract void onUp();
method onDoubleTapConfirmed (line 1053) | public abstract void onDoubleTapConfirmed(float x, float y);
method onScroll (line 1055) | public abstract void onScroll(float dx, float dy, float totalX, floa...
method onFling (line 1057) | public abstract void onFling(float velocityX, float velocityY);
method canScale (line 1059) | public abstract boolean canScale();
method onScale (line 1061) | public abstract void onScale(float focusX, float focusY, float scale);
method onUpdateAnimation (line 1063) | public abstract boolean onUpdateAnimation(long time);
method onDataChanged (line 1065) | public abstract void onDataChanged();
method onPageLeft (line 1067) | public abstract void onPageLeft();
method onPageRight (line 1069) | public abstract void onPageRight();
method isTapOrPressDisable (line 1071) | public abstract boolean isTapOrPressDisable();
method findPageByIndex (line 1073) | public abstract GalleryPageView findPageByIndex(int index);
method getCurrentIndex (line 1078) | public abstract int getCurrentIndex();
method setCurrentIndex (line 1080) | public abstract void setCurrentIndex(int index);
method getIndexUnder (line 1082) | public abstract int getIndexUnder(float x, float y);
method getInternalCurrentIndex (line 1084) | abstract int getInternalCurrentIndex();
method placeCenter (line 1086) | protected void placeCenter(GLView view) {
FILE: app/src/main/java/com/hippo/glgallery/GestureRecognizer.java
class GestureRecognizer (line 28) | class GestureRecognizer {
method GestureRecognizer (line 36) | public GestureRecognizer(Context context, Listener listener) {
method onTouchEvent (line 45) | public void onTouchEvent(MotionEvent event) {
method isDown (line 51) | public boolean isDown() {
type Listener (line 55) | public interface Listener {
method onSingleTapUp (line 56) | boolean onSingleTapUp(float x, float y);
method onSingleTapConfirmed (line 58) | boolean onSingleTapConfirmed(float x, float y);
method onDoubleTap (line 60) | boolean onDoubleTap(float x, float y);
method onDoubleTapConfirmed (line 62) | boolean onDoubleTapConfirmed(float x, float y);
method onLongPress (line 64) | void onLongPress(float x, float y);
method onScroll (line 66) | boolean onScroll(float dx, float dy, float totalX, float totalY, flo...
method onFling (line 72) | boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, flo...
method onScaleBegin (line 74) | boolean onScaleBegin(float focusX, float focusY);
method onScale (line 76) | boolean onScale(float focusX, float focusY, float scale);
method onScaleEnd (line 78) | void onScaleEnd();
method onDown (line 80) | void onDown(float x, float y);
method onUp (line 82) | void onUp();
method onPointerDown (line 84) | void onPointerDown(float x, float y);
method onPointerUp (line 86) | void onPointerUp();
class MyGestureListener (line 89) | private class MyGestureListener extends GestureDetector.SimpleOnGestur...
method onSingleTapUp (line 90) | @Override
method onSingleTapConfirmed (line 95) | @Override
method onDoubleTapEvent (line 100) | @Override
method onDoubleTap (line 109) | @Override
method onLongPress (line 114) | @Override
method onScroll (line 117) | @Override
method onFling (line 123) | @Override
class MyScaleListener (line 129) | private class MyScaleListener extends ScaleGestureDetector.SimpleOnSca...
method onScaleBegin (line 130) | @Override
method onScale (line 135) | @Override
method onScaleEnd (line 140) | @Override
class MyDownUpListener (line 146) | private class MyDownUpListener implements DownUpDetector.DownUpListener {
method onDown (line 147) | @Override
method onUp (line 152) | @Override
method onPointerDown (line 157) | @Override
method onPointerUp (line 162) | @Override
FILE: app/src/main/java/com/hippo/glgallery/ImageView.java
class ImageView (line 32) | class ImageView extends GLView implements ImageTexture.Callback {
method ImageView (line 62) | public ImageView() {
method getSuggestedMinimumWidth (line 68) | @Override
method getSuggestedMinimumHeight (line 74) | @Override
method onMeasure (line 80) | @Override
method onSizeChanged (line 119) | @Override
method onPositionInRootChanged (line 125) | @Override
method getScaleDefault (line 139) | public void getScaleDefault(float[] scaleDefault) {
method getImageTexture (line 157) | public ImageTexture getImageTexture() {
method setImageTexture (line 161) | public void setImageTexture(ImageTexture imageTexture) {
method isLoaded (line 204) | public boolean isLoaded() {
method canFling (line 208) | public boolean canFling() {
method getMaxDx (line 219) | public int getMaxDx() {
method getMinDx (line 229) | public int getMinDx() {
method getMaxDy (line 239) | public int getMaxDy() {
method getMinDy (line 249) | public int getMinDy() {
method getScale (line 259) | public float getScale() {
method adjustPosition (line 267) | private void adjustPosition() {
method setScaleOffset (line 302) | public void setScaleOffset(int scaleMode, int startPosition, float sca...
method scroll (line 404) | public void scroll(int dx, int dy, int[] remain) {
method scale (line 466) | public void scale(float focusX, float focusY, float scale) {
method applyPositionInRoot (line 496) | private void applyPositionInRoot() {
method onRender (line 523) | @Override
method invalidateImageTexture (line 543) | @Override
FILE: app/src/main/java/com/hippo/glgallery/PagerLayoutManager.java
class PagerLayoutManager (line 38) | class PagerLayoutManager extends GalleryView.LayoutManager {
method PagerLayoutManager (line 71) | public PagerLayoutManager(Context context, @NonNull GalleryView galler...
method setInterval (line 85) | public void setInterval(int interval) {
method resetParameters (line 102) | private void resetParameters() {
method cancelAllAnimations (line 108) | private boolean cancelAllAnimations() {
method setMode (line 118) | public void setMode(@Mode int mode) {
method setScaleMode (line 139) | public void setScaleMode(int scaleMode) {
method setStartPosition (line 156) | public void setStartPosition(int startPosition) {
method onAttach (line 173) | @Override
method removeProgress (line 182) | private void removeProgress() {
method removeErrorView (line 189) | private void removeErrorView() {
method removePage (line 198) | private void removePage(@NonNull GalleryPageView page) {
method removeAllPages (line 204) | private void removeAllPages() {
method onDetach (line 220) | @Override
method getLeftPage (line 239) | private GalleryPageView getLeftPage() {
method getRightPage (line 243) | private GalleryPageView getRightPage() {
method obtainPage (line 247) | private GalleryPageView obtainPage() {
method layoutPage (line 253) | private void layoutPage(GalleryPageView page, int widthSpec, int heigh...
method onFill (line 267) | @Override
method onDown (line 365) | @Override
method onUp (line 370) | @Override
method onDoubleTapConfirmed (line 393) | @Override
method pagePrevious (line 414) | private void pagePrevious() {
method pageNext (line 434) | private void pageNext() {
method pageLeft (line 456) | private void pageLeft() {
method pageRight (line 464) | private void pageRight() {
method scrollBetweenPages (line 472) | private int scrollBetweenPages(int dx) {
method scrollInternal (line 521) | public void scrollInternal(float dx, float dy) {
method onScroll (line 563) | @Override
method onFling (line 568) | @Override
method canScale (line 580) | @Override
method onScale (line 585) | @Override
method onUpdateAnimation (line 595) | @Override
method onDataChanged (line 603) | @Override
method onPageLeft (line 618) | @Override
method onPageRight (line 636) | @Override
method isTapOrPressDisable (line 654) | @Override
method findPageByIndex (line 659) | @Override
method getCurrentIndex (line 673) | @Override
method setCurrentIndex (line 682) | @Override
method getIndexUnder (line 728) | @Override
method getInternalCurrentIndex (line 747) | @Override
class SmoothScroller (line 761) | private class SmoothScroller extends Animation {
method SmoothScroller (line 765) | public SmoothScroller() {
method startSmoothScroll (line 769) | public void startSmoothScroll(int dx, int duration) {
method onCalculate (line 777) | @Override
class PageFling (line 795) | private class PageFling extends Fling {
method PageFling (line 802) | public PageFling(Context context) {
method startFling (line 806) | public void startFling(int velocityX, int minX, int maxX,
method onCalculate (line 841) | @Override
class SmoothScaler (line 855) | private class SmoothScaler extends Animation {
method SmoothScaler (line 862) | public SmoothScaler() {
method startSmoothScaler (line 866) | public void startSmoothScaler(float focusX, float focusY,
method onCalculate (line 878) | @Override
FILE: app/src/main/java/com/hippo/glgallery/ScrollLayoutManager.java
class ScrollLayoutManager (line 37) | class ScrollLayoutManager extends GalleryView.LayoutManager {
method ScrollLayoutManager (line 71) | public ScrollLayoutManager(Context context, @NonNull GalleryView galle...
method setInterval (line 79) | public void setInterval(int interval) {
method resetParameters (line 96) | private void resetParameters() {
method cancelAllAnimations (line 109) | private boolean cancelAllAnimations() {
method onAttach (line 117) | @Override
method removeProgress (line 126) | private void removeProgress() {
method removeErrorView (line 133) | private void removeErrorView() {
method removePage (line 142) | private void removePage(@NonNull GalleryPageView page) {
method removeAllPages (line 148) | private void removeAllPages() {
method onDetach (line 155) | @Override
method obtainPage (line 174) | private GalleryPageView obtainPage() {
method getPageForIndex (line 180) | private GalleryPageView getPageForIndex(List<GalleryPageView> pages, i...
method isInScreen (line 193) | private boolean isInScreen(GalleryPageView page, boolean includeFirst) {
method getReservation (line 203) | private float getReservation() {
method fillPages (line 207) | private void fillPages(int startIndex, int startOffset) {
method onFill (line 399) | @Override
method onDown (line 497) | @Override
method onUp (line 503) | @Override
method onDoubleTapConfirmed (line 508) | @Override
method getBottomState (line 527) | private void getBottomState() {
method scrollInternal (line 545) | private boolean scrollInternal(float dx, float dy) {
method onScroll (line 646) | @Override
method onFling (line 654) | @Override
method canScale (line 698) | @Override
method onScale (line 703) | @Override
method onUpdateAnimation (line 750) | @Override
method onDataChanged (line 757) | @Override
method onPageLeft (line 772) | @Override
method onPageRight (line 821) | @Override
method isTapOrPressDisable (line 874) | @Override
method findPageByIndex (line 879) | @Override
method getCurrentIndex (line 889) | @Override
method setCurrentIndex (line 900) | @Override
method getIndexUnder (line 947) | @Override
method getInternalCurrentIndex (line 961) | @Override
class PageFling (line 970) | private class PageFling extends Fling {
method PageFling (line 976) | public PageFling(Context context) {
method startFling (line 980) | public void startFling(int velocityX, int minX, int maxX,
method onCalculate (line 1015) | @Override
method onFinish (line 1029) | @Override
class SmoothScaler (line 1036) | private class SmoothScaler extends Animation {
method SmoothScaler (line 1043) | public SmoothScaler() {
method startSmoothScaler (line 1047) | public void startSmoothScaler(float focusX, float focusY,
method onCalculate (line 1059) | @Override
FILE: app/src/main/java/com/hippo/glgallery/SimpleAdapter.java
class SimpleAdapter (line 25) | public class SimpleAdapter extends GalleryView.Adapter implements Galler...
method SimpleAdapter (line 29) | public SimpleAdapter(@NonNull GLRootView glRootView, @NonNull GalleryP...
method clearUploader (line 34) | public void clearUploader() {
method onBind (line 38) | @Override
method onUnbind (line 48) | @Override
method size (line 55) | @Override
method onDataChanged (line 60) | @Override
method onPageWait (line 65) | @Override
method onPagePercent (line 77) | @Override
method onPageSucceed (line 89) | @Override
method onPageFailed (line 109) | @Override
method onDataChanged (line 121) | @Override
method findPageByIndex (line 129) | private GalleryPageView findPageByIndex(int index) {
FILE: app/src/main/java/com/hippo/glview/anim/AlphaAnimation.java
class AlphaAnimation (line 22) | public class AlphaAnimation extends CanvasAnimation {
method AlphaAnimation (line 27) | public AlphaAnimation(float from, float to) {
method apply (line 33) | @Override
method getCanvasSaveFlags (line 38) | @Override
method onCalculate (line 43) | @Override
FILE: app/src/main/java/com/hippo/glview/anim/Animation.java
class Animation (line 49) | abstract public class Animation {
method setInterpolator (line 75) | public void setInterpolator(Interpolator interpolator) {
method setDuration (line 79) | public void setDuration(long duration) {
method setRepeatCount (line 83) | public void setRepeatCount(int repeatCount) {
method isRunning (line 87) | public boolean isRunning() {
method getLastFrameTime (line 91) | public long getLastFrameTime() {
method start (line 95) | public void start() {
method startAt (line 103) | public void startAt(long time) {
method startNow (line 108) | public void startNow() {
method setStartTime (line 113) | public void setStartTime(long time) {
method cancel (line 117) | public void cancel() {
method reset (line 121) | public void reset() {
method calculate (line 127) | public boolean calculate(long currentTimeMillis) {
method onCalculate (line 155) | abstract protected void onCalculate(float progress);
method onFinish (line 157) | protected void onFinish() {
FILE: app/src/main/java/com/hippo/glview/anim/CanvasAnimation.java
class CanvasAnimation (line 21) | public abstract class CanvasAnimation extends Animation {
method getCanvasSaveFlags (line 22) | public abstract int getCanvasSaveFlags();
method apply (line 24) | public abstract void apply(GLCanvas canvas);
FILE: app/src/main/java/com/hippo/glview/anim/FloatAnimation.java
class FloatAnimation (line 21) | public class FloatAnimation extends Animation {
method setRange (line 26) | public void setRange(float from, float to) {
method onCalculate (line 31) | @Override
method get (line 36) | public float get() {
FILE: app/src/main/java/com/hippo/glview/glrenderer/BasicTexture.java
class BasicTexture (line 29) | public abstract class BasicTexture implements Texture {
method BasicTexture (line 49) | protected BasicTexture(GLCanvas canvas, int id, int state) {
method BasicTexture (line 58) | protected BasicTexture() {
method inFinalizer (line 65) | public static boolean inFinalizer() {
method yieldAllTextures (line 69) | public static void yieldAllTextures() {
method invalidateAllTextures (line 77) | public static void invalidateAllTextures() {
method setAssociatedCanvas (line 86) | protected void setAssociatedCanvas(GLCanvas canvas) {
method setSize (line 94) | public void setSize(int width, int height) {
method isFlippedVertically (line 105) | public boolean isFlippedVertically() {
method getId (line 109) | public int getId() {
method getWidth (line 113) | @Override
method getHeight (line 118) | @Override
method getTextureWidth (line 124) | public int getTextureWidth() {
method getTextureHeight (line 129) | public int getTextureHeight() {
method hasBorder (line 144) | public boolean hasBorder() {
method setBorder (line 148) | protected void setBorder(boolean hasBorder) {
method draw (line 152) | @Override
method draw (line 157) | @Override
method draw (line 162) | @Override
method onBind (line 169) | abstract protected boolean onBind(GLCanvas canvas);
method getTarget (line 172) | abstract protected int getTarget();
method isLoaded (line 174) | public boolean isLoaded() {
method recycle (line 180) | public void recycle() {
method yield (line 189) | public void yield() {
method freeResource (line 193) | private void freeResource() {
method finalize (line 203) | @Override
FILE: app/src/main/java/com/hippo/glview/glrenderer/CanvasTexture.java
class CanvasTexture (line 26) | abstract class CanvasTexture extends UploadedTexture {
method CanvasTexture (line 29) | public CanvasTexture(int width, int height) {
method onGetBitmap (line 35) | @Override
method onFreeBitmap (line 43) | @Override
method onDraw (line 50) | abstract protected void onDraw(Canvas canvas, Bitmap backing);
FILE: app/src/main/java/com/hippo/glview/glrenderer/GLCanvas.java
type GLCanvas (line 29) | public interface GLCanvas {
method getGLId (line 34) | GLId getGLId();
method setSize (line 41) | void setSize(int width, int height);
method clearBuffer (line 44) | void clearBuffer();
method clearBuffer (line 46) | void clearBuffer(float[] argb);
method getAlpha (line 48) | float getAlpha();
method setAlpha (line 51) | void setAlpha(float alpha);
method multiplyAlpha (line 54) | void multiplyAlpha(float alpha);
method translate (line 57) | void translate(float x, float y, float z);
method translate (line 59) | void translate(float x, float y);
method scale (line 61) | void scale(float sx, float sy, float sz);
method rotate (line 63) | void rotate(float angle, float x, float y, float z);
method multiplyMatrix (line 65) | void multiplyMatrix(float[] mMatrix, int offset);
method save (line 69) | void save();
method save (line 72) | void save(int saveFlags);
method restore (line 78) | void restore();
method drawLine (line 82) | void drawLine(float x1, float y1, float x2, float y2, GLPaint paint);
method drawRect (line 86) | void drawRect(float x1, float y1, float x2, float y2, GLPaint paint);
method drawOval (line 90) | void drawOval(float cx, float cy, float radiusX, float radiusY,
method drawArc (line 94) | void drawArc(float cx, float cy, float radiusX, float radiusY,
method fillRect (line 98) | void fillRect(float x, float y, float width, float height, int color);
method fillOval (line 101) | void fillOval(float cx, float cy, float radiusX, float radiusY, int co...
method fillSector (line 104) | void fillSector(float cx, float cy, float radiusX, float radiusY, floa...
method drawTexture (line 107) | void drawTexture(BasicTexture texture, int x, int y, int width, int he...
method drawMesh (line 109) | void drawMesh(BasicTexture tex, int x, int y, int xyBuffer, int uvBuff...
method drawTexture (line 112) | void drawTexture(BasicTexture texture, RectF source, RectF target);
method drawTexture (line 115) | void drawTexture(BasicTexture texture, float[] mTextureTransform, int ...
method drawMixed (line 120) | void drawMixed(BasicTexture from, int toColor, float ratio, int x, int...
method drawMixed (line 126) | void drawMixed(BasicTexture from, int toColor, float ratio, RectF src,...
method unloadTexture (line 132) | boolean unloadTexture(BasicTexture texture);
method deleteBuffer (line 135) | void deleteBuffer(int bufferId);
method deleteRecycledResources (line 139) | void deleteRecycledResources();
method dumpStatisticsAndClear (line 142) | void dumpStatisticsAndClear();
method beginRenderTarget (line 144) | void beginRenderTarget(RawTexture texture);
method endRenderTarget (line 146) | void endRenderTarget();
method setTextureParameters (line 156) | void setTextureParameters(BasicTexture texture);
method initializeTextureSize (line 165) | void initializeTextureSize(BasicTexture texture, int format, int type);
method initializeTexture (line 173) | void initializeTexture(BasicTexture texture, Bitmap bitmap);
method texSubImage2D (line 186) | void texSubImage2D(BasicTexture texture, int xOffset, int yOffset, Bit...
method uploadBuffer (line 194) | int uploadBuffer(java.nio.FloatBuffer buffer);
method uploadBuffer (line 202) | int uploadBuffer(java.nio.ByteBuffer buffer);
method recoverFromLightCycle (line 208) | void recoverFromLightCycle();
method getBounds (line 221) | void getBounds(Rect bounds, int x, int y, int width, int height);
FILE: app/src/main/java/com/hippo/glview/glrenderer/GLES11Canvas.java
class GLES11Canvas (line 43) | public class GLES11Canvas implements GLCanvas {
method GLES11Canvas (line 132) | public GLES11Canvas(GL11 gl) {
method allocateDirectNativeOrderBuffer (line 160) | private static ByteBuffer allocateDirectNativeOrderBuffer(int size) {
method convertCoordinate (line 167) | private static void convertCoordinate(RectF source, RectF target,
method isMatrixRotatedOrFlipped (line 194) | private static boolean isMatrixRotatedOrFlipped(float[] matrix) {
method checkFramebufferStatus (line 202) | private static void checkFramebufferStatus(GL11ExtensionPack gl11ep) {
method setSize (line 225) | @Override
method getAlpha (line 251) | @Override
method setAlpha (line 256) | @Override
method multiplyAlpha (line 261) | @Override
method drawRect (line 266) | @Override
method drawLine (line 284) | @Override
method drawOval (line 302) | @Override
method drawArc (line 309) | @Override
method fillRect (line 316) | @Override
method fillOval (line 332) | @Override
method fillSector (line 348) | @Override
method translate (line 371) | @Override
method translate (line 379) | @Override
method scale (line 388) | @Override
method rotate (line 393) | @Override
method multiplyMatrix (line 402) | @Override
method textureRect (line 409) | private void textureRect(float x, float y, float width, float height) {
method drawMesh (line 423) | @Override
method mapPoints (line 462) | private float[] mapPoints(float[] m, int x1, int y1, int x2, int y2) {
method drawBoundTexture (line 482) | private void drawBoundTexture(
method drawTexture (line 514) | @Override
method drawTexture (line 520) | private void drawTexture(BasicTexture texture,
method drawTexture (line 531) | @Override
method drawTexture (line 550) | @Override
method drawMixed (line 561) | @Override
method notBindTexture (line 567) | private boolean notBindTexture(BasicTexture texture) {
method setTextureColor (line 575) | private void setTextureColor(float r, float g, float b, float alpha) {
method setMixedColor (line 583) | private void setMixedColor(int toColor, float ratio, float alpha) {
method drawMixed (line 624) | @Override
method drawMixed (line 659) | private void drawMixed(BasicTexture from, int toColor,
method clearBuffer (line 683) | @Override
method clearBuffer (line 693) | @Override
method setTextureCoords (line 698) | private void setTextureCoords(RectF source) {
method setTextureCoords (line 702) | private void setTextureCoords(float left, float top,
method setTextureCoords (line 715) | private void setTextureCoords(float[] mTextureTransform) {
method unloadTexture (line 723) | @Override
method deleteBuffer (line 732) | @Override
method deleteRecycledResources (line 739) | @Override
method save (line 756) | @Override
method save (line 761) | @Override
method restore (line 780) | @Override
method freeRestoreConfig (line 789) | private void freeRestoreConfig(ConfigState action) {
method obtainRestoreConfig (line 794) | private ConfigState obtainRestoreConfig() {
method dumpStatisticsAndClear (line 803) | @Override
method saveTransform (line 818) | private void saveTransform() {
method restoreTransform (line 822) | private void restoreTransform() {
method setRenderTarget (line 826) | private void setRenderTarget(RawTexture texture) {
method endRenderTarget (line 856) | @Override
method beginRenderTarget (line 864) | @Override
method setTextureParameters (line 871) | @Override
method initializeTextureSize (line 893) | @Override
method initializeTexture (line 902) | @Override
method texSubImage2D (line 909) | @Override
method uploadBuffer (line 917) | @Override
method uploadBuffer (line 922) | @Override
method uploadBuffer (line 927) | private int uploadBuffer(Buffer buf, int elementSize) {
method recoverFromLightCycle (line 937) | @Override
method getBounds (line 942) | @Override
method getGLId (line 947) | @Override
class GLState (line 952) | private static class GLState {
method GLState (line 960) | public GLState(GL11 gl) {
method setTexEnvMode (line 986) | public void setTexEnvMode(int mode) {
method setLineWidth (line 992) | public void setLineWidth(float width) {
method setTextureAlpha (line 998) | public void setTextureAlpha(float alpha) {
method setColorMode (line 1011) | public void setColorMode(int color, float alpha) {
method setTextureTarget (line 1029) | public void setTextureTarget(int target) {
method setBlendEnabled (line 1040) | public void setBlendEnabled(boolean enabled) {
class ConfigState (line 1051) | private static class ConfigState {
method restore (line 1056) | public void restore(GLES11Canvas canvas) {
FILE: app/src/main/java/com/hippo/glview/glrenderer/GLES11IdImpl.java
class GLES11IdImpl (line 26) | public class GLES11IdImpl implements GLId {
method generateTexture (line 31) | @Override
method glGenBuffers (line 38) | @Override
method glDeleteTextures (line 47) | @Override
method glDeleteBuffers (line 54) | @Override
method glDeleteFramebuffers (line 61) | @Override
FILE: app/src/main/java/com/hippo/glview/glrenderer/GLES20Canvas.java
class GLES20Canvas (line 39) | public class GLES20Canvas implements GLCanvas {
method GLES20Canvas (line 216) | public GLES20Canvas() {
method createBuffer (line 240) | private static FloatBuffer createBuffer(float[] values) {
method loadShader (line 249) | private static int loadShader(int type, String shaderCode) {
method copyTextureCoordinates (line 263) | private static void copyTextureCoordinates(BasicTexture texture, RectF...
method convertCoordinate (line 280) | private static void convertCoordinate(RectF source, RectF target, Basi...
method checkFramebufferStatus (line 304) | private static void checkFramebufferStatus() {
method checkError (line 321) | public static void checkError() {
method printMatrix (line 329) | @SuppressWarnings("unused")
method assembleProgram (line 342) | private int assembleProgram(int vertexShader, int fragmentShader, Shad...
method setSize (line 368) | @Override
method clearBuffer (line 384) | @Override
method clearBuffer (line 392) | @Override
method getAlpha (line 400) | @Override
method setAlpha (line 405) | @Override
method multiplyAlpha (line 410) | @Override
method translate (line 415) | @Override
method translate (line 423) | @Override
method scale (line 433) | @Override
method rotate (line 438) | @Override
method multiplyMatrix (line 451) | @Override
method save (line 460) | @Override
method save (line 465) | @Override
method restore (line 488) | @Override
method drawLine (line 501) | @Override
method drawRect (line 508) | @Override
method drawOval (line 514) | @Override
method drawArc (line 521) | @Override
method draw (line 529) | private void draw(int type, int offset, int count, float x, float y, f...
method draw (line 534) | private void draw(int type, int offset, int count, float x, float y, f...
method prepareDraw (line 540) | private void prepareDraw(int offset, int color, float lineWidth) {
method getColor (line 560) | private float[] getColor(int color) {
method enableBlending (line 572) | private void enableBlending(boolean enableBlending) {
method setPosition (line 582) | private void setPosition(ShaderParameter[] params, int offset) {
method draw (line 592) | private void draw(ShaderParameter[] params, int type, int count, float...
method setMatrix (line 604) | private void setMatrix(ShaderParameter[] params, float x, float y, flo...
method fillRect (line 612) | @Override
method fillOval (line 619) | @Override
method fillSector (line 626) | @Override
method drawTexture (line 640) | @Override
method drawTexture (line 651) | @Override
method drawTexture (line 663) | @Override
method drawTextureRect (line 673) | private void drawTextureRect(BasicTexture texture, RectF source, RectF...
method setTextureMatrix (line 678) | private void setTextureMatrix(RectF source) {
method drawTextureRect (line 685) | private void drawTextureRect(BasicTexture texture, float[] textureMatr...
method prepareTexture (line 705) | private void prepareTexture(BasicTexture texture, int program, ShaderP...
method drawMesh (line 720) | @Override
method drawMixed (line 762) | @Override
method drawMixed (line 769) | @Override
method unloadTexture (line 792) | @Override
method deleteBuffer (line 803) | @Override
method deleteRecycledResources (line 810) | @Override
method dumpStatisticsAndClear (line 827) | @Override
method endRenderTarget (line 838) | @Override
method beginRenderTarget (line 847) | @Override
method getTargetTexture (line 855) | private RawTexture getTargetTexture() {
method setRenderTarget (line 860) | private void setRenderTarget(BasicTexture oldTexture, RawTexture textu...
method setTextureParameters (line 890) | @Override
method initializeTextureSize (line 901) | @Override
method initializeTexture (line 911) | @Override
method texSubImage2D (line 919) | @Override
method uploadBuffer (line 928) | @Override
method uploadBuffer (line 933) | @Override
method uploadBuffer (line 938) | private int uploadBuffer(Buffer buffer, int elementSize) {
method recoverFromLightCycle (line 950) | @Override
method getBounds (line 958) | @Override
method getGLId (line 971) | @Override
class ShaderParameter (line 976) | private abstract static class ShaderParameter {
method ShaderParameter (line 980) | public ShaderParameter(String name) {
method loadHandle (line 984) | public abstract void loadHandle(int program);
class UniformShaderParameter (line 987) | private static class UniformShaderParameter extends ShaderParameter {
method UniformShaderParameter (line 988) | public UniformShaderParameter(String name) {
method loadHandle (line 992) | @Override
class AttributeShaderParameter (line 999) | private static class AttributeShaderParameter extends ShaderParameter {
method AttributeShaderParameter (line 1000) | public AttributeShaderParameter(String name) {
method loadHandle (line 1004) | @Override
FILE: app/src/main/java/com/hippo/glview/glrenderer/GLES20IdImpl.java
class GLES20IdImpl (line 26) | public class GLES20IdImpl implements GLId {
method generateTexture (line 29) | @Override
method glGenBuffers (line 36) | @Override
method glDeleteTextures (line 42) | @Override
method glDeleteBuffers (line 48) | @Override
method glDeleteFramebuffers (line 54) | @Override
FILE: app/src/main/java/com/hippo/glview/glrenderer/GLId.java
type GLId (line 23) | public interface GLId {
method generateTexture (line 24) | int generateTexture();
method glGenBuffers (line 26) | void glGenBuffers(int n, int[] buffers, int offset);
method glDeleteTextures (line 28) | void glDeleteTextures(GL11 gl, int n, int[] textures, int offset);
method glDeleteBuffers (line 30) | void glDeleteBuffers(GL11 gl, int n, int[] buffers, int offset);
method glDeleteFramebuffers (line 32) | void glDeleteFramebuffers(GL11ExtensionPack gl11ep, int n, int[] buffe...
FILE: app/src/main/java/com/hippo/glview/glrenderer/GLPaint.java
class GLPaint (line 19) | public class GLPaint {
method getColor (line 24) | public int getColor() {
method setColor (line 28) | public void setColor(int color) {
method getBackgroundColor (line 32) | public int getBackgroundColor() {
method setBackgroundColor (line 36) | public void setBackgroundColor(int backgroundColor) {
method getLineWidth (line 40) | public float getLineWidth() {
method setLineWidth (line 44) | public void setLineWidth(float width) {
FILE: app/src/main/java/com/hippo/glview/glrenderer/MovableTextTexture.java
class MovableTextTexture (line 35) | public final class MovableTextTexture extends SpriteTexture {
method MovableTextTexture (line 41) | private MovableTextTexture(Bitmap bitmap, int count, int[] rects, char...
method create (line 58) | public static MovableTextTexture create(Typeface typeface, int size, i...
method getTextIndexes (line 117) | public int[] getTextIndexes(String text) {
method getTextWidth (line 128) | public float getTextWidth(String text) {
method getTextWidth (line 143) | public float getTextWidth(int[] indexes) {
method getMaxWidth (line 156) | public float getMaxWidth() {
method getTextHeight (line 160) | public float getTextHeight() {
method drawText (line 164) | public void drawText(GLCanvas canvas, String text, int x, int y) {
method drawText (line 177) | public void drawText(GLCanvas canvas, int[] indexes, int x, int y) {
FILE: app/src/main/java/com/hippo/glview/glrenderer/NativeTexture.java
class NativeTexture (line 24) | public abstract class NativeTexture extends BasicTexture {
method checkError (line 31) | public static void checkError() {
method invalidateContent (line 39) | public void invalidateContent() {
method texImage (line 43) | protected abstract void texImage(boolean init);
method uploadToCanvas (line 45) | private void uploadToCanvas(GLCanvas canvas) {
method updateContent (line 63) | public void updateContent(GLCanvas canvas) {
method isContentValid (line 79) | public boolean isContentValid() {
method onBind (line 83) | @Override
method getTarget (line 89) | @Override
method isOpaque (line 94) | @Override
method setOpaque (line 99) | public void setOpaque(boolean isOpaque) {
FILE: app/src/main/java/com/hippo/glview/glrenderer/RawTexture.java
class RawTexture (line 23) | public class RawTexture extends BasicTexture {
method RawTexture (line 29) | public RawTexture(int width, int height, boolean opaque) {
method isOpaque (line 34) | @Override
method isFlippedVertically (line 39) | @Override
method setIsFlippedVertically (line 44) | public void setIsFlippedVertically(boolean isFlipped) {
method prepare (line 48) | protected void prepare(GLCanvas canvas) {
method onBind (line 57) | @Override
method yield (line 64) | @Override
method getTarget (line 69) | @Override
FILE: app/src/main/java/com/hippo/glview/glrenderer/SpriteTexture.java
class SpriteTexture (line 26) | public class SpriteTexture extends TiledTexture {
method SpriteTexture (line 33) | public SpriteTexture(Bitmap bitmap, boolean isOpaque, int count, int[]...
method getCount (line 41) | public int getCount() {
method drawSprite (line 45) | public void drawSprite(GLCanvas canvas, int index, int x, int y) {
method drawSprite (line 57) | public void drawSprite(GLCanvas canvas, int index, int x, int y, int w...
method drawSpriteMixed (line 67) | public void drawSpriteMixed(GLCanvas canvas, int index, int color, flo...
method drawSpriteMixed (line 79) | public void drawSpriteMixed(GLCanvas canvas, int index, int color, flo...
FILE: app/src/main/java/com/hippo/glview/glrenderer/StringTexture.java
class StringTexture (line 31) | public class StringTexture extends CanvasTexture {
method StringTexture (line 36) | private StringTexture(String text, TextPaint paint,
method getDefaultPaint (line 44) | public static TextPaint getDefaultPaint(float textSize, int color) {
method newInstance (line 53) | public static StringTexture newInstance(
method newInstance (line 58) | public static StringTexture newInstance(
method newInstance (line 72) | private static StringTexture newInstance(String text, TextPaint paint) {
method onDraw (line 82) | @Override
FILE: app/src/main/java/com/hippo/glview/glrenderer/Texture.java
type Texture (line 35) | public interface Texture {
method getWidth (line 36) | int getWidth();
method getHeight (line 38) | int getHeight();
method draw (line 40) | void draw(GLCanvas canvas, int x, int y);
method draw (line 42) | void draw(GLCanvas canvas, int x, int y, int w, int h);
method draw (line 44) | void draw(GLCanvas canvas, RectF source, RectF target);
method isOpaque (line 46) | boolean isOpaque();
FILE: app/src/main/java/com/hippo/glview/glrenderer/TiledTexture.java
class TiledTexture (line 37) | public class TiledTexture implements Texture {
method TiledTexture (line 71) | public TiledTexture(Bitmap bitmap, boolean isOpaque) {
method freeTile (line 92) | private static void freeTile(Tile tile) {
method obtainTile (line 101) | private static Tile obtainTile() {
method mapRect (line 124) | private static void mapRect(RectF output,
method uploadNextTile (line 133) | private boolean uploadNextTile(GLCanvas canvas) {
method isReady (line 155) | public boolean isReady() {
method recycle (line 160) | public void recycle() {
method drawMixed (line 170) | public void drawMixed(GLCanvas canvas, int color, float ratio,
method drawMixed (line 186) | public void drawMixed(GLCanvas canvas, int color, float ratio,
method draw (line 209) | @Override
method draw (line 226) | @Override
method getWidth (line 249) | @Override
method getHeight (line 254) | @Override
method draw (line 259) | @Override
method isOpaque (line 264) | @Override
class Uploader (line 269) | public static class Uploader implements GLRoot.OnGLIdleListener {
method Uploader (line 276) | public Uploader(GLRoot glRoot) {
method clear (line 280) | public synchronized void clear() {
method addTexture (line 284) | public synchronized void addTexture(TiledTexture t) {
method onGLIdle (line 293) | @Override
class Tile (line 315) | private static class Tile extends UploadedTexture {
method setSize (line 323) | @Override
method onGetBitmap (line 333) | @Override
method onFreeBitmap (line 357) | @Override
FILE: app/src/main/java/com/hippo/glview/glrenderer/UploadedTexture.java
class UploadedTexture (line 43) | public abstract class UploadedTexture extends BasicTexture {
method UploadedTexture (line 62) | protected UploadedTexture() {
method UploadedTexture (line 66) | protected UploadedTexture(boolean hasBorder) {
method getBorderLine (line 74) | private static Bitmap getBorderLine(
method resetUploadLimit (line 90) | public static void resetUploadLimit() {
method uploadLimitReached (line 94) | public static boolean uploadLimitReached() {
method setIsUploading (line 98) | protected void setIsUploading(boolean uploading) {
method isUploading (line 102) | public boolean isUploading() {
method setThrottled (line 106) | protected void setThrottled(boolean throttled) {
method getBitmap (line 110) | private Bitmap getBitmap() {
method freeBitmap (line 122) | private void freeBitmap() {
method getWidth (line 130) | @Override
method getHeight (line 136) | @Override
method onGetBitmap (line 142) | protected abstract Bitmap onGetBitmap();
method onFreeBitmap (line 144) | protected abstract void onFreeBitmap(Bitmap bitmap);
method invalidateContent (line 146) | public void invalidateContent() {
method isContentValid (line 156) | public boolean isContentValid() {
method updateContent (line 165) | public void updateContent(GLCanvas canvas) {
method uploadToCanvas (line 181) | private void uploadToCanvas(GLCanvas canvas) {
method onBind (line 243) | @Override
method getTarget (line 249) | @Override
method isOpaque (line 254) | @Override
method setOpaque (line 259) | public void setOpaque(boolean isOpaque) {
method recycle (line 263) | @Override
class BorderKey (line 269) | private static class BorderKey implements Cloneable {
method hashCode (line 274) | @Override
method equals (line 280) | @Override
method clone (line 287) | @NonNull
FILE: app/src/main/java/com/hippo/glview/image/GLImageMovableTextView.java
class GLImageMovableTextView (line 26) | public class GLImageMovableTextView extends GLView {
method generateIndexes (line 34) | private void generateIndexes() {
method setTextTexture (line 42) | public void setTextTexture(ImageMovableTextTexture textTexture) {
method setText (line 52) | public void setText(String text) {
method setGravity (line 65) | public void setGravity(int gravity) {
method getSuggestedMinimumWidth (line 72) | @Override
method getSuggestedMinimumHeight (line 82) | @Override
method onRender (line 92) | @Override
FILE: app/src/main/java/com/hippo/glview/image/ImageMovableTextTexture.java
class ImageMovableTextTexture (line 32) | public class ImageMovableTextTexture extends ImageSpriteTexture {
method ImageMovableTextTexture (line 38) | public ImageMovableTextTexture(@NonNull ImageWrapper image, int count,...
method create (line 56) | @Nullable
method getTextIndexes (line 122) | public int[] getTextIndexes(String text) {
method getTextWidth (line 133) | public float getTextWidth(String text) {
method getTextWidth (line 148) | public float getTextWidth(int[] indexes) {
method getMaxWidth (line 161) | public float getMaxWidth() {
method getTextHeight (line 165) | public float getTextHeight() {
method drawText (line 169) | public void drawText(GLCanvas canvas, String text, int x, int y) {
method drawText (line 182) | public void drawText(GLCanvas canvas, int[] indexes, int x, int y) {
FILE: app/src/main/java/com/hippo/glview/image/ImageSpriteTexture.java
class ImageSpriteTexture (line 26) | public class ImageSpriteTexture extends ImageTexture {
method ImageSpriteTexture (line 33) | public ImageSpriteTexture(@NonNull ImageWrapper image, int count, int[...
method getCount (line 41) | public int getCount() {
method drawSprite (line 45) | public void drawSprite(GLCanvas canvas, int index, int x, int y) {
method drawSprite (line 57) | public void drawSprite(GLCanvas canvas, int index, int x, int y, int w...
method drawSpriteMixed (line 67) | public void drawSpriteMixed(GLCanvas canvas, int index, int color, flo...
method drawSpriteMixed (line 79) | public void drawSpriteMixed(GLCanvas canvas, int index, int color, flo...
FILE: app/src/main/java/com/hippo/glview/image/ImageTexture.java
class ImageTexture (line 43) | public class ImageTexture implements Texture, Animatable {
method ImageTexture (line 88) | public ImageTexture(@NonNull ImageWrapper image) {
method obtainSmallTile (line 151) | private static Tile obtainSmallTile() {
method obtainLargeTile (line 164) | private static Tile obtainLargeTile() {
method mapRect (line 190) | private static void mapRect(RectF output,
method getCallback (line 199) | public Callback getCallback() {
method setCallback (line 206) | public final void setCallback(Callback cb) {
method invalidateSelf (line 210) | public void invalidateSelf() {
method start (line 217) | @Override
method stop (line 250) | @Override
method isRunning (line 256) | @Override
method uploadNextTile (line 261) | private boolean uploadNextTile(GLCanvas canvas) {
method getWidth (line 283) | @Override
method getHeight (line 288) | @Override
method syncFrame (line 293) | private void syncFrame() {
method draw (line 303) | @Override
method draw (line 309) | @Override
method draw (line 327) | @Override
method drawMixed (line 353) | public void drawMixed(GLCanvas canvas, int color, float ratio,
method drawMixed (line 370) | public void drawMixed(GLCanvas canvas, int color, float ratio,
method isOpaque (line 394) | @Override
method isReady (line 399) | public boolean isReady() {
method recycle (line 403) | public void recycle() {
type Callback (line 438) | public interface Callback {
method invalidateImageTexture (line 439) | void invalidateImageTexture(ImageTexture who);
class Uploader (line 442) | public static class Uploader implements GLRoot.OnGLIdleListener {
method Uploader (line 449) | public Uploader(GLRoot glRoot) {
method clear (line 453) | public synchronized void clear() {
method addTexture (line 457) | public synchronized void addTexture(ImageTexture t) {
method onGLIdle (line 466) | @Override
class Tile (line 488) | private static class Tile extends NativeTexture {
method freeSmallTile (line 499) | private static void freeSmallTile(Tile tile) {
method freeLargeTile (line 507) | private static void freeLargeTile(Tile tile) {
method setSize (line 515) | public void setSize(@TileType int tileType, int width, int height) {
method texImage (line 536) | @Override
method invalidate (line 551) | private void invalidate() {
method free (line 556) | public void free() {
class AnimateRunnable (line 570) | private class AnimateRunnable implements Runnable {
method run (line 571) | @Override
method prepareAnimation (line 586) | private boolean prepareAnimation() {
method runAnimationLoop (line 604) | private void runAnimationLoop() {
method shouldContinueAnimation (line 636) | private boolean shouldContinueAnimation() {
method setImageBusy (line 642) | private void setImageBusy(boolean busy) {
method performReleaseIfNeeded (line 648) | private void performReleaseIfNeeded() {
FILE: app/src/main/java/com/hippo/glview/image/ImageWrapper.java
class ImageWrapper (line 30) | public class ImageWrapper {
method ImageWrapper (line 42) | public ImageWrapper(@NonNull Image image) {
method setCutRect (line 51) | public void setCutRect(int left, int top, int right, int bottom) {
method setCutPercent (line 69) | public void setCutPercent(float left, float top, float right, float bo...
method obtain (line 79) | public synchronized boolean obtain() {
method release (line 91) | public synchronized void release() {
method isImageRecycled (line 98) | public boolean isImageRecycled() {
method getAnimated (line 105) | public Boolean getAnimated() {
method getWidth (line 112) | public int getWidth() {
method getHeight (line 119) | public int getHeight() {
method setFrameUpdateAllowed (line 126) | public void setFrameUpdateAllowed(boolean allowed) {
method texImage (line 133) | public void texImage(boolean init, int offsetX, int offsetY, int width...
method start (line 140) | public void start() {
method getDelay (line 147) | public int getDelay() {
method isOpaque (line 154) | public boolean isOpaque() {
method isRecycled (line 161) | public boolean isRecycled() {
FILE: app/src/main/java/com/hippo/glview/util/GalleryUtils.java
class GalleryUtils (line 26) | public class GalleryUtils {
method intColorToFloatARGBArray (line 29) | public static float[] intColorToFloatARGBArray(int from) {
method floatARGBArrayTointColor (line 41) | public static int floatARGBArrayTointColor(float[] from) {
method setRenderThread (line 45) | public static void setRenderThread() {
method isRenderThread (line 49) | public static boolean isRenderThread() {
method assertInRenderThread (line 53) | public static void assertInRenderThread() {
FILE: app/src/main/java/com/hippo/glview/view/AnimationTime.java
class AnimationTime (line 27) | public class AnimationTime {
method update (line 31) | public static void update() {
method get (line 36) | public static long get() {
method startTime (line 40) | public static long startTime() {
FILE: app/src/main/java/com/hippo/glview/view/GLRoot.java
type GLRoot (line 25) | public interface GLRoot {
method addOnGLIdleListener (line 26) | void addOnGLIdleListener(OnGLIdleListener listener);
method registerLaunchedAnimation (line 28) | void registerLaunchedAnimation(CanvasAnimation animation);
method requestRenderForced (line 30) | void requestRenderForced();
method requestRender (line 32) | void requestRender();
method requestLayoutContentPane (line 34) | void requestLayoutContentPane();
method lockRenderThread (line 36) | void lockRenderThread();
method unlockRenderThread (line 38) | void unlockRenderThread();
method setContentPane (line 40) | void setContentPane(GLView content);
method setOrientationSource (line 42) | void setOrientationSource(OrientationSource source);
method getDisplayRotation (line 44) | int getDisplayRotation();
method getCompensation (line 46) | int getCompensation();
method getCompensationMatrix (line 48) | Matrix getCompensationMatrix();
method freeze (line 50) | void freeze();
method unfreeze (line 52) | void unfreeze();
method setLightsOutMode (line 54) | void setLightsOutMode(boolean enabled);
method getContext (line 56) | Context getContext();
method getWidth (line 58) | int getWidth();
method getHeight (line 60) | int getHeight();
type OnGLIdleListener (line 64) | interface OnGLIdleListener {
method onGLIdle (line 65) | boolean onGLIdle(GLCanvas canvas, boolean renderRequested);
FILE: app/src/main/java/com/hippo/glview/view/GLRootView.java
class GLRootView (line 65) | public class GLRootView extends GLSurfaceView
method GLRootView (line 103) | public GLRootView(Context context) {
method GLRootView (line 107) | @SuppressWarnings("deprecation")
method registerLaunchedAnimation (line 122) | @Override
method addOnGLIdleListener (line 131) | @Override
method setContentPane (line 142) | @Override
method requestRenderForced (line 164) | @Override
method requestRender (line 169) | @Override
method superRequestRender (line 181) | private void superRequestRender() {
method requestLayoutContentPane (line 185) | @Override
method layoutContentPane (line 202) | private void layoutContentPane() {
method onLayout (line 249) | @Override
method outputFps (line 255) | private void outputFps() {
method onDrawFrameLocked (line 268) | private void onDrawFrameLocked() {
method rotateCanvas (line 320) | private void rotateCanvas(int degrees) {
method dispatchTouchEvent (line 335) | @Override
method lockRenderThread (line 366) | @Override
method unlockRenderThread (line 371) | @Override
method onPause (line 376) | @Override
method onResume (line 385) | @Override
method setOrientationSource (line 393) | @Override
method getDisplayRotation (line 398) | @Override
method getCompensation (line 403) | @Override
method getCompensationMatrix (line 408) | @Override
method freeze (line 413) | @Override
method unfreeze (line 420) | @Override
method setLightsOutMode (line 428) | @Override
method surfaceChanged (line 441) | @Override
method surfaceCreated (line 447) | @Override
method surfaceDestroyed (line 453) | @Override
method onDetachedFromWindow (line 459) | @Override
method dispatchSaveInstanceState (line 468) | @Override
method dispatchRestoreInstanceState (line 479) | @Override
method finalize (line 487) | @Override
class GLRootRenderer (line 496) | private class GLRootRenderer implements GLSurfaceView.Renderer {
method onSurfaceCreated (line 500) | @Override
method onSurfaceChanged (line 527) | @Override
method onDrawFrame (line 538) | @Override
class IdleRunner (line 565) | private class IdleRunner implements Runnable {
method run (line 569) | @Override
method enable (line 590) | public void enable() {
class ConfigChooser (line 599) | private class ConfigChooser implements EGLConfigChooser {
method chooseConfig (line 602) | @Override
method chooseConfig (line 636) | private EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, EGLCon...
method findConfigAttrib (line 672) | private int findConfigAttrib(EGL10 egl, EGLDisplay display,
class ContextFactory (line 681) | private class ContextFactory implements EGLContextFactory {
method createContext (line 684) | @Override
method destroyContext (line 693) | @Override
FILE: app/src/main/java/com/hippo/glview/view/GLView.java
class GLView (line 53) | public class GLView implements TouchOwner {
method getDefaultBegin (line 134) | public static int getDefaultBegin(int size, int specSize, int paddingB...
method getDefaultSize (line 159) | public static int getDefaultSize(int size, int measureSpec) {
method getMaxSize (line 187) | public static int getMaxSize(int size, int measureSpec) {
method getComponentSpec (line 200) | public static int getComponentSpec(int spec, int childSize) {
method measureComponent (line 258) | public static void measureComponent(GLView component, int widthSpec, i...
method measureAllComponents (line 265) | public static void measureAllComponents(GLView parent, int widthSpec, ...
method startAnimation (line 275) | public void startAnimation(CanvasAnimation animation, boolean atOnce) {
method getVisibility (line 295) | @Visibility
method setVisibility (line 314) | public void setVisibility(@Visibility int visibility) {
method attachToRoot (line 334) | void attachToRoot(GLRoot root) {
method detachFromRoot (line 340) | void detachFromRoot() {
method pause (line 346) | void pause() {
method resume (line 351) | void resume() {
method isAttachedToRoot (line 355) | public boolean isAttachedToRoot() {
method getComponentCount (line 360) | public int getComponentCount() {
method getComponent (line 365) | public GLView getComponent(int index) {
method addComponent (line 373) | public void addComponent(GLView component) {
method addComponent (line 377) | public void addComponent(GLView component, int index) {
method addComponent (line 381) | public void addComponent(GLView component, LayoutParams params) {
method addComponent (line 385) | public void addComponent(GLView component, int index, LayoutParams par...
method removeComponent (line 424) | public void removeComponent(GLView component) {
method removeComponentAt (line 431) | public boolean removeComponentAt(int index) {
method removeAllComponents (line 445) | public void removeAllComponents() {
method removeOneComponent (line 452) | private void removeOneComponent(GLView component) {
method getId (line 470) | public int getId() {
method setId (line 481) | public void setId(int id) {
method bounds (line 485) | public Rect bounds() {
method setHotspot (line 489) | @Override
method getHotspotX (line 495) | public float getHotspotX() {
method getHotspotY (line 499) | public float getHotspotY() {
method isEnabled (line 503) | @Override
method isPressed (line 508) | @Override
method setPressed (line 513) | @Override
method isClickable (line 518) | @Override
method isLongClickable (line 523) | @Override
method performClick (line 528) | @Override
method performLongClick (line 536) | @Override
method setOnClickListener (line 545) | public void setOnClickListener(OnClickListener listener) {
method setOnLongClickListener (line 549) | public void setOnLongClickListener(OnLongClickListener listener) {
method getWidth (line 553) | @Override
method getHeight (line 558) | @Override
method offsetTopAndBottom (line 568) | public void offsetTopAndBottom(int offset) {
method offsetLeftAndRight (line 581) | public void offsetLeftAndRight(int offset) {
method getGLRoot (line 589) | public GLRoot getGLRoot() {
method invalidate (line 595) | public void invalidate() {
method requestLayout (line 601) | public void requestLayout() {
method render (line 614) | public void render(GLCanvas canvas) {
method onRender (line 636) | public void onRender(GLCanvas canvas) {
method setBackgroundColor (line 639) | public void setBackgroundColor(int color) {
method renderChild (line 643) | protected void renderChild(GLCanvas canvas, GLView component) {
method onTouch (line 673) | protected boolean onTouch(MotionEvent event) {
method dispatchTouchEvent (line 680) | protected boolean dispatchTouchEvent(MotionEvent event,
method dispatchTouchEvent (line 696) | protected boolean dispatchTouchEvent(MotionEvent event) {
method saveHierarchyState (line 735) | public void saveHierarchyState(SparseArray<Parcelable> container) {
method dispatchSaveInstanceState (line 739) | protected void dispatchSaveInstanceState(SparseArray<Parcelable> conta...
method onSaveInstanceState (line 751) | protected Parcelable onSaveInstanceState() {
method restoreHierarchyState (line 761) | public void restoreHierarchyState(SparseArray<Parcelable> container) {
method dispatchRestoreInstanceState (line 765) | protected void dispatchRestoreInstanceState(SparseArray<Parcelable> co...
method onRestoreInstanceState (line 777) | protected void onRestoreInstanceState(Parcelable state) {
method setPaddings (line 783) | public void setPaddings(int paddingLeft, int paddingTop, int paddingRi...
method setPaddingLeft (line 787) | public void setPaddingLeft(int paddingLeft) {
method setPaddingTop (line 791) | public void setPaddingTop(int paddingTop) {
method setPaddingRight (line 795) | public void setPaddingRight(int paddingRight) {
method setPaddingBottom (line 799) | public void setPaddingBottom(int paddingBottom) {
method getPaddings (line 803) | public Rect getPaddings() {
method layout (line 812) | public void layout(int left, int top, int right, int bottom) {
method dispatchNotifyPositionInRoot (line 824) | public void dispatchNotifyPositionInRoot() {
method notifyPositionInRoot (line 832) | public boolean notifyPositionInRoot() {
method setBounds (line 856) | private boolean setBounds(int left, int top, int right, int bottom) {
method onSizeChanged (line 873) | protected void onSizeChanged(int newW, int newH, int oldW, int oldH) {
method onPositionInRootChanged (line 876) | protected void onPositionInRootChanged(int x, int y, int oldX, int old...
method getPositionInRoot (line 879) | public void getPositionInRoot(int[] position) {
method getValidRect (line 890) | public void getValidRect(Rect rect) {
method measure (line 908) | public void measure(int widthSpec, int heightSpec) {
method onMeasure (line 930) | protected void onMeasure(int widthSpec, int heightSpec) {
method getSuggestedMinimumHeight (line 935) | protected int getSuggestedMinimumHeight() {
method getSuggestedMinimumWidth (line 939) | protected int getSuggestedMinimumWidth() {
method getMinimumHeight (line 949) | public int getMinimumHeight() {
method setMinimumHeight (line 961) | public void setMinimumHeight(int minHeight) {
method getMinimumWidth (line 972) | public int getMinimumWidth() {
method setMinimumWidth (line 984) | public void setMinimumWidth(int minWidth) {
method setMeasuredSize (line 989) | protected void setMeasuredSize(int width, int height) {
method getMeasuredWidth (line 995) | public int getMeasuredWidth() {
method getMeasuredHeight (line 999) | public int getMeasuredHeight() {
method onLayout (line 1003) | protected void onLayout(
method getLayoutParams (line 1007) | public LayoutParams getLayoutParams() {
method setLayoutParams (line 1011) | public void setLayoutParams(LayoutParams params) {
method checkLayoutParams (line 1023) | protected boolean checkLayoutParams(LayoutParams p) {
method generateDefaultLayoutParams (line 1027) | protected LayoutParams generateDefaultLayoutParams() {
method generateLayoutParams (line 1031) | protected LayoutParams generateLayoutParams(LayoutParams p) {
method getBoundsOf (line 1038) | public boolean getBoundsOf(GLView descendant, Rect out) {
method onVisibilityChanged (line 1054) | protected void onVisibilityChanged(GLView changedView, @Visibility int...
method onAttachToRoot (line 1060) | public void onAttachToRoot(GLRoot root) {
method onDetachFromRoot (line 1067) | public void onDetachFromRoot() {
method onPause (line 1074) | public void onPause() {
method onResume (line 1080) | public void onResume() {
method lockRendering (line 1086) | public void lockRendering() {
method unlockRendering (line 1092) | public void unlockRendering() {
method dumpTree (line 1100) | void dumpTree(String prefix) {
type OnClickListener (line 1112) | public interface OnClickListener {
method onClick (line 1113) | boolean onClick(GLView v);
type OnLongClickListener (line 1116) | public interface OnLongClickListener {
method onLongClick (line 1117) | boolean onLongClick(GLView v);
class MeasureSpec (line 1147) | public static class MeasureSpec {
method makeMeasureSpec (line 1188) | public static int makeMeasureSpec(int size, int mode) {
method getMode (line 1200) | public static int getMode(int measureSpec) {
method getSize (line 1210) | public static int getSize(int measureSpec) {
method toString (line 1221) | public static String toString(int measureSpec) {
class LayoutParams (line 1245) | public static class LayoutParams {
method LayoutParams (line 1281) | public LayoutParams(int width, int height) {
method LayoutParams (line 1291) | public LayoutParams(LayoutParams source) {
class GravityLayoutParams (line 1300) | public static class GravityLayoutParams extends LayoutParams {
method GravityLayoutParams (line 1303) | public GravityLayoutParams(GLView.LayoutParams source) {
method GravityLayoutParams (line 1311) | public GravityLayoutParams(int width, int height) {
FILE: app/src/main/java/com/hippo/glview/view/Gravity.java
class Gravity (line 26) | public class Gravity {
method centerHorizontal (line 43) | public static boolean centerHorizontal(int gravity) {
method right (line 47) | public static boolean right(int gravity) {
method left (line 51) | public static boolean left(int gravity) {
method centerVertical (line 55) | public static boolean centerVertical(int gravity) {
method top (line 59) | public static boolean top(int gravity) {
method bottom (line 63) | public static boolean bottom(int gravity) {
method getPosition (line 67) | public static @PositionMode
FILE: app/src/main/java/com/hippo/glview/view/OrientationSource.java
type OrientationSource (line 19) | public interface OrientationSource {
method getDisplayRotation (line 20) | int getDisplayRotation();
method getCompensation (line 22) | int getCompensation();
FILE: app/src/main/java/com/hippo/glview/view/TouchHelper.java
class TouchHelper (line 28) | public class TouchHelper {
method TouchHelper (line 41) | public TouchHelper(@NonNull TouchOwner owner) {
method initialize (line 45) | public static void initialize(Context context) {
method onTouch (line 49) | public boolean onTouch(MotionEvent event) {
method setPressed (line 151) | private void setPressed(boolean pressed, float x, float y) {
method pointInView (line 164) | public boolean pointInView(float localX, float localY, float slop) {
method removeLongPressCallback (line 172) | private void removeLongPressCallback() {
method removeTapCallback (line 181) | private void removeTapCallback() {
method checkForLongClick (line 188) | private void checkForLongClick(int delayOffset) {
class CheckForLongPress (line 200) | private final class CheckForLongPress implements Runnable {
method run (line 201) | @Override
class CheckForTap (line 211) | private final class CheckForTap implements Runnable {
method run (line 215) | @Override
class PerformClick (line 223) | private final class PerformClick implements Runnable {
method run (line 224) | @Override
class UnsetPressedState (line 230) | private final class UnsetPressedState implements Runnable {
method run (line 231) | @Override
FILE: app/src/main/java/com/hippo/glview/view/TouchOwner.java
type TouchOwner (line 19) | public interface TouchOwner {
method setHotspot (line 20) | void setHotspot(float x, float y);
method isEnabled (line 22) | boolean isEnabled();
method isPressed (line 24) | boolean isPressed();
method setPressed (line 26) | void setPressed(boolean pressed);
method isClickable (line 28) | boolean isClickable();
method isLongClickable (line 30) | boolean isLongClickable();
method performClick (line 32) | void performClick();
method performLongClick (line 34) | boolean performLongClick();
method getWidth (line 36) | int getWidth();
method getHeight (line 38) | int getHeight();
FILE: app/src/main/java/com/hippo/glview/widget/GLFrameLayout.java
class GLFrameLayout (line 22) | public class GLFrameLayout extends GLView {
method onMeasure (line 23) | @Override
method onLayout (line 55) | @Override
method checkLayoutParams (line 92) | @Override
method generateDefaultLayoutParams (line 97) | @Override
method generateLayoutParams (line 102) | @Override
FILE: app/src/main/java/com/hippo/glview/widget/GLLinearLayout.java
class GLLinearLayout (line 31) | public class GLLinearLayout extends GLView {
method setInterval (line 38) | public void setInterval(int interval) {
method setOrientation (line 51) | public void setOrientation(@OrientationMode int orientation) {
method onMeasure (line 58) | @Override
method onLayout (line 157) | @Override
method checkLayoutParams (line 206) | @Override
method generateDefaultLayoutParams (line 211) | @Override
method generateLayoutParams (line 216) | @Override
class LayoutParams (line 226) | public static class LayoutParams extends GravityLayoutParams {
method LayoutParams (line 229) | public LayoutParams(GLView.LayoutParams source) {
method LayoutParams (line 237) | public LayoutParams(int width, int height) {
FILE: app/src/main/java/com/hippo/glview/widget/GLProgressView.java
class GLProgressView (line 36) | public class GLProgressView extends GLView {
method GLProgressView (line 67) | public GLProgressView() {
method setupAnimations (line 76) | public void setupAnimations() {
method startAnimations (line 131) | private void startAnimations() {
method stopAnimations (line 138) | private void stopAnimations() {
method onLayout (line 145) | @Override
method setColor (line 159) | public void setColor(int color) {
method setBgColor (line 164) | public void setBgColor(int color) {
method isIndeterminate (line 169) | public boolean isIndeterminate() {
method setIndeterminate (line 173) | public void setIndeterminate(boolean indeterminate) {
method setProgress (line 185) | public void setProgress(float progress) {
method onRender (line 195) | @Override
method update (line 223) | private void update() {
FILE: app/src/main/java/com/hippo/glview/widget/GLTextureView.java
class GLTextureView (line 25) | public class GLTextureView extends GLView {
method getTexture (line 31) | public Texture getTexture() {
method setTexture (line 35) | public void setTexture(Texture texture) {
method getSuggestedMinimumWidth (line 45) | @Override
method getSuggestedMinimumHeight (line 50) | @Override
method onRender (line 55) | @Override
FILE: app/src/main/java/com/hippo/util/JsoupUtils.java
class JsoupUtils (line 25) | public final class JsoupUtils {
method getElementByClass (line 26) | @Nullable
method getElementByClass (line 37) | @Nullable
method getElementByTag (line 48) | @Nullable
FILE: app/src/main/java/com/hippo/util/LogCat.java
class LogCat (line 24) | public final class LogCat {
method LogCat (line 25) | private LogCat() {
method save (line 28) | public static boolean save(OutputStream outputStream) {
FILE: app/src/main/java/com/hippo/util/SqlUtils.java
class SqlUtils (line 26) | public class SqlUtils {
method exeSQLSafely (line 27) | public static void exeSQLSafely(SQLiteDatabase db, String sql) {
method dropTable (line 35) | public static void dropTable(SQLiteDatabase db, String tableName) {
method dropAllTable (line 39) | public static void dropAllTable(SQLiteDatabase db) {
method sqlEscapeString (line 57) | public static String sqlEscapeString(String value) {
method getBoolean (line 72) | public static boolean getBoolean(Cursor cursor, String column, boolean...
method getInt (line 82) | public static int getInt(Cursor cursor, String column, int defValue) {
method getLong (line 92) | public static long getLong(Cursor cursor, String column, long defValue) {
method getFloat (line 102) | public static float getFloat(Cursor cursor, String column, float defVa...
method getString (line 112) | public static String getString(Cursor cursor, String column, String de...
FILE: app/src/main/java/com/hippo/util/TextUrl.java
class TextUrl (line 26) | public final class TextUrl {
method handleTextUrl (line 29) | public static CharSequence handleTextUrl(CharSequence content) {
FILE: app/src/main/java/com/hippo/view/BringOutTransition.java
class BringOutTransition (line 26) | public class BringOutTransition extends ViewTransition {
method BringOutTransition (line 27) | public BringOutTransition(ContentLayout contentLayout, SearchLayout mS...
method startAnimations (line 31) | @Override
FILE: app/src/main/java/com/hippo/view/ViewTransition.java
class ViewTransition (line 24) | public class ViewTransition {
method ViewTransition (line 33) | public ViewTransition(View... views) {
method setOnShowViewListener (line 47) | public void setOnShowViewListener(OnShowViewListener listener) {
method getShownViewIndex (line 51) | public int getShownViewIndex() {
method showView (line 55) | public boolean showView(int shownView) {
method showView (line 59) | public boolean showView(int shownView, boolean animation) {
method startAnimations (line 104) | protected void startAnimations(final View hiddenView, final View shown...
type OnShowViewListener (line 125) | public interface OnShowViewListener {
method onShowView (line 126) | void onShowView(View hiddenView, View shownView);
FILE: app/src/main/java/com/hippo/widget/AutoWrapLayout.java
class AutoWrapLayout (line 37) | public class AutoWrapLayout extends ViewGroup {
method AutoWrapLayout (line 43) | public AutoWrapLayout(Context context) {
method AutoWrapLayout (line 47) | public AutoWrapLayout(Context context, AttributeSet attrs) {
method AutoWrapLayout (line 51) | public AutoWrapLayout(Context context, AttributeSet attrs, int defStyl...
method getAlignment (line 67) | public Alignment getAlignment() {
method setAlignment (line 71) | public void setAlignment(Alignment baseLine) {
method adjustBaseLine (line 84) | private void adjustBaseLine(int lineHeight, int startIndex, int endInd...
method onMeasure (line 106) | @SuppressLint("DrawAllocation")
method onLayout (line 226) | @Override
method generateLayoutParams (line 238) | @Override
method generateDefaultLayoutParams (line 243) | @Override
method generateLayoutParams (line 248) | @Override
type Alignment (line 253) | public enum Alignment {
method Alignment (line 260) | Alignment(int ni) {
FILE: app/src/main/java/com/hippo/widget/ColorView.java
class ColorView (line 24) | public class ColorView extends View {
method ColorView (line 27) | public ColorView(Context context) {
method ColorView (line 31) | public ColorView(Context context, AttributeSet attrs) {
method ColorView (line 35) | public ColorView(Context context, AttributeSet attrs, int defStyleAttr) {
method setColor (line 39) | public void setColor(int color) {
method onDraw (line 46) | @Override
FILE: app/src/main/java/com/hippo/widget/CuteSpinner.java
class CuteSpinner (line 30) | public class CuteSpinner extends AppCompatSpinner {
method CuteSpinner (line 31) | public CuteSpinner(Context context) {
method CuteSpinner (line 36) | public CuteSpinner(Context context, int mode) {
method CuteSpinner (line 41) | public CuteSpinner(Context context, AttributeSet attrs) {
method CuteSpinner (line 46) | public CuteSpinner(Context context, AttributeSet attrs, int defStyleAt...
method CuteSpinner (line 51) | public CuteSpinner(Context context, AttributeSet attrs, int defStyleAt...
method CuteSpinner (line 56) | public CuteSpinner(Context context, AttributeSet attrs, int defStyleAt...
method init (line 61) | @SuppressLint("CustomViewStyleable")
FILE: app/src/main/java/com/hippo/widget/DateUtils.java
class DateUtils (line 19) | final class DateUtils {
method hasSeconds (line 23) | public static boolean hasSeconds(CharSequence inFormat) {
method hasDesignator (line 27) | public static boolean hasDesignator(CharSequence inFormat, char design...
method skipQuotedText (line 49) | private static int skipQuotedText(CharSequence s, int i, int len) {
FILE: app/src/main/java/com/hippo/widget/DrawerView.java
class DrawerView (line 26) | public class DrawerView extends FrameLayout {
method DrawerView (line 35) | public DrawerView(Context context) {
method DrawerView (line 40) | public DrawerView(Context context, AttributeSet attrs) {
method DrawerView (line 45) | public DrawerView(Context context, AttributeSet attrs, int defStyleAtt...
method init (line 50) | private void init(Context context, AttributeSet attrs) {
method onMeasure (line 60) | @Override
FILE: app/src/main/java/com/hippo/widget/IndicatingListView.java
class IndicatingListView (line 33) | public class IndicatingListView extends ListView {
method IndicatingListView (line 38) | public IndicatingListView(Context context) {
method IndicatingListView (line 43) | public IndicatingListView(Context context, AttributeSet attrs) {
method IndicatingListView (line 48) | public IndicatingListView(Context context, AttributeSet attrs, int def...
method init (line 53) | @SuppressLint("CustomViewStyleable")
method fillTopIndicatorDrawRect (line 66) | private void fillTopIndicatorDrawRect() {
method fillBottomIndicatorDrawRect (line 70) | private void fillBottomIndicatorDrawRect() {
method needShowTopIndicator (line 74) | private boolean needShowTopIndicator() {
method needShowBottomIndicator (line 78) | private boolean needShowBottomIndicator() {
method draw (line 82) | @Override
FILE: app/src/main/java/com/hippo/widget/LinkifyTextView.java
class LinkifyTextView (line 29) | public class LinkifyTextView extends ObservedTextView {
method LinkifyTextView (line 32) | public LinkifyTextView(Context context) {
method LinkifyTextView (line 36) | public LinkifyTextView(Context context, AttributeSet attrs) {
method LinkifyTextView (line 40) | public LinkifyTextView(Context context, AttributeSet attrs, int defSty...
method getCurrentSpan (line 44) | public ClickableSpan getCurrentSpan() {
method clearCurrentSpan (line 48) | public void clearCurrentSpan() {
method onTouchEvent (line 52) | @SuppressLint("ClickableViewAccessibility")
FILE: app/src/main/java/com/hippo/widget/MaxSizeContainer.java
class MaxSizeContainer (line 28) | public class MaxSizeContainer extends ViewGroup {
method MaxSizeContainer (line 32) | public MaxSizeContainer(Context context, AttributeSet attrs) {
method MaxSizeContainer (line 37) | public MaxSizeContainer(Context context, AttributeSet attrs, int defSt...
method init (line 42) | private void init(Context context, AttributeSet attrs) {
method getMeasureSpec (line 53) | private int getMeasureSpec(int measureSpec, int max) {
method onMeasure (line 72) | @Override
method onLayout (line 86) | @Override
FILE: app/src/main/java/com/hippo/widget/ObservedTextView.java
class ObservedTextView (line 24) | public class ObservedTextView extends AppCompatTextView {
method ObservedTextView (line 27) | public ObservedTextView(Context context) {
method ObservedTextView (line 31) | public ObservedTextView(Context context, AttributeSet attrs) {
method ObservedTextView (line 35) | public ObservedTextView(Context context, AttributeSet attrs, int defSt...
method onAttachedToWindow (line 39) | @Override
method onDetachedFromWindow (line 48) | @Override
method setOnWindowAttachListener (line 57) | public void setOnWindowAttachListener(OnWindowAttachListener onWindowA...
type OnWindowAttachListener (line 61) | public interface OnWindowAttachListener {
method onAttachedToWindow (line 62) | void onAttachedToWindow();
method onDetachedFromWindow (line 64) | void onDetachedFromWindow();
FILE: app/src/main/java/com/hippo/widget/RadioGridGroup.java
class RadioGridGroup (line 32) | public class RadioGridGroup extends SimpleGridLayout {
method RadioGridGroup (line 46) | public RadioGridGroup(Context context, AttributeSet attrs) {
method RadioGridGroup (line 51) | public RadioGridGroup(Context context, AttributeSet attrs, int defStyl...
method init (line 56) | private void init(Context context, AttributeSet attrs) {
method setOnHierarchyChangeListener (line 76) | @Override
method onFinishInflate (line 85) | @Override
method addView (line 98) | @Override
method check (line 123) | public void check(@IdRes int id) {
method setCheckedId (line 140) | private void setCheckedId(@IdRes int id) {
method setCheckedStateForView (line 147) | private void setCheckedStateForView(int viewId, boolean checked) {
method getCheckedRadioButtonId (line 162) | @IdRes
method clearCheck (line 175) | public void clearCheck() {
method setOnCheckedChangeListener (line 185) | public void setOnCheckedChangeListener(OnCheckedChangeListener listene...
type OnCheckedChangeListener (line 193) | public interface OnCheckedChangeListener {
method onCheckedChanged (line 201) | void onCheckedChanged(RadioGridGroup group, @IdRes int checkedId);
class CheckedStateTracker (line 204) | private class CheckedStateTracker implements CompoundButton.OnCheckedC...
method onCheckedChanged (line 205) | @Override
class PassThroughHierarchyChangeListener (line 228) | private class PassThroughHierarchyChangeListener implements
method onChildViewAdded (line 235) | @Override
method onChildViewRemoved (line 256) | @Override
FILE: app/src/main/java/com/hippo/widget/SearchBarMover.java
class SearchBarMover (line 31) | public class SearchBarMover extends RecyclerView.OnScrollListener {
method SearchBarMover (line 38) | public SearchBarMover(Helper helper, View searchBar, RecyclerView... r...
method cancelAnimation (line 46) | public void cancelAnimation() {
method onScrollStateChanged (line 52) | @Override
method onScrolled (line 59) | @Override
method returnSearchBarPosition (line 70) | public void returnSearchBarPosition() {
method returnSearchBarPosition (line 74) | @SuppressWarnings("SimplifiableIfStatement")
method showSearchBar (line 152) | public void showSearchBar() {
method showSearchBar (line 156) | public void showSearchBar(boolean animation) {
type Helper (line 211) | public interface Helper {
method isValidView (line 212) | boolean isValidView(RecyclerView recyclerView);
method getValidRecyclerView (line 214) | @Nullable
method forceShowSearchBar (line 217) | boolean forceShowSearchBar();
FILE: app/src/main/java/com/hippo/widget/SimpleGridAutoSpanLayout.java
class SimpleGridAutoSpanLayout (line 22) | public class SimpleGridAutoSpanLayout extends SimpleGridLayout {
method SimpleGridAutoSpanLayout (line 29) | public SimpleGridAutoSpanLayout(Context context) {
method SimpleGridAutoSpanLayout (line 33) | public SimpleGridAutoSpanLayout(Context context, AttributeSet attrs) {
method SimpleGridAutoSpanLayout (line 37) | public SimpleGridAutoSpanLayout(Context context, AttributeSet attrs, i...
method getSpanCountForSuitableSize (line 41) | public static int getSpanCountForSuitableSize(int total, int single) {
method getSpanCountForMinSize (line 52) | public static int getSpanCountForMinSize(int total, int single) {
method setColumnSize (line 56) | public void setColumnSize(int columnSize) {
method setStrategy (line 64) | public void setStrategy(int strategy) {
method onMeasure (line 72) | @Override
FILE: app/src/main/java/com/hippo/widget/SimpleGridLayout.java
class SimpleGridLayout (line 34) | public class SimpleGridLayout extends ViewGroup {
method SimpleGridLayout (line 43) | public SimpleGridLayout(Context context) {
method SimpleGridLayout (line 48) | public SimpleGridLayout(Context context, AttributeSet attrs) {
method SimpleGridLayout (line 53) | public SimpleGridLayout(Context context, AttributeSet attrs, int defSt...
method init (line 58) | private void init(Context context, AttributeSet attrs) {
method setItemMargin (line 69) | public void setItemMargin(int itemMargin) {
method setColumnCount (line 76) | public void setColumnCount(int columnCount) {
method onMeasure (line 87) | @Override
method onLayout (line 146) | @Override
FILE: app/src/main/java/com/hippo/widget/Slider.java
class Slider (line 48) | public class Slider extends View {
method Slider (line 94) | public Slider(Context context, AttributeSet attrs) {
method Slider (line 99) | public Slider(Context context, AttributeSet attrs, int defStyleAttr) {
method init (line 104) | @SuppressWarnings("deprecation")
method updateTextSize (line 167) | private void updateTextSize() {
method updateBubbleSize (line 180) | private void updateBubbleSize() {
method updatePopup (line 196) | private void updatePopup() {
method updateBubblePosition (line 213) | private void updateBubblePosition() {
method onSizeChanged (line 218) | @Override
method onAttachedToWindow (line 226) | @Override
method onDetachedFromWindow (line 233) | @Override
method startProgressAnimation (line 240) | private void startProgressAnimation(float percent) {
method startShowBubbleAnimation (line 259) | private void startShowBubbleAnimation() {
method startHideBubbleAnimation (line 267) | private void startHideBubbleAnimation() {
method setColor (line 275) | public void setColor(int color) {
method setRange (line 281) | public void setRange(int start, int end) {
method getProgress (line 289) | public int getProgress() {
method setProgress (line 293) | public void setProgress(int progress) {
method setReverse (line 317) | public void setReverse(boolean reverse) {
method setOnSetProgressListener (line 324) | public void setOnSetProgressListener(OnSetProgressListener listener) {
method onDraw (line 328) | @Override
method setShowBubble (line 373) | private void setShowBubble(boolean showBubble) {
method onTouchEvent (line 384) | @SuppressLint("ClickableViewAccessibility")
type OnSetProgressListener (line 452) | public interface OnSetProgressListener {
method onSetProgress (line 453) | void onSetProgress(Slider slider, int newProgress, int oldProgress, ...
method onFingerDown (line 455) | void onFingerDown();
method onFingerUp (line 457) | void onFingerUp();
class BubbleView (line 460) | @SuppressLint("ViewConstructor")
method BubbleView (line 470) | public BubbleView(Context context, Paint paint) {
method setColor (line 478) | public void setColor(int color) {
method setProgress (line 482) | public void setProgress(int progress) {
method onSizeChanged (line 491) | @Override
method onDraw (line 498) | @Override
class CheckForShowBubble (line 510) | private final class CheckForShowBubble implements Runnable {
method run (line 511) | @Override
FILE: app/src/main/java/com/hippo/widget/TextClock.java
class TextClock (line 38) | public class TextClock extends AppCompatTextView {
method onReceive (line 59) | @Override
method TextClock (line 69) | public TextClock(Context context) {
method TextClock (line 73) | public TextClock(Context context, AttributeSet attrs) {
method TextClock (line 77) | public TextClock(Context context, AttributeSet attrs, int defStyle) {
method init (line 87) | private void init() {
method createTime (line 93) | private void createTime(String timeZone) {
method getFormat12Hour (line 101) | public CharSequence getFormat12Hour() {
method setFormat12Hour (line 105) | public void setFormat12Hour(CharSequence format) {
method getFormat24Hour (line 112) | public CharSequence getFormat24Hour() {
method run (line 115) | @Override
method setFormat24Hour (line 126) | public void setFormat24Hour(CharSequence format) {
method is24HourModeEnabled (line 133) | public boolean is24HourModeEnabled() {
method getTimeZone (line 137) | public String getTimeZone() {
method setTimeZone (line 141) | public void setTimeZone(String timeZone) {
method chooseFormat (line 154) | private void chooseFormat() {
method getFormat (line 158) | public CharSequence getFormat() {
method chooseFormat (line 169) | private void chooseFormat(boolean handleTicker) {
method onAttachedToWindow (line 187) | @Override
method onDetachedFromWindow (line 207) | @Override
method registerReceiver (line 221) | private void registerReceiver() {
method onChange (line 230) | @Override
method onChange (line 236) | @Override
method registerObserver (line 243) | private void registerObserver() {
method unregisterReceiver (line 248) | private void unregisterReceiver() {
method unregisterObserver (line 252) | private void unregisterObserver() {
method onTimeChanged (line 257) | private void onTimeChanged() {
FILE: app/src/main/java/com/hippo/widget/lockpattern/LockPatternUtils.java
class LockPatternUtils (line 25) | public class LockPatternUtils {
method stringToPattern (line 32) | public static List<LockPatternView.Cell> stringToPattern(String string) {
method patternToString (line 48) | public static String patternToString(List<LockPatternView.Cell> patter...
FILE: app/src/main/java/com/hippo/widget/lockpattern/LockPatternView.java
class LockPatternView (line 56) | @SuppressWarnings("IntegerDivisionInFloatingPointContext")
method LockPatternView (line 116) | public LockPatternView(Context context) {
method LockPatternView (line 120) | public LockPatternView(Context context, AttributeSet attrs) {
method gcd (line 188) | private static int gcd(int a, int b) {
method getCellSize (line 241) | public int getCellSize() {
method getPatternString (line 245) | public String getPatternString() {
method setOnPatternListener (line 254) | public void setOnPatternListener(
method setPattern (line 266) | public void setPattern(DisplayMode displayMode, List<Cell> pattern) {
method setDisplayMode (line 284) | public void setDisplayMode(DisplayMode displayMode) {
method notifyCellAdded (line 301) | private void notifyCellAdded() {
method notifyPatternStarted (line 307) | private void notifyPatternStarted() {
method notifyPatternDetected (line 313) | private void notifyPatternDetected() {
method notifyPatternCleared (line 319) | private void notifyPatternCleared() {
method resetPattern (line 328) | private void resetPattern() {
method clearPatternDrawLookup (line 338) | private void clearPatternDrawLookup() {
method onSizeChanged (line 346) | @Override
method resolveMeasured (line 355) | @SuppressLint("SwitchIntDef")
method onMeasure (line 365) | @Override
method detectAndAddHit (line 398) | private Cell detectAndAddHit(float x, float y) {
method addCellToPattern (line 433) | private void addCellToPattern(Cell newCell) {
method startCellActivatedAnimation (line 442) | private void startCellActivatedAnimation(Cell cell) {
method startLineEndAnimation (line 452) | private void startLineEndAnimation(final CellState state,
method startRadiusAnimation (line 473) | private void startRadiusAnimation(float start, float end, long duration,
method checkForNewHit (line 495) | private Cell checkForNewHit(float x, float y) {
method getRowHit (line 517) | private int getRowHit(float y) {
method getColumnHit (line 537) | private int getColumnHit(float x) {
method onHoverEvent (line 551) | @Override
method onTouchEvent (line 574) | @SuppressLint("ClickableViewAccessibility")
method setPatternInProgress (line 608) | private void setPatternInProgress(boolean progress) {
method handleActionMove (line 612) | private void handleActionMove(MotionEvent event) {
method handleActionUp (line 675) | private void handleActionUp() {
method cancelLineAnimations (line 691) | private void cancelLineAnimations() {
method handleActionDown (line 704) | private void handleActionDown(MotionEvent event) {
method getCenterXForColumn (line 737) | private float getCenterXForColumn(int column) {
method getCenterYForRow (line 741) | private float getCenterYForRow(int row) {
method onDraw (line 745) | @Override
method calculateLastSegmentAlpha (line 863) | private float calculateLastSegmentAlpha(float x, float y, float lastX,...
method getCurrentColor (line 871) | private int getCurrentColor(boolean partOfPattern) {
method drawCircle (line 889) | private void drawCircle(Canvas canvas, float centerX, float centerY, f...
method onSaveInstanceState (line 896) | @Override
method onRestoreInstanceState (line 905) | @Override
type DisplayMode (line 920) | public enum DisplayMode {
type OnPatternListener (line 940) | public interface OnPatternListener {
method onPatternStart (line 944) | void onPatternStart();
method onPatternCleared (line 949) | void onPatternCleared();
method onPatternCellAdded (line 956) | void onPatternCellAdded(List<Cell> pattern);
method onPatternDetected (line 963) | void onPatternDetected(List<Cell> pattern);
class Cell (line 969) | public static class Cell {
method Cell (line 988) | private Cell(int row, int column) {
method of (line 998) | public static synchronized Cell of(int row, int column) {
method checkRange (line 1003) | private static void checkRange(int row, int column) {
method getRow (line 1012) | public int getRow() {
method getColumn (line 1016) | public int getColumn() {
method toString (line 1020) | @NonNull
class CellState (line 1026) | public static class CellState {
class SavedState (line 1040) | private static class SavedState extends BaseSavedState {
method createFromParcel (line 1043) | @Override
method newArray (line 1048) | @Override
method SavedState (line 1061) | private SavedState(Parcelable superState, String serializedPattern, ...
method SavedState (line 1073) | @SuppressLint("ParcelClassLoader")
method getSerializedPattern (line 1082) | public String getSerializedPattern() {
method getDisplayMode (line 1086) | public int getDisplayMode() {
method isInputEnabled (line 1090) | public boolean isInputEnabled() {
method isInStealthMode (line 1094) | public boolean isInStealthMode() {
method writeToParcel (line 1098) | @Override
FILE: app/src/main/java/com/hippo/widget/recyclerview/AutoGridLayoutManager.java
class AutoGridLayoutManager (line 27) | public class AutoGridLayoutManager extends GridLayoutManager {
method AutoGridLayoutManager (line 37) | public AutoGridLayoutManager(Context context, int columnSize, int fake...
method AutoGridLayoutManager (line 43) | public AutoGridLayoutManager(Context context, int columnSize, int orie...
method getSpanCountForSuitableSize (line 48) | public static int getSpanCountForSuitableSize(int total, int single) {
method getSpanCountForMinSize (line 59) | public static int getSpanCountForMinSize(int total, int single) {
method setColumnSize (line 63) | public void setColumnSize(int columnSize) {
method setStrategy (line 71) | public void setStrategy(int strategy) {
method onLayoutChildren (line 79) | @Override
method addOnUpdateSpanCountListener (line 107) | public void addOnUpdateSpanCountListener(OnUpdateSpanCountListener lis...
method removeOnUpdateSpanCountListener (line 114) | public void removeOnUpdateSpanCountListener(OnUpdateSpanCountListener ...
type OnUpdateSpanCountListener (line 120) | public interface OnUpdateSpanCountListener {
method onUpdateSpanCount (line 121) | void onUpdateSpanCount(int spanCount);
FILE: app/src/main/java/com/hippo/widget/recyclerview/AutoStaggeredGridLayoutManager.java
class AutoStaggeredGridLayoutManager (line 28) | public class AutoStaggeredGridLayoutManager extends StaggeredGridLayoutM...
method AutoStaggeredGridLayoutManager (line 38) | public AutoStaggeredGridLayoutManager(int columnSize, int orientation) {
method getSpanCountForSuitableSize (line 43) | public static int getSpanCountForSuitableSize(int total, int single) {
method getSpanCountForMinSize (line 54) | public static int getSpanCountForMinSize(int total, int single) {
method setColumnSize (line 58) | public void setColumnSize(int columnSize) {
method setStrategy (line 66) | public void setStrategy(int strategy) {
method onMeasure (line 74) | @Override
method addOnUpdateSpanCountListener (line 108) | public void addOnUpdateSpanCountListener(OnUpdateSpanCountListener lis...
method removeOnUpdateSpanCountListener (line 115) | public void removeOnUpdateSpanCountListener(OnUpdateSpanCountListener ...
type OnUpdateSpanCountListener (line 121) | public interface OnUpdateSpanCountListener {
method onUpdateSpanCount (line 122) | void onUpdateSpanCount(int spanCount);
FILE: app/src/main/java/com/hippo/yorozuya/AnimationUtils.java
class AnimationUtils (line 25) | public final class AnimationUtils {
method AnimationUtils (line 30) | private AnimationUtils() {
FILE: app/src/main/java/com/hippo/yorozuya/AssertError.java
class AssertError (line 19) | public class AssertError extends Error {
method AssertError (line 20) | public AssertError(String detailMessage) {
FILE: app/src/main/java/com/hippo/yorozuya/AssertException.java
class AssertException (line 19) | public class AssertException extends Exception {
method AssertException (line 20) | public AssertException(String detailMessage) {
FILE: app/src/main/java/com/hippo/yorozuya/AssertUtils.java
class AssertUtils (line 19) | public final class AssertUtils {
method AssertUtils (line 20) | private AssertUtils() {
method assertTrue (line 23) | public static void assertTrue(boolean cond) {
method assertTrueEx (line 27) | public static void assertTrueEx(boolean cond) throws AssertException {
method assertTrue (line 31) | public static void assertTrue(String message, boolean cond) {
method assertTrueEx (line 37) | public static void assertTrueEx(String message, boolean cond) throws A...
method assertNull (line 43) | public static void assertNull(Object object) {
method assertNullEx (line 47) | public static void assertNullEx(Object object) throws AssertException {
method assertNull (line 51) | public static void assertNull(String message, Object object) {
method assertNullEx (line 57) | public static void assertNullEx(String message, Object object) throws ...
method assertNotNull (line 63) | public static void assertNotNull(Object object) {
method assertNotNullEx (line 67) | public static void assertNotNullEx(Object object) throws AssertExcepti...
method assertNotNull (line 71) | public static void assertNotNull(String message, Object object) {
method assertNotNullEx (line 77) | public static void assertNotNullEx(String message, Object object) thro...
method assertEquals (line 83) | public static void assertEquals(int expected, int actual) {
method assertEqualsEx (line 87) | public static void assertEqualsEx(int expected, int actual) throws Ass...
method assertEquals (line 91) | public static void assertEquals(String message, int expected, int actu...
method assertEqualsEx (line 97) | public static void assertEqualsEx(String message, int expected, int ac...
method assertInstanceOf (line 103) | public static void assertInstanceOf(Object obj, Class<?> clazz) {
method assertInstanceOfEx (line 107) | public static void assertInstanceOfEx(Object obj, Class<?> clazz) thro...
method assertInstanceOf (line 111) | public static void assertInstanceOf(String message, Object obj, Class<...
method assertInstanceOfEx (line 117) | public static void assertInstanceOfEx(String message, Object obj, Clas...
FILE: app/src/main/java/com/hippo/yorozuya/ConcurrentPool.java
class ConcurrentPool (line 19) | public class ConcurrentPool<T> {
method ConcurrentPool (line 24) | @SuppressWarnings("unchecked")
method push (line 34) | public synchronized void push(T t) {
method pop (line 40) | public synchronized T pop() {
FILE: app/src/main/java/com/hippo/yorozuya/FileUtils.java
class FileUtils (line 34) | public final class FileUtils {
method FileUtils (line 47) | private FileUtils() {
method ensureFile (line 50) | public static boolean ensureFile(File file) {
method ensureDirectory (line 54) | public static boolean ensureDirectory(File file) {
method humanReadableByteCount (line 74) | public static String humanReadableByteCount(long bytes, boolean si) {
method delete (line 88) | public static boolean delete(File file) {
method deleteContent (line 112) | public static boolean deleteContent(File file) {
method read (line 130) | @Nullable
method write (line 148) | public static boolean write(File file, String str) {
method sanitizeFilename (line 169) | public static String sanitizeFilename(@NonNull String filename) {
method getExtensionFromFilename (line 205) | public static String getExtensionFromFilename(@Nullable String filenam...
method getNameFromFilename (line 224) | public static String getNameFromFilename(@Nullable String filename) {
method createTempFile (line 245) | @Nullable
method createTempDir (line 273) | @Nullable
method rename (line 296) | public static boolean rename(@NonNull File from, @NonNull File to) {
FILE: app/src/main/java/com/hippo/yorozuya/IOUtils.java
class IOUtils (line 27) | public final class IOUtils {
method IOUtils (line 31) | private IOUtils() {
method closeQuietly (line 39) | public static void closeQuietly(Closeable is) {
method copy (line 58) | public static long copy(InputStream input, OutputStream output)
method readAsciiLine (line 77) | public static String readAsciiLine(final InputStream in) throws IOExce...
method readString (line 96) | public static String readString(final InputStream is, String encoding)...
method getAllByte (line 109) | public static byte[] getAllByte(InputStream is) throws IOException {
FILE: app/src/main/java/com/hippo/yorozuya/IntIdGenerator.java
class IntIdGenerator (line 21) | public final class IntIdGenerator {
method IntIdGenerator (line 26) | public IntIdGenerator() {
method IntIdGenerator (line 29) | public IntIdGenerator(int init) {
method nextId (line 33) | @SuppressWarnings("StatementWithEmptyBody")
method setNextId (line 40) | public void setNextId(int id) {
method checkInValidId (line 45) | private void checkInValidId(int id) {
FILE: app/src/main/java/com/hippo/yorozuya/LayoutUtils.java
class LayoutUtils (line 21) | public final class LayoutUtils {
method LayoutUtils (line 22) | private LayoutUtils() {
method dp2pix (line 32) | public static int dp2pix(Context context, float dp) {
method pix2dp (line 43) | public static float pix2dp(Context context, int pix) {
method sp2pix (line 53) | public static int sp2pix(Context context, float sp) {
method pix2sp (line 63) | public static float pix2sp(Context context, float pix) {
FILE: app/src/main/java/com/hippo/yorozuya/MathUtils.java
class MathUtils (line 22) | public final class MathUtils {
method MathUtils (line 27) | private MathUtils() {
method abs (line 30) | public static float abs(float v) {
method log (line 34) | public static float log(float a) {
method exp (line 38) | public static float exp(float a) {
method pow (line 42) | public static float pow(float a, float b) {
method max (line 46) | public static float max(float a, float b) {
method max (line 50) | public static float max(int a, int b) {
method max (line 54) | public static float max(float a, float b, float c) {
method max (line 58) | public static float max(int a, int b, int c) {
method max (line 62) | public static float max(float... arg) {
method max (line 78) | public static int max(int... arg) {
method min (line 94) | public static float min(float a, float b) {
method min (line 98) | public static float min(int a, int b) {
method min (line 102) | public static float min(float a, float b, float c) {
method min (line 106) | public static float min(int a, int b, int c) {
method min (line 110) | public static float min(float... args) {
method min (line 126) | public static int min(int... args) {
method dist (line 142) | public static float dist(float x1, float y1, float x2, float y2) {
method dist (line 148) | public static float dist(float x1, float y1, float z1, float x2, float...
method near (line 155) | public static boolean near(float x1, float y1, float x2, float y2, flo...
method near (line 159) | public static boolean near(float x1, float y1, float z1, float x2, flo...
method mag (line 163) | public static float mag(float a, float b) {
method mag (line 167) | public static float mag(float a, float b, float c) {
method sq (line 171) | public static float sq(float v) {
method cross (line 175) | public static float cross(float v1x, float v1y, float v2x, float v2y) {
method radians (line 179) | public static float radians(float degrees) {
method degrees (line 183) | public static float degrees(float radians) {
method acos (line 187) | public static float acos(float value) {
method asin (line 191) | public static float asin(float value) {
method atan (line 195) | public static float atan(float value) {
method atan2 (line 199) | public static float atan2(float a, float b) {
method tan (line 203) | public static float tan(float angle) {
method lerp (line 207) | public static int lerp(int start, int stop, float amount) {
method lerp (line 211) | public static float lerp(float start, float stop, float amount) {
method delerp (line 215) | public static float delerp(int start, int stop, int value) {
method delerp (line 223) | public static float delerp(float start, float stop, float value) {
method norm (line 231) | public static float norm(float start, float stop, float value) {
method map (line 235) | public static float map(float minStart, float minStop, float maxStart,...
method clamp (line 242) | public static int clamp(int x, int min, int max) {
method clamp (line 250) | public static float clamp(float x, float min, float max) {
method clamp (line 258) | public static long clamp(long x, long min, long max) {
method nextPowerOf2 (line 269) | public static int nextPowerOf2(int n) {
method previousPowerOf2 (line 286) | public static int previousPowerOf2(int n) {
method hammingWeight (line 297) | public static int hammingWeight(int n) {
method ceilDivide (line 306) | public static int ceilDivide(int a, int b) {
method ceilDivide (line 313) | public static long ceilDivide(long a, long b) {
method coverageRadius (line 326) | public static float coverageRadius(float w, float h, float x, float y) {
method positiveModulo (line 342) | public static float positiveModulo(float x, float y) {
method negativeModulo (line 350) | public static float negativeModulo(float x, float y) {
method random (line 361) | public static int random(int howbig) {
method random (line 368) | public static int random(int howsmall, int howbig) {
method random (line 377) | public static float random(float howbig) {
method random (line 384) | public static float random(float howsmall, float howbig) {
method randomSeed (line 390) | public static void randomSeed(long seed) {
FILE: app/src/main/java/com/hippo/yorozuya/NumberUtils.java
class NumberUtils (line 19) | public final class NumberUtils {
method NumberUtils (line 20) | private NumberUtils() {
method int2boolean (line 29) | public static boolean int2boolean(int integer) {
method boolean2int (line 39) | public static int boolean2int(boolean bool) {
method parseIntSafely (line 50) | public static int parseIntSafely(String str, int defaultValue) {
method parseLongSafely (line 65) | public static long parseLongSafely(String str, long defaultValue) {
method parseFloatSafely (line 80) | public static float parseFloatSafely(String str, float defaultValue) {
FILE: app/src/main/java/com/hippo/yorozuya/OSUtils.java
class OSUtils (line 28) | public final class OSUtils {
method OSUtils (line 35) | private OSUtils() {
method checkMainLoop (line 38) | public static void checkMainLoop() {
method getAppAllocatedMemory (line 47) | public static long getAppAllocatedMemory() {
method getAppMaxMemory (line 54) | public static long getAppMaxMemory() {
method getTotalMemory (line 61) | public static long getTotalMemory() {
FILE: app/src/main/java/com/hippo/yorozuya/ObjectUtils.java
class ObjectUtils (line 29) | public final class ObjectUtils {
method ObjectUtils (line 30) | private ObjectUtils() {
method equal (line 36) | public static boolean equal(@Nullable Object a, @Nullable Object b) {
method toString (line 43) | public static String toString(Object o) {
method dumpObject (line 47) | private static void dumpObject(Object o, PrintWriter writer, String pr...
method dumpBoolean (line 53) | private static void dumpBoolean(boolean z, PrintWriter writer, String ...
method dumpByte (line 59) | private static void dumpByte(byte b, PrintWriter writer, String prefix) {
method dumpChar (line 65) | private static void dumpChar(char c, PrintWriter writer, String prefix) {
method dumpShort (line 71) | private static void dumpShort(short s, PrintWriter writer, String pref...
method dumpInt (line 77) | private static void dumpInt(int i, PrintWriter writer, String prefix) {
method dumpLong (line 83) | private static void dumpLong(long j, PrintWriter writer, String prefix) {
method dumpFloat (line 89) | private static void dumpFloat(float f, PrintWriter writer, String pref...
method dumpDouble (line 95) | private static void dumpDouble(double d, PrintWriter writer, String pr...
method dumpArray (line 101) | private static void dumpArray(Object array, PrintWriter writer, String...
method dump (line 186) | public static void dump(Object o, PrintWriter writer) {
method dump (line 190) | public static void dump(Object o, PrintWriter writer, String prefix) {
method dump (line 194) | public static void dump(Object o, PrintWriter writer, String prefix, b...
FILE: app/src/main/java/com/hippo/yorozuya/Pool.java
class Pool (line 19) | public class Pool<T> {
method Pool (line 24) | @SuppressWarnings("unchecked")
method push (line 34) | public void push(T t) {
method pop (line 40) | public T pop() {
FILE: app/src/main/java/com/hippo/yorozuya/ResourcesUtils.java
class ResourcesUtils (line 25) | public final class ResourcesUtils {
method ResourcesUtils (line 29) | private ResourcesUtils() {
method getFloat (line 32) | public static float getFloat(Resources resources, int resId) {
method getAttrValue (line 38) | private static void getAttrValue(Context context, int attrId, TypedVal...
method getAttrColor (line 42) | public static int getAttrColor(Context context, @AttrRes int attrId) {
method getAttrBoolean (line 62) | public static boolean getAttrBoolean(Context context, @AttrRes int att...
method getAttrDimensionPixelOffset (line 79) | public static int getAttrDimensionPixelOffset(Context context, @AttrRe...
FILE: app/src/main/java/com/hippo/yorozuya/SimpleAnimatorListener.java
class SimpleAnimatorListener (line 23) | public abstract class SimpleAnimatorListener implements Animator.Animato...
method onAnimationStart (line 24) | @Override
method onAnimationEnd (line 28) | @Override
method onAnimationCancel (line 32) | @Override
method onAnimationRepeat (line 36) | @Override
FILE: app/src/main/java/com/hippo/yorozuya/SimpleHandler.java
class SimpleHandler (line 22) | public final class SimpleHandler extends Handler {
method SimpleHandler (line 25) | private SimpleHandler(Looper mainLooper) {
method getInstance (line 29) | public static Handler getInstance() {
FILE: app/src/main/java/com/hippo/yorozuya/StringUtils.java
class StringUtils (line 27) | public final class StringUtils {
method StringUtils (line 36) | private StringUtils() {
method unescapeXml (line 42) | public static String unescapeXml(String str) {
method replace (line 69) | public static String replace(final String text, final String searchStr...
method replace (line 101) | public static String replace(final String text, final String searchStr...
method endsWith (line 127) | public static boolean endsWith(String string, String[] suffixs) {
method split (line 161) | public static String[] split(final String str, final char separatorCha...
method splitWorker (line 178) | private static String[] splitWorker(final String str, final char separ...
method avoidNull (line 213) | public static String avoidNull(String value) {
method avoidNull (line 217) | public static String avoidNull(String value, String defaultValue) {
method isAllDigit (line 221) | public static boolean isAllDigit(String str) {
method length (line 235) | public static int length(String str) {
method equals (line 242) | public static boolean equals(String str1, String str2) {
method ordinalIndexOf (line 247) | public static int ordinalIndexOf(String str, char c, int n) {
method trim (line 266) | public static String trim(String str) {
method trim (line 275) | public static String trim(String str, char[] excluded) {
method remove (line 295) | public static String remove(String str, char[] removed) {
FILE: app/src/main/java/com/hippo/yorozuya/Utilities.java
class Utilities (line 21) | public final class Utilities {
method contain (line 29) | public static boolean contain(@Nullable Object[] array, @Nullable Obje...
method contain (line 49) | public static boolean contain(@Nullable char[] array, char ch) {
FILE: app/src/main/java/com/hippo/yorozuya/ViewUtils.java
class ViewUtils (line 35) | public final class ViewUtils {
method ViewUtils (line 39) | private ViewUtils() {
method getCenterInWindows (line 48) | public static void getCenterInWindows(View view, int[] location) {
method getLocationInWindow (line 60) | public static void getLocationInWindow(View view, int[] location) {
method getCenterInAncestor (line 71) | public static void getCenterInAncestor(View view, int[] location, int ...
method getLocationInAncestor (line 84) | public static void getLocationInAncestor(View view, int[] location, in...
method getCenterInAncestor (line 122) | public static void getCenterInAncestor(View view, int[] location, View...
method getLocationInAncestor (line 135) | public static void getLocationInAncestor(View view, int[] location, Vi...
method getAncestor (line 174) | public static View getAncestor(View view, int id) {
method getChild (line 198) | public static View getChild(View view, int id) {
method getBitmapFromView (line 222) | public static Bitmap getBitmapFromView(View v) {
method removeFromParent (line 242) | public static void removeFromParent(View view) {
method removeHardwareAccelerationSupport (line 264) | public static void removeHardwareAccelerationSupport(View v) {
method addHardwareAccelerationSupport (line 270) | public static void addHardwareAccelerationSupport(View v) {
method measureView (line 276) | public static void measureView(View v, int width, int height) {
method isViewUnder (line 305) | public static boolean isViewUnder(@Nullable View view, int x, int y, i...
method getSuitableSize (line 327) | public static int getSuitableSize(int size, int measureSpec) {
method removeOnGlobalLayoutListener (line 350) | public static void removeOnGlobalLayoutListener(ViewTreeObserver viewT...
method getIndexInParent (line 361) | public static int getIndexInParent(View view) {
method transformPointToViewLocal (line 382) | public static void transformPointToViewLocal(float[] point, View paren...
method setEnabledRecursively (line 387) | public static void setEnabledRecursively(View view, boolean enabled) {
method dumpViewHierarchy (line 396) | public static void dumpViewHierarchy(View view, PrintWriter writer) {
method dumpViewHierarchy (line 400) | private static void dumpViewHierarchy(View view, PrintWriter writer, S...
method generateViewId (line 420) | public static int generateViewId() {
method translationXBy (line 435) | public static void translationXBy(View view, float offset) {
method translationYBy (line 442) | public static void translationYBy(View view, float offset) {
method getX2 (line 453) | public static float getX2(View view) {
method getY2 (line 464) | public static float getY2(View view) {
method $$ (line 468) | @NonNull
method $$ (line 477) | @NonNull
method $$ (line 486) | @NonNull
FILE: app/src/main/java/com/hippo/yorozuya/thread/InfiniteThreadExecutor.java
class InfiniteThreadExecutor (line 28) | public class InfiniteThreadExecutor implements Executor {
method InfiniteThreadExecutor (line 37) | public InfiniteThreadExecutor(long keepAliveMillis, Queue<Runnable> wo...
method execute (line 43) | @Override
method getThreadCount (line 57) | public int getThreadCount() {
class Task (line 61) | private class Task implements Runnable {
method run (line 62) | @Override
FILE: app/src/main/java/com/hippo/yorozuya/thread/PriorityThread.java
class PriorityThread (line 21) | public class PriorityThread extends Thread {
method PriorityThread (line 24) | public PriorityThread(Runnable runnable, int priority) {
method PriorityThread (line 29) | public PriorityThread(Runnable runnable, String name, int priority) {
method run (line 34) | @Override
FILE: app/src/main/java/com/hippo/yorozuya/thread/PriorityThreadFactory.java
class PriorityThreadFactory (line 27) | public class PriorityThreadFactory implements ThreadFactory {
method PriorityThreadFactory (line 32) | public PriorityThreadFactory(String name, int priority) {
method newThread (line 37) | @Override
Condensed preview — 615 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,125K chars).
[
{
"path": ".editorconfig",
"chars": 291,
"preview": "[*.{kt,kts}]\nij_kotlin_imports_layout = *\nij_kotlin_line_break_after_multiline_when_entry = false\nktlint_code_style = in"
},
{
"path": ".github/ISSUE_TEMPLATE/bug-report.yml",
"chars": 5107,
"preview": "name: Bug 反馈 / Bug report\ndescription: 提交一个问题报告 / Create a bug report\nlabels:\n - \"bug\"\nbody:\n - type: markdown\n att"
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 149,
"preview": "blank_issues_enabled: false\ncontact_links:\n - name: 所有其他问题 / All other questions\n url: https://www.google.com/\n abou"
},
{
"path": ".github/workflows/ci.yml",
"chars": 1783,
"preview": "name: CI\n\non:\n push:\n branches:\n - '*'\n pull_request:\n workflow_dispatch:\n\njobs:\n linux:\n name: Build\n "
},
{
"path": ".github/workflows/releases.yml",
"chars": 1684,
"preview": "name: Releases\n\non:\n push:\n tags:\n - \"*\"\n\njobs:\n linux:\n name: Build\n runs-on: ubuntu-latest\n steps:\n"
},
{
"path": ".gitignore",
"chars": 108,
"preview": ".gradle\n/local.properties\n.DS_Store\n/build\n/src\n*.iml\n.idea\n/captures\nrelease\ngoogle-services.json\n/.kotlin\n"
},
{
"path": "LICENSE",
"chars": 35148,
"preview": " GNU GENERAL PUBLIC LICENSE\n Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
},
{
"path": "NOTICE",
"chars": 137,
"preview": "EhViewer\nCopyright 2014-2016 Hippo Seven\n\nAn Unofficial E-Hentai Application for Android.\n\n香风智乃是最可爱的女孩子。\nchino kafuu is "
},
{
"path": "README.md",
"chars": 4044,
"preview": "<p align=\"right\">\n <strong>English</strong>\n <span> | </span>\n <a href=\"/docs/README/zh-cn.md\">\n 简体中文\n </a>\n</p>\n\n<"
},
{
"path": "app/.gitignore",
"chars": 113,
"preview": "/build\n/src/main/java-gen\nmanifest-merger-release-report.txt\n/src/main/libs\n/src/main/obj\n# Intellij\n*.iml\n/.cxx\n"
},
{
"path": "app/build.gradle.kts",
"chars": 6043,
"preview": "import java.time.Instant\nimport java.time.ZoneOffset\nimport java.time.format.DateTimeFormatter\nimport org.jetbrains.kotl"
},
{
"path": "app/proguard-rules.pro",
"chars": 335,
"preview": "-keepclassmembers class * implements android.os.Parcelable {\n public static final ** CREATOR;\n}\n\n-keepclasseswithmemb"
},
{
"path": "app/schemas/com.hippo.network.CookiesDatabase/1.json",
"chars": 2569,
"preview": "{\n \"formatVersion\": 1,\n \"database\": {\n \"version\": 1,\n \"identityHash\": \"c801ee62729ba20a203b150211234d5c\",\n \"e"
},
{
"path": "app/schemas/com.hippo.network.CookiesDatabase/2.json",
"chars": 2593,
"preview": "{\n \"formatVersion\": 1,\n \"database\": {\n \"version\": 2,\n \"identityHash\": \"1b80cd29939b0f43934721f1289ba94d\",\n \"e"
},
{
"path": "app/src/debug/res/values/strings.xml",
"chars": 752,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n ~ Copyright 2016 Hippo Seven\n ~\n ~ Licensed under the Apache License, Ve"
},
{
"path": "app/src/main/AndroidManifest.xml",
"chars": 7831,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n ~ Copyright 2016 Hippo Seven\n ~\n ~ Licensed under the Apache License, Ver"
},
{
"path": "app/src/main/cpp/0001-Insert-link-libs.patch",
"chars": 657,
"preview": "From aee8f7147ddb262fd9e5feee8d5b17094cf3470f Mon Sep 17 00:00:00 2001\nFrom: FooIbar <118464521+FooIbar@users.noreply.gi"
},
{
"path": "app/src/main/cpp/0002-Fix-zip_time-performance.patch",
"chars": 646,
"preview": "From e971b9f23727833cc39b9e325db30f383e5bfc30 Mon Sep 17 00:00:00 2001\nFrom: Dude so hot <djohn@fbi.gov>\nDate: Thu, 14 N"
},
{
"path": "app/src/main/cpp/0003-Use-UTF-8-as-default-charset-on-bionic.patch",
"chars": 880,
"preview": "From 86d199429b3fabc83f7dcc9afd72e7b4c7750b1a Mon Sep 17 00:00:00 2001\nFrom: FooIbar <118464521+FooIbar@users.noreply.gi"
},
{
"path": "app/src/main/cpp/CMakeLists.txt",
"chars": 3048,
"preview": "cmake_minimum_required(VERSION 3.14)\nproject(ehviewer C)\ninclude(FetchContent)\n\nif (NOT CMAKE_BUILD_TYPE STREQUAL \"Debug"
},
{
"path": "app/src/main/cpp/archive.c",
"chars": 14181,
"preview": "/*\n * Copyright 2022-2024 Tarsin Norbin\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can red"
},
{
"path": "app/src/main/cpp/ehviewer.h",
"chars": 1553,
"preview": "/*\n * Copyright 2022 Tarsin Norbin\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistri"
},
{
"path": "app/src/main/cpp/gifutils.c",
"chars": 3279,
"preview": "/*\n * Copyright 2023 Tarsin Norbin\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistri"
},
{
"path": "app/src/main/cpp/hash.c",
"chars": 1682,
"preview": "/*\n * Copyright 2022-2024 Tarsin Norbin\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can red"
},
{
"path": "app/src/main/cpp/image.c",
"chars": 4081,
"preview": "/*\n * Copyright 2022 Tarsin Norbin\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistri"
},
{
"path": "app/src/main/cpp/natsort/strnatcmp.c",
"chars": 3250,
"preview": "/* -*- mode: c; c-file-style: \"k&r\" -*-\n\n strnatcmp.c -- Perform 'natural order' comparisons of strings in C.\n Copyrig"
},
{
"path": "app/src/main/cpp/natsort/strnatcmp.h",
"chars": 1138,
"preview": "/* -*- mode: c; c-file-style: \"k&r\" -*-\n\n strnatcmp.c -- Perform 'natural order' comparisons of strings in C.\n Copyrig"
},
{
"path": "app/src/main/cpp/nettle/.gitignore",
"chars": 7,
"preview": "/nettle"
},
{
"path": "app/src/main/cpp/nettle/CMakeLists.txt",
"chars": 7261,
"preview": "cmake_minimum_required(VERSION 3.4.1)\nproject(nettle C)\n\nset(LIBNETTLE_DEFINITIONS\n -DHAVE_CONFIG_H)\n\nset(LIBNETT"
},
{
"path": "app/src/main/cpp/nettle/config.h",
"chars": 8593,
"preview": "/* config.h. Generated from config.h.in by configure. */\n/* config.h.in. Generated from configure.ac by autoheader. "
},
{
"path": "app/src/main/cpp/nettle/keymap.h",
"chars": 2,
"preview": " \n"
},
{
"path": "app/src/main/cpp/nettle/rotors.h",
"chars": 2,
"preview": " \n"
},
{
"path": "app/src/main/cpp/nettle/version.h",
"chars": 1655,
"preview": "/* version.h\n\n Information about library version.\n\n Copyright (C) 2015 Red Hat, Inc.\n Copyright (C) 2015 Niels Möl"
},
{
"path": "app/src/main/java/com/hippo/app/CheckBoxDialogBuilder.kt",
"chars": 1468,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/app/EditTextCheckBoxDialogBuilder.kt",
"chars": 2799,
"preview": "/*\n * Copyright 2022 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/app/EditTextDialogBuilder.kt",
"chars": 2294,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/app/ListCheckBoxDialogBuilder.kt",
"chars": 2254,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/database/MSQLiteBuilder.kt",
"chars": 4062,
"preview": "/*\n * Copyright 2017 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/database/MSQLiteOpenHelper.kt",
"chars": 1422,
"preview": "/*\n * Copyright 2017 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/drawable/AddDeleteDrawable.kt",
"chars": 4323,
"preview": "/*\n * Copyright (C) 2015 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may no"
},
{
"path": "app/src/main/java/com/hippo/drawable/BatteryDrawable.kt",
"chars": 4507,
"preview": "/*\n * Copyright (C) 2014 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may no"
},
{
"path": "app/src/main/java/com/hippo/drawable/DrawerArrowDrawable.kt",
"chars": 7529,
"preview": "/*\n * Copyright (C) 2015 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may no"
},
{
"path": "app/src/main/java/com/hippo/drawable/PreciselyClipDrawable.kt",
"chars": 2590,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/drawable/TriangleDrawable.kt",
"chars": 1984,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/drawable/UnikeryDrawable.kt",
"chars": 2553,
"preview": "/*\n * Copyright 2015 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/drawable/WrapDrawable.kt",
"chars": 2326,
"preview": "/*\n * Copyright 2015 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/easyrecyclerview/EasyRecyclerView.kt",
"chars": 22260,
"preview": "/*\n * Copyright (C) 2015 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may no"
},
{
"path": "app/src/main/java/com/hippo/easyrecyclerview/FastScroller.kt",
"chars": 12849,
"preview": "/*\n * Copyright 2015 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/easyrecyclerview/HandlerDrawable.kt",
"chars": 2511,
"preview": "/*\n * Copyright 2015 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/easyrecyclerview/LayoutManagerUtils.kt",
"chars": 6569,
"preview": "/*\n * Copyright 2015 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/easyrecyclerview/LinearDividerItemDecoration.kt",
"chars": 8906,
"preview": "/*\n * Copyright (C) 2015 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may no"
},
{
"path": "app/src/main/java/com/hippo/easyrecyclerview/MarginItemDecoration.kt",
"chars": 2089,
"preview": "/*\n * Copyright (C) 2015 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may no"
},
{
"path": "app/src/main/java/com/hippo/easyrecyclerview/SimpleHolder.kt",
"chars": 781,
"preview": "/*\n * Copyright (C) 2015 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may no"
},
{
"path": "app/src/main/java/com/hippo/easyrecyclerview/SimpleSmoothScroller.kt",
"chars": 1215,
"preview": "/*\n * Copyright (C) 2015 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may no"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/AppConfig.java",
"chars": 5068,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/Crash.kt",
"chars": 3551,
"preview": "/*\n * Copyright 2019 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/EhApplication.kt",
"chars": 10266,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/EhDB.kt",
"chars": 13948,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/EhProxySelector.kt",
"chars": 2994,
"preview": "/*\n * Copyright 2019 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/FavouriteStatusRouter.java",
"chars": 2236,
"preview": "/*\n * Copyright 2019 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/GetText.kt",
"chars": 895,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/Settings.kt",
"chars": 33057,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/UrlOpener.kt",
"chars": 4015,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/WindowInsetsAnimationHelper.java",
"chars": 3918,
"preview": "/*\n * Copyright 2022 Tarsin Norbin\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistri"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/EhCacheKeyFactory.kt",
"chars": 2438,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/EhClient.kt",
"chars": 5492,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/EhCookieStore.kt",
"chars": 10940,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/EhEngine.kt",
"chars": 24613,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/EhFilter.kt",
"chars": 10809,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/EhRequest.kt",
"chars": 2195,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/EhRequestBuilder.kt",
"chars": 1222,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/EhTagDatabase.kt",
"chars": 11604,
"preview": "/*\n * Copyright 2019 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/EhUrl.kt",
"chars": 5494,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/EhUrlOpener.kt",
"chars": 2662,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/EhUtils.kt",
"chars": 5381,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/data/AbstractGalleryInfo.kt",
"chars": 1325,
"preview": "/*\n * Copyright 2023 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/data/BaseGalleryInfo.kt",
"chars": 2237,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/data/FavListUrlBuilder.kt",
"chars": 1961,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/data/GalleryComment.kt",
"chars": 1206,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/data/GalleryCommentList.kt",
"chars": 820,
"preview": "/*\n * Copyright 2019 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/data/GalleryDetail.kt",
"chars": 2138,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/data/GalleryInfo.kt",
"chars": 4686,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/data/GalleryPreview.kt",
"chars": 1294,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/data/GalleryTagGroup.kt",
"chars": 935,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/data/LargePreviewSet.kt",
"chars": 2212,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/data/ListUrlBuilder.kt",
"chars": 12313,
"preview": "/*\n * Copyright (C) 2015 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may no"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/data/NormalPreviewSet.kt",
"chars": 3086,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/data/PreviewSet.kt",
"chars": 1016,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/exception/CloudflareBypassException.kt",
"chars": 155,
"preview": "package com.hippo.ehviewer.client.exception\n\nimport com.hippo.ehviewer.R\n\nclass CloudflareBypassException : EhException("
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/exception/EhException.kt",
"chars": 980,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/exception/InsufficientFundsException.kt",
"chars": 150,
"preview": "package com.hippo.ehviewer.client.exception\n\nimport com.hippo.ehviewer.R\n\nclass InsufficientFundsException : EhException"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/exception/NoHAtHClientException.kt",
"chars": 754,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/exception/NotLoggedInException.kt",
"chars": 839,
"preview": "/*\n * Copyright 2023 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/exception/OffensiveException.kt",
"chars": 767,
"preview": "/*\n * Copyright (C) 2015 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may no"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/exception/ParseException.kt",
"chars": 832,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/exception/PiningException.kt",
"chars": 705,
"preview": "/*\n * Copyright (C) 2015 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may no"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/exception/QuotaExceededException.kt",
"chars": 838,
"preview": "/*\n * Copyright 2023 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/parser/ArchiveParser.kt",
"chars": 3532,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/parser/EventPaneParser.kt",
"chars": 894,
"preview": "/*\n * Copyright 2022 Tarsin Norbin\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistri"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/parser/FavoritesParser.kt",
"chars": 2185,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/parser/ForumsParser.kt",
"chars": 1170,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/parser/GalleryApiParser.kt",
"chars": 1950,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/parser/GalleryDetailParser.kt",
"chars": 20282,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/parser/GalleryDetailUrlParser.kt",
"chars": 1585,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/parser/GalleryListParser.kt",
"chars": 12916,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/parser/GalleryListUrlParser.kt",
"chars": 4821,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/parser/GalleryMultiPageViewerParser.kt",
"chars": 1637,
"preview": "/*\n * Copyright 2022 Tarsin Norbin\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistri"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/parser/GalleryNotAvailableParser.kt",
"chars": 1191,
"preview": "/*\n * Copyright 2022 Tarsin Norbin\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistri"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/parser/GalleryPageApiParser.kt",
"chars": 2473,
"preview": "/*\n * Copyright 2019 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/parser/GalleryPageParser.kt",
"chars": 2451,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/parser/GalleryPageUrlParser.kt",
"chars": 1774,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/parser/GalleryTokenApiParser.kt",
"chars": 1235,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/parser/HomeParser.kt",
"chars": 2703,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/parser/ParserUtils.kt",
"chars": 1502,
"preview": "/*\n * Copyright 2015 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/parser/ProfileParser.kt",
"chars": 2094,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/parser/RateGalleryParser.kt",
"chars": 1186,
"preview": "/*\n * Copyright 2015 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/parser/SignInParser.kt",
"chars": 1462,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/parser/TorrentParser.kt",
"chars": 2386,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/parser/UserConfigParser.kt",
"chars": 591,
"preview": "package com.hippo.ehviewer.client.parser\n\nimport com.hippo.ehviewer.Settings\nimport com.hippo.yorozuya.unescapeXml\n\nobje"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/parser/VoteCommentParser.kt",
"chars": 1125,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/client/parser/VoteTagParser.kt",
"chars": 1301,
"preview": "/*\n * Copyright 2022 Tarsin Norbin\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistri"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/coil/DiskCache.kt",
"chars": 1239,
"preview": "/*\n * Copyright 2023 Tarsin Norbin\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistri"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/coil/DownloadThumbInterceptor.kt",
"chars": 2775,
"preview": "/*\n * Copyright 2024 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/coil/LockPool.kt",
"chars": 1923,
"preview": "/*\n * Copyright 2024 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/coil/MergeInterceptor.kt",
"chars": 1547,
"preview": "/*\n * Copyright 2023 Tarsin Norbin\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistri"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/coil/NamedMutex.kt",
"chars": 1971,
"preview": "/*\n * Copyright 2024 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/dao/BasicDao.kt",
"chars": 810,
"preview": "/*\n * Copyright 2022 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/dao/BookmarkInfo.kt",
"chars": 1097,
"preview": "/*\n * Copyright 2022 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/dao/BookmarksDao.kt",
"chars": 1112,
"preview": "/*\n * Copyright 2022 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/dao/DownloadDirname.kt",
"chars": 1033,
"preview": "/*\n * Copyright 2022 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/dao/DownloadDirnameDao.kt",
"chars": 1386,
"preview": "/*\n * Copyright 2022 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/dao/DownloadInfo.kt",
"chars": 2199,
"preview": "/*\n * Copyright 2022 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/dao/DownloadLabel.kt",
"chars": 1085,
"preview": "/*\n * Copyright 2022 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/dao/DownloadLabelDao.kt",
"chars": 1431,
"preview": "/*\n * Copyright 2022 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/dao/DownloadsDao.kt",
"chars": 1358,
"preview": "/*\n * Copyright 2022 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/dao/EhDatabase.kt",
"chars": 1746,
"preview": "/*\n * Copyright 2022 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/dao/Filter.kt",
"chars": 1133,
"preview": "/*\n * Copyright 2022 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/dao/FilterDao.kt",
"chars": 1256,
"preview": "/*\n * Copyright 2022 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/dao/HistoryDao.kt",
"chars": 1680,
"preview": "/*\n * Copyright 2022 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/dao/HistoryInfo.kt",
"chars": 1922,
"preview": "/*\n * Copyright 2022 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/dao/LocalFavoriteInfo.kt",
"chars": 1640,
"preview": "/*\n * Copyright 2022 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/dao/LocalFavoritesDao.kt",
"chars": 1604,
"preview": "/*\n * Copyright 2022 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/dao/QuickSearch.kt",
"chars": 1528,
"preview": "/*\n * Copyright 2022 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/dao/QuickSearchDao.kt",
"chars": 1405,
"preview": "/*\n * Copyright 2022 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/download/DownloadManager.kt",
"chars": 39939,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/download/DownloadService.kt",
"chars": 21050,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/gallery/ArchiveGalleryProvider.kt",
"chars": 5992,
"preview": "/*\n * Copyright 2023 Tarsin Norbin\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistri"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/gallery/EhGalleryProvider.kt",
"chars": 4770,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/gallery/GalleryProvider2.kt",
"chars": 1546,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/jni/Archive.kt",
"chars": 1185,
"preview": "/*\n * Copyright 2024 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/jni/GifUtils.kt",
"chars": 954,
"preview": "/*\n * Copyright 2024 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/jni/Hash.kt",
"chars": 794,
"preview": "/*\n * Copyright 2024 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/jni/Image.kt",
"chars": 930,
"preview": "/*\n * Copyright 2024 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/preference/AccountPreference.kt",
"chars": 5495,
"preview": "/*\n * Copyright 2018 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/preference/CleanRedundancyPreference.kt",
"chars": 2812,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/preference/ClearSearchHistoryPreference.kt",
"chars": 1677,
"preview": "/*\n * Copyright 2025 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/preference/ImageLimitsPreference.kt",
"chars": 5869,
"preview": "/*\n * Copyright 2018 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/preference/ProxyPreference.kt",
"chars": 6035,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/preference/RestoreDownloadPreference.kt",
"chars": 6386,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/preference/TaskPreference.kt",
"chars": 2070,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/preference/UserAgentPreference.kt",
"chars": 2789,
"preview": "/*\n * Copyright 2024 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/preference/VersionPreference.kt",
"chars": 1155,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/shortcuts/ShortcutsActivity.kt",
"chars": 1395,
"preview": "/*\n * Copyright 2018 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/spider/DownloadInfoMagics.kt",
"chars": 1692,
"preview": "/*\n * Copyright 2024 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/spider/SpiderDen.kt",
"chars": 12048,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/spider/SpiderInfo.kt",
"chars": 4284,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/spider/SpiderQueen.kt",
"chars": 31865,
"preview": "/*\n * Copyright 2016 Hippo Seven\n * Rewrite with Kotlin coroutines, Tarsin Norbin 2023\n *\n * Licensed under the Apache L"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/CommonOperations.kt",
"chars": 12050,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/EhActivity.kt",
"chars": 3550,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/GalleryActivity.kt",
"chars": 53137,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/MainActivity.kt",
"chars": 25167,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/SettingsActivity.kt",
"chars": 2222,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/WebViewActivity.kt",
"chars": 1568,
"preview": "package com.hippo.ehviewer.ui\n\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Bundle\nimp"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/dialog/SelectItemWithIconAdapter.kt",
"chars": 1937,
"preview": "/*\n * Copyright 2019 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/fragment/AboutFragment.kt",
"chars": 1334,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/fragment/AdvancedFragment.kt",
"chars": 17171,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/fragment/BaseFragment.kt",
"chars": 1426,
"preview": "/*\n * Copyright 2022 Tarsin Norbin\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistri"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/fragment/BasePreferenceFragment.kt",
"chars": 2893,
"preview": "/*\n * Copyright 2022 Tarsin Norbin\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistri"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/fragment/DownloadFragment.kt",
"chars": 6539,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/fragment/EhFragment.kt",
"chars": 5684,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/fragment/FilterFragment.kt",
"chars": 16355,
"preview": "/*\n * Copyright 2022 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/fragment/MyTagsFragment.kt",
"chars": 3661,
"preview": "/*\n * Copyright 2022 Tarsin Norbin\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistri"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/fragment/PrivacyFragment.kt",
"chars": 1729,
"preview": "/*\n * Copyright 2022 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/fragment/ReadFragment.kt",
"chars": 1019,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/fragment/SetSecurityFragment.kt",
"chars": 3532,
"preview": "/*\n * Copyright 2022 Moedog\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistribute it"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/fragment/SettingsFragment.kt",
"chars": 1134,
"preview": "/*\n * Copyright 2022 Tarsin Norbin\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistri"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/fragment/UConfigFragment.kt",
"chars": 5943,
"preview": "/*\n * Copyright 2022 Tarsin Norbin\n *\n * This file is part of EhViewer\n *\n * EhViewer is free software: you can redistri"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/scene/BaseScene.kt",
"chars": 7588,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/scene/CookieSignInScene.kt",
"chars": 9072,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadsScene.kt",
"chars": 53300,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/scene/EhCallback.kt",
"chars": 1993,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/scene/EnterGalleryDetailTransaction.kt",
"chars": 1959,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.kt",
"chars": 43680,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryAdapter.kt",
"chars": 12026,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryCommentsScene.kt",
"chars": 39272,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.kt",
"chars": 88890,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryHolder.kt",
"chars": 1827,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryInfoScene.kt",
"chars": 8519,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.kt",
"chars": 69399,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryPreviewsScene.kt",
"chars": 13034,
"preview": "/*\n * Copyright 2016 Hippo Seven\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
}
]
// ... and 415 more files (download for full content)
About this extraction
This page contains the full source code of the xb2016/EhViewer-NekoInverter GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 615 files (2.8 MB), approximately 766.8k tokens, and a symbol index with 1767 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.