Patch Xmarks for Android to get ActionBar with menu


Xmarks is basically the only software offering cross platform cross browser bookmark sync. Since the transfer to LastPass there probably won’t be any more updates to the Android version of Xmarks. The “latest version” is to this day exactly 5 years old.

The 5 year old apk comes with a lot of baggage. It depended on the hardware menu button which was common back than. Since the app runs in compatibility mode now, the menu button is placed either on the software controls panel or accessible via a hardware button (long/double/triple) press.

Unfortunately there are at least some phones lacking the menu trigger shortcut (and by phones I mean Lenovo Phab 2 Pro). The menu button is crucial for syncing bookmarks. I don’t use that Xmarks but I was able to patch and recompile apk to include native Android ActionBar containing menu.

There are no bookmarks on the above screenshot but it was tested and it works with an actual account and few hundreds of bookmarks. To get the apk yourself, decompile Xmarks 1.0.16 using apktool (version 2.2.1 to get the same output) and apply following patch.

--- "Xmarks 1.0.16/AndroidManifest.xml" 2017-01-26 20:45:28.965042700 +0100
+++ "Xmarks 1.0.16 patched/AndroidManifest.xml" 2017-01-03 11:40:33.979000000 +0100
@@ -8,7 +8,7 @@
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
<supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:smallScreens="true" android:xlargeScreens="true"/>
<application android:icon="@drawable/xmarks_logo" android:label="@string/app_name">
- <activity android:configChanges="keyboardHidden|orientation" android:label="@string/app_name" android:launchMode="singleTask" android:name="Xmarks">
+ <activity android:configChanges="keyboardHidden|orientation" android:label="@string/app_name" android:launchMode="singleTask" android:name="Xmarks" android:theme="@android:style/Theme.Holo">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
diff -Naur "Xmarks 1.0.16/apktool.yml" "Xmarks 1.0.16 patched/apktool.yml"
--- "Xmarks 1.0.16/apktool.yml" 2017-01-26 20:45:29.308817100 +0100
+++ "Xmarks 1.0.16 patched/apktool.yml" 2017-01-03 11:20:35.228581000 +0100
@@ -9,7 +9,7 @@
renameManifestPackage: null
sdkInfo:
minSdkVersion: '3'
- targetSdkVersion: '9'
+ targetSdkVersion: '14'
sharedLibrary: false
unknownFiles: {}
usesFramework:
@@ -18,5 +18,5 @@
tag: null
version: 2.2.1
versionInfo:
- versionCode: '17'
- versionName: 1.0.16
+ versionCode: '18'
+ versionName: 1.0.18
diff -Naur "Xmarks 1.0.16/smali/com/xmarks/android/OpenTabs.smali" "Xmarks 1.0.16 patched/smali/com/xmarks/android/OpenTabs.smali"
--- "Xmarks 1.0.16/smali/com/xmarks/android/OpenTabs.smali" 2017-01-26 20:45:29.168182900 +0100
+++ "Xmarks 1.0.16 patched/smali/com/xmarks/android/OpenTabs.smali" 2017-01-03 11:09:27.474906600 +0100
@@ -274,14 +274,14 @@
.end packed-switch
.end method

-.method public onPrepareOptionsMenu(Landroid/view/Menu;)Z
+.method public onCreateOptionsMenu(Landroid/view/Menu;)Z
.locals 3

.prologue
const/4 v2, 0x0

.line 215
- invoke-super {p0, p1}, Landroid/app/ExpandableListActivity;->onPrepareOptionsMenu(Landroid/view/Menu;)Z
+ invoke-super {p0, p1}, Landroid/app/ExpandableListActivity;->onCreateOptionsMenu(Landroid/view/Menu;)Z

.line 216
invoke-interface {p1}, Landroid/view/Menu;->clear()V
diff -Naur "Xmarks 1.0.16/smali/com/xmarks/android/Xmarks.smali" "Xmarks 1.0.16 patched/smali/com/xmarks/android/Xmarks.smali"
--- "Xmarks 1.0.16/smali/com/xmarks/android/Xmarks.smali" 2017-01-26 20:45:29.199434800 +0100
+++ "Xmarks 1.0.16 patched/smali/com/xmarks/android/Xmarks.smali" 2017-01-03 11:47:16.204132000 +0100
@@ -520,7 +520,7 @@
.line 500
const/4 v1, 0x3

- invoke-virtual {p0, v1, v0}, Lcom/xmarks/android/Xmarks;->setFeatureDrawableResource(II)V
+ #invoke-virtual {p0, v1, v0}, Lcom/xmarks/android/Xmarks;->setFeatureDrawableResource(II)V

.line 502
:cond_1
@@ -1240,12 +1240,12 @@
sput-object p0, Lcom/xmarks/android/Xmarks;->d:Lcom/xmarks/android/Xmarks;

.line 97
- invoke-virtual {p0, v10}, Lcom/xmarks/android/Xmarks;->requestWindowFeature(I)Z
+ #invoke-virtual {p0, v10}, Lcom/xmarks/android/Xmarks;->requestWindowFeature(I)Z

.line 98
const/4 v0, 0x5

- invoke-virtual {p0, v0}, Lcom/xmarks/android/Xmarks;->requestWindowFeature(I)Z
+ #invoke-virtual {p0, v0}, Lcom/xmarks/android/Xmarks;->requestWindowFeature(I)Z

.line 99
invoke-static {}, Lcom/xmarks/android/Xmarks;->a()V
@@ -1337,7 +1337,7 @@
invoke-direct/range {v0 .. v6}, Lcom/xmarks/android/s;-><init>(Lcom/xmarks/android/Xmarks;Landroid/content/Context;ILandroid/database/Cursor;[Ljava/lang/String;[I)V

.line 107
- invoke-virtual {p0, v9}, Lcom/xmarks/android/Xmarks;->requestWindowFeature(I)Z
+ #invoke-virtual {p0, v9}, Lcom/xmarks/android/Xmarks;->requestWindowFeature(I)Z

.line 108
invoke-virtual {p0, v0}, Lcom/xmarks/android/Xmarks;->setListAdapter(Landroid/widget/ListAdapter;)V
@@ -1352,7 +1352,7 @@
move-result v0

.line 109
- invoke-virtual {p0, v9, v0}, Lcom/xmarks/android/Xmarks;->setFeatureDrawableResource(II)V
+ #invoke-virtual {p0, v9, v0}, Lcom/xmarks/android/Xmarks;->setFeatureDrawableResource(II)V

.line 111
new-instance v0, Ljava/util/Stack;
@@ -1382,12 +1382,12 @@

move-result-object v0

- invoke-virtual {p0, v0}, Lcom/xmarks/android/Xmarks;->setTitle(Ljava/lang/CharSequence;)V
+ #invoke-virtual {p0, v0}, Lcom/xmarks/android/Xmarks;->setTitle(Ljava/lang/CharSequence;)V

.line 115
const/16 v0, 0x2710

- invoke-virtual {p0, v0}, Lcom/xmarks/android/Xmarks;->setProgress(I)V
+ #invoke-virtual {p0, v0}, Lcom/xmarks/android/Xmarks;->setProgress(I)V

.line 117
const-string v0, "username"
@@ -2065,7 +2065,7 @@
return-void
.end method

-.method public onPrepareOptionsMenu(Landroid/view/Menu;)Z
+.method public onCreateOptionsMenu(Landroid/view/Menu;)Z
.locals 5

.prologue
@@ -2074,7 +2074,7 @@
const/4 v3, 0x0

.line 351
- invoke-super {p0, p1}, Landroid/app/ListActivity;->onPrepareOptionsMenu(Landroid/view/Menu;)Z
+ invoke-super {p0, p1}, Landroid/app/ListActivity;->onCreateOptionsMenu(Landroid/view/Menu;)Z

.line 352
invoke-interface {p1}, Landroid/view/Menu;->clear()V

As a bonus, you will get dark Holo theme as well.