From 6dcceec3c9dd3fc1a59d1aa3b188be5cd47f9c45 Mon Sep 17 00:00:00 2001 From: LoveSy Date: Fri, 12 Nov 2021 20:28:38 +0800 Subject: [PATCH] [app] Fix hint text (#1397) * [app] Fix hint text * Fix text underline --- .../manager/ui/fragment/RepoFragment.java | 47 +++++++++++-------- .../manager/ui/widget/ExpandableTextView.java | 1 + app/src/main/res/layout/item_onlinemodule.xml | 15 +++++- core/src/main/cpp/main/src/jni/zygisk.h | 43 ++++++++++------- 4 files changed, 68 insertions(+), 38 deletions(-) diff --git a/app/src/main/java/org/lsposed/manager/ui/fragment/RepoFragment.java b/app/src/main/java/org/lsposed/manager/ui/fragment/RepoFragment.java index 55186292..139012af 100644 --- a/app/src/main/java/org/lsposed/manager/ui/fragment/RepoFragment.java +++ b/app/src/main/java/org/lsposed/manager/ui/fragment/RepoFragment.java @@ -198,31 +198,38 @@ public class RepoFragment extends BaseFragment implements RepoLoader.Listener { holder.appName.setText(module.getDescription()); SpannableStringBuilder sb = new SpannableStringBuilder(module.getName()); - ModuleUtil.InstalledModule installedModule = ModuleUtil.getInstance().getModule(module.getName()); - if (installedModule != null) { - var ver = repoLoader.getModuleLatestVersion(installedModule.packageName); - if (ver != null && ver.upgradable(installedModule.versionCode, installedModule.versionName)) { - sb.append("\n"); - String recommended = getString(R.string.update_available, ver.versionName); - sb.append(recommended); - final ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(ResourceUtils.resolveColor(requireActivity().getTheme(), androidx.appcompat.R.attr.colorAccent)); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - final TypefaceSpan typefaceSpan = new TypefaceSpan(Typeface.create("sans-serif-medium", Typeface.NORMAL)); - sb.setSpan(typefaceSpan, sb.length() - recommended.length(), sb.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE); - } else { - final StyleSpan styleSpan = new StyleSpan(Typeface.BOLD); - sb.setSpan(styleSpan, sb.length() - recommended.length(), sb.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE); - } - sb.setSpan(foregroundColorSpan, sb.length() - recommended.length(), sb.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE); - } - } + String summary = module.getSummary(); if (summary != null) { sb.append("\n"); sb.append(summary); } - + holder.appDescription.setVisibility(View.VISIBLE); holder.appDescription.setText(sb); + sb = new SpannableStringBuilder(); + ModuleUtil.InstalledModule installedModule = ModuleUtil.getInstance().getModule(module.getName()); + if (installedModule != null) { + var ver = repoLoader.getModuleLatestVersion(installedModule.packageName); + if (ver != null && ver.upgradable(installedModule.versionCode, installedModule.versionName)) { + String hint = getString(R.string.update_available, ver.versionName); + sb.append(hint); + final ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(ResourceUtils.resolveColor(requireActivity().getTheme(), androidx.appcompat.R.attr.colorAccent)); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + final TypefaceSpan typefaceSpan = new TypefaceSpan(Typeface.create("sans-serif-medium", Typeface.NORMAL)); + sb.setSpan(typefaceSpan, sb.length() - hint.length(), sb.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE); + } else { + final StyleSpan styleSpan = new StyleSpan(Typeface.BOLD); + sb.setSpan(styleSpan, sb.length() - hint.length(), sb.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE); + } + sb.setSpan(foregroundColorSpan, sb.length() - hint.length(), sb.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE); + } + } + if (sb.length() > 0) { + holder.hint.setVisibility(View.VISIBLE); + holder.hint.setText(sb); + } else { + holder.hint.setVisibility(View.GONE); + } holder.itemView.setOnClickListener(v -> { searchView.clearFocus(); @@ -273,12 +280,14 @@ public class RepoFragment extends BaseFragment implements RepoLoader.Listener { ConstraintLayout root; TextView appName; TextView appDescription; + TextView hint; ViewHolder(ItemOnlinemoduleBinding binding) { super(binding.getRoot()); root = binding.itemRoot; appName = binding.appName; appDescription = binding.description; + hint = binding.hint; } } diff --git a/app/src/main/java/org/lsposed/manager/ui/widget/ExpandableTextView.java b/app/src/main/java/org/lsposed/manager/ui/widget/ExpandableTextView.java index b3a62259..b4ea10cc 100644 --- a/app/src/main/java/org/lsposed/manager/ui/widget/ExpandableTextView.java +++ b/app/src/main/java/org/lsposed/manager/ui/widget/ExpandableTextView.java @@ -71,6 +71,7 @@ public class ExpandableTextView extends MaterialTextView { @Override public void updateDrawState(@NonNull TextPaint ds) { + super.updateDrawState(ds); ds.setTypeface(Typeface.DEFAULT_BOLD); } }; diff --git a/app/src/main/res/layout/item_onlinemodule.xml b/app/src/main/res/layout/item_onlinemodule.xml index 211cd35c..b0c1871c 100644 --- a/app/src/main/res/layout/item_onlinemodule.xml +++ b/app/src/main/res/layout/item_onlinemodule.xml @@ -58,11 +58,24 @@ android:layout_gravity="center_vertical" android:maxLines="6" android:textAppearance="?android:attr/textAppearanceSmall" - app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="@+id/app_name" app:layout_constraintTop_toBottomOf="@id/app_name" tools:text="@tools:sample/lorem" /> + + diff --git a/core/src/main/cpp/main/src/jni/zygisk.h b/core/src/main/cpp/main/src/jni/zygisk.h index eb6e9613..680d6afc 100644 --- a/core/src/main/cpp/main/src/jni/zygisk.h +++ b/core/src/main/cpp/main/src/jni/zygisk.h @@ -1,9 +1,5 @@ -// All content of this file is released to the public domain. - -// This file is the public API for Zygisk modules. -// DO NOT use this file for developing Zygisk modules as it might contain WIP changes. -// Always use the following header for development as those are finalized APIs: -// https://github.com/topjohnwu/zygisk-module-sample/blob/master/module/jni/zygisk.hpp +// This is the public API for Zygisk modules. +// DO NOT MODIFY ANY CODE IN THIS HEADER. #pragma once @@ -12,14 +8,20 @@ #define ZYGISK_API_VERSION 1 /* + Define a class and inherit zygisk::ModuleBase to implement the functionality of your module. Use the macro REGISTER_ZYGISK_MODULE(className) to register that class to Zygisk. + Please note that modules will only be loaded after zygote has forked the child process. THIS MEANS ALL OF YOUR CODE RUNS IN THE APP/SYSTEM SERVER PROCESS, NOT THE ZYGOTE DAEMON! + Example code: + static jint (*orig_logger_entry_max)(JNIEnv *env); static jint my_logger_entry_max(JNIEnv *env) { return orig_logger_entry_max(env); } + static void example_handler(int socket) { ... } + class ExampleModule : public zygisk::ModuleBase { public: void onLoad(zygisk::Api *api, JNIEnv *env) override { @@ -37,8 +39,11 @@ private: zygisk::Api *api; JNIEnv *env; }; + REGISTER_ZYGISK_MODULE(ExampleModule) + REGISTER_ZYGISK_COMPANION(example_handler) + */ namespace zygisk { @@ -143,6 +148,8 @@ namespace zygisk { DLCLOSE_MODULE_LIBRARY = 1, }; +// All API functions will stop working after post[XXX]Specialize as Zygisk will be unloaded +// from the specialized process afterwards. struct Api { // Connect to a root companion process and get a Unix domain socket for IPC. @@ -264,23 +271,23 @@ void zygisk_companion_entry(int client) { func(client); } } // namespace internal - int Api::connectCompanion() { - return impl->connectCompanion(impl->_this); + inline int Api::connectCompanion() { + return impl->connectCompanion ? impl->connectCompanion(impl->_this) : -1; } - void Api::setOption(Option opt) { - impl->setOption(impl->_this, opt); + inline void Api::setOption(Option opt) { + if (impl->setOption) impl->setOption(impl->_this, opt); } - void Api::hookJniNativeMethods(JNIEnv *env, const char *className, JNINativeMethod *methods, int numMethods) { - impl->hookJniNativeMethods(env, className, methods, numMethods); + inline void Api::hookJniNativeMethods(JNIEnv *env, const char *className, JNINativeMethod *methods, int numMethods) { + if (impl->hookJniNativeMethods) impl->hookJniNativeMethods(env, className, methods, numMethods); } - void Api::pltHookRegister(const char *regex, const char *symbol, void *newFunc, void **oldFunc) { - impl->pltHookRegister(regex, symbol, newFunc, oldFunc); + inline void Api::pltHookRegister(const char *regex, const char *symbol, void *newFunc, void **oldFunc) { + if (impl->pltHookRegister) impl->pltHookRegister(regex, symbol, newFunc, oldFunc); } - void Api::pltHookExclude(const char *regex, const char *symbol) { - impl->pltHookExclude(regex, symbol); + inline void Api::pltHookExclude(const char *regex, const char *symbol) { + if (impl->pltHookExclude) impl->pltHookExclude(regex, symbol); } - bool Api::pltHookCommit() { - return impl->pltHookCommit(); + inline bool Api::pltHookCommit() { + return impl->pltHookCommit != nullptr && impl->pltHookCommit(); } } // namespace zygisk