1
0

Updated actions for compatibility with 4.23.15505 (closes #79) (#83)

- Updated documentation for nickel_orientation action.
- Updated documentation for nickel_browser action.
- Updated nickel_open:library:* action.
- Updated nickel_misc:home action.
- Updated symbol tests for 4.23.15505.
This commit is contained in:
Patrick Gaskin
2020-08-11 19:57:12 -04:00
committed by GitHub
parent da4b55e4e1
commit a70d09dd9e
3 changed files with 58 additions and 17 deletions

View File

@@ -31,11 +31,12 @@
# nickel_setting - changes a setting
# nickel_extras - opens one of the beta features
# nickel_browser - opens the browser
# (on firmware 4.23.15505+, you won't be able to exit the browser unless you use the "modal" option or add "menu_item:browser:Quit:nickel_misc:home" to the config)
# nickel_misc - other stuff which isn't significant enough for its own category
# nickel_open - opens a view
# nickel_wifi - controls wifi (note: it doesn't wait for it to connect or disconnect, neither does it check for success)
# nickel_orientation - controls screen orientation
# (devices without an orientation sensor need to use the kobopatch patch "Allow rotation on all devices" or set [DeveloperSettings] ForceAllowLandscape=true)
# (devices without an orientation sensor may need to use the kobopatch patch "Allow rotation on all devices" or set [DeveloperSettings] ForceAllowLandscape=true)
# (devices with an orientation sensor don't need to do anything, but can set the config setting to make this work on all views)
# (this will override the rotation icon/popup until it is set to something different or the device is rebooted)
# power - gracefully controls the power state

View File

@@ -60,6 +60,25 @@ NM_ACTION_(nickel_open) {
char *arg2 = strtrim(tmp1);
NM_CHECK(nullptr, arg2, "could not find a : in the argument");
//libnickel 4.23.15505 * _ZN11MainNavViewC1EP7QWidget
if (dlsym(RTLD_DEFAULT, "_ZN11MainNavViewC1EP7QWidget")) {
NM_LOG("nickel_open: detected firmware >15505 (new nav tab bar), checking special cases");
if (!strcmp(arg1, "library") && !strcmp(arg2, "dropbox")) {
//libnickel 4.23.15505 * _ZN14MoreController7dropboxEv
void (*MoreController_dropbox)(void*);
reinterpret_cast<void*&>(MoreController_dropbox) = dlsym(RTLD_DEFAULT, "_ZN14MoreController7dropboxEv");
NM_CHECK(nullptr, MoreController_dropbox, "could not dlsym MoreController::dropbox");
// technically, we need a MoreController, but it isn't used as of 15505, so it doesn't matter (and if it ever does, it's not going to crash in a critical place)
MoreController_dropbox(nullptr);
return nm_action_result_silent();
}
NM_LOG("nickel_open: no special handling needed for '%s:%s' on fw >15505", arg1, arg2);
}
const char *sym_c = nullptr; // *NavMixin constructor (subclass of QObject)
const char *sym_d = nullptr; // *NavMixin destructor (D1, not D0 because it also tries to call delete)
const char *sym_f = nullptr; // *NavMixin::* function
@@ -83,7 +102,7 @@ NM_ACTION_(nickel_open) {
else if (!strcmp(arg2, "series")) sym_f = "_ZN15LibraryNavMixin10showSeriesEv"; //libnickel 4.20.14601 * _ZN15LibraryNavMixin10showSeriesEv
else if (!strcmp(arg2, "shelves")) sym_f = "_ZN15LibraryNavMixin11showShelvesEv"; //libnickel 4.6 * _ZN15LibraryNavMixin11showShelvesEv
else if (!strcmp(arg2, "pocket")) sym_f = "_ZN15LibraryNavMixin17showPocketLibraryEv"; //libnickel 4.6 * _ZN15LibraryNavMixin17showPocketLibraryEv
else if (!strcmp(arg2, "dropbox")) sym_f = "_ZN15LibraryNavMixin11showDropboxEv"; //libnickel 4.18.13737 * _ZN15LibraryNavMixin11showDropboxEv
else if (!strcmp(arg2, "dropbox")) sym_f = "_ZN15LibraryNavMixin11showDropboxEv"; //libnickel 4.18.13737 4.22.15268 _ZN15LibraryNavMixin11showDropboxEv
} else if (!strcmp(arg1, "reading_life")) {
sym_c = "_ZN19ReadingLifeNavMixinC1Ev"; //libnickel 4.6 * _ZN19ReadingLifeNavMixinC1Ev
sym_d = "_ZN19ReadingLifeNavMixinD1Ev"; //libnickel 4.6 * _ZN19ReadingLifeNavMixinD1Ev
@@ -104,9 +123,9 @@ NM_ACTION_(nickel_open) {
NM_CHECK(nullptr, sym_d, "destructor not specified (this is a bug)");
NM_CHECK(nullptr, sym_f, "unknown view '%s' (in '%s:%s')", arg2, arg1, arg2);
void (*fn_c)(QObject *_this);
void (*fn_d)(QObject *_this);
void (*fn_f)(QObject *_this);
void (*fn_c)(void *_this);
void (*fn_d)(void *_this);
void (*fn_f)(void *_this);
reinterpret_cast<void*&>(fn_c) = dlsym(RTLD_DEFAULT, sym_c);
reinterpret_cast<void*&>(fn_d) = dlsym(RTLD_DEFAULT, sym_d);
@@ -117,10 +136,27 @@ NM_ACTION_(nickel_open) {
NM_CHECK(nullptr, fn_f, "could not find function %s (is your firmware too old?)", sym_f);
NM_LOG("c: %s = %p; d: %s = %p; f: %s = %p", sym_c, fn_c, sym_d, fn_d, sym_f, fn_f);
QObject obj(nullptr);
fn_c(&obj);
fn_f(&obj);
fn_d(&obj);
// HACK: I don't exactly know why this is needed, but without it, most of
// the LibraryNavMixin ones segfault. On firmware versions before 15505, it
// must be initialized as a QObject (I don't understand why, though). Before
// 15505, I used to just declare it as a QObject on the stack like `QObject
// obj(nullptr);`, but this doesn't work anymore after 15505 because it's
// too small for the pointer to the LibraryBuilder the LibraryNavMixin now
// uses. To solve that, we allocate more than enough memory on the stack,
// then use placement new to initialize the QObject. Note that I'm not
// calling the QObject destructor (even though we should) since I don't feel
// comfortable with it because I don't totally understand how the
// LibraryNavMixin does its initialization, and there isn't a risk of there
// being signals pointing to this stack variable since the nav mixins don't
// use signals/slots or keep references to themselves.
// TODO: Figure out how this actually works.
void *obj = alloca(512);
new(obj) QObject();
fn_c(obj);
fn_f(obj);
fn_d(obj);
return nm_action_result_silent();
}
@@ -407,12 +443,16 @@ NM_ACTION_(nickel_browser) {
NM_ACTION_(nickel_misc) {
if (!strcmp(arg, "home")) {
//libnickel 4.6 * _ZN19StatusBarController4homeEv
void (*StatusBarController_home)();
reinterpret_cast<void*&>(StatusBarController_home) = dlsym(RTLD_DEFAULT, "_ZN19StatusBarController4homeEv");
NM_CHECK(nullptr, StatusBarController_home, "could not dlsym StatusBarController::home");
//libnickel 4.6 * _ZN19StatusBarController4homeEv _ZN17MainNavController4homeEv
void (*StatusBarController_home)(void*);
void (*MainNavController_home)(void*);
StatusBarController_home();
reinterpret_cast<void*&>(StatusBarController_home) = dlsym(RTLD_DEFAULT, "_ZN19StatusBarController4homeEv");
reinterpret_cast<void*&>(MainNavController_home) = dlsym(RTLD_DEFAULT, "_ZN17MainNavController4homeEv");
NM_CHECK(nullptr, StatusBarController_home || MainNavController_home, "could not dlsym StatusBarController::home (pre-4.23.15505) or MainNavController::home (4.23.15505+)");
// technically, we need an instance, but it isn't used so it doesn't matter (and if it does crash, we can fix it later as it's not critical) as of 15505
(StatusBarController_home ?: MainNavController_home)(nullptr);
} else if (!strcmp(arg, "rescan_books")) {
//libnickel 4.13.12638 * _ZN19PlugWorkflowManager14sharedInstanceEv
PlugWorkflowManager *(*PlugWorkflowManager_sharedInstance)();
@@ -685,7 +725,7 @@ NM_ACTION_(nickel_orientation) {
NM_LOG(Device_hasOrientationSensor(dev)
? "nickel_orientation: if this didn't do anything, you may need to set [DeveloperSettings] ForceAllowLandscape=true to allow landscape orientations on all views"
: "nickel_orientation: if this didn't do anything, ensure you have applied the 'Allow rotation on all devices' kobopatch patch, or that you have set [DeveloperSettings] ForceAllowLandscape=true");
: "nickel_orientation: if this didn't do anything, you may need to apply the 'Allow rotation on all devices' kobopatch patch, or that you have set [DeveloperSettings] ForceAllowLandscape=true");
// Set the orientation.
//

View File

@@ -33,7 +33,7 @@ func main() {
"4.11.11982", "4.11.12019", "4.12.12111", "4.13.12638", "4.14.12777",
"4.15.12920", "4.16.13162", "4.17.13651", "4.17.13694", "4.18.13737",
"4.19.14123", "4.20.14601", "4.20.14617", "4.20.14622", "4.21.15015",
"4.22.15190", "4.22.15268",
"4.22.15190", "4.22.15268", "4.23.15505",
}
checks := map[string]map[string][]SymCheck{}
@@ -144,7 +144,7 @@ func main() {
}
func GetPatcher(version, lib string) (*patchlib.Patcher, error) {
resp, err := http.Get("https://github.com/pgaskin/kobopatch-patches/raw/v64/testdata/" + version + ".tar.xz")
resp, err := http.Get("https://github.com/pgaskin/kobopatch-patches/raw/v65/testdata/" + version + ".tar.xz")
if err != nil {
return nil, fmt.Errorf("get kobopatch testdata for %#v: %w", version, err)
}