diff --git a/.gitattributes b/.gitattributes
index f170c62..edd3a6e 100755
--- a/.gitattributes
+++ b/.gitattributes
@@ -7,4 +7,4 @@ META-INF/** text eol=lf
# Denote all files that are truly binary and should not be modified.
common/addon/**/tools/** binary
-common/tools/** binary
\ No newline at end of file
+common/tools/*.zip binary
diff --git a/.gitignore b/.gitignore
index 45dd7f7..e42278e 100755
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
__MACOSX
.DS_Store
/*.zip
-
+php.xml
+/.idea
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/WebviewManager-Module.iml b/.idea/WebviewManager-Module.iml
new file mode 100644
index 0000000..c956989
--- /dev/null
+++ b/.idea/WebviewManager-Module.iml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..b2a67c9
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index f18eaed..8bd618d 100644
--- a/CODE_OF_CONDUCT.md
+++ b/CODE_OF_CONDUCT.md
@@ -1,94 +1,56 @@
-# Citizen Code of Conduct
+# Androidacy Code of Conduct
-## 1. Purpose
+## Introduction
-A primary goal of Webview Manager Module is to be inclusive to the largest number of contributors, with the most varied and diverse backgrounds possible. As such, we are committed to providing a friendly, safe and welcoming environment for all, regardless of gender, sexual orientation, ability, ethnicity, socioeconomic status, and religion (or lack thereof).
+At Androidacy, we're committed to fostering an open, inclusive, supportive, and respectful community for everyone who participates in our repositories and communities. This Code of Conduct outlines our expectations for participant behavior as well as the consequences for unacceptable behavior.
-This code of conduct outlines our expectations for all those who participate in our community, as well as the consequences for unacceptable behavior.
+## Our Pledge
-We invite all those who participate in Webview Manager Module to help us create safe and positive experiences for everyone.
+We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. We value and respect all individuals irrespective of their race, religion, sexual orientation, gender identity, age, nationality, appearance, or technical expertise.
-## 2. Open [Source/Culture/Tech] Citizenship
+## Our Standards
-A supplemental goal of this Code of Conduct is to increase open [source/culture/tech] citizenship by encouraging participants to recognize and strengthen the relationships between our actions and their effects on our community.
+### Expected Behavior
-Communities mirror the societies in which they exist and positive action is essential to counteract the many forms of inequality and abuses of power that exist in society.
+We expect all participants in Androidacy communities to:
-If you see someone who is making an extra effort to ensure our community is welcoming, friendly, and encourages all participants to contribute to the fullest extent, we want to know.
+- Demonstrate empathy and kindness towards other people.
+- Respect personal identities and experiences, particularly related to LGBTQ+, race, religion, sexuality, and gender.
+- Give and gracefully accept constructive feedback.
+- Focus on what is best not just for us as individuals, but for the overall community.
-## 3. Expected Behavior
+### Unacceptable Behavior
-The following behaviors are expected and requested of all community members:
+We consider the following behaviors unacceptable:
- * Participate in an authentic and active way. In doing so, you contribute to the health and longevity of this community.
- * Exercise consideration and respect in your speech and actions.
- * Attempt collaboration before conflict.
- * Refrain from demeaning, discriminatory, or harassing behavior and speech.
- * Be mindful of your surroundings and of your fellow participants. Alert community leaders if you notice a dangerous situation, someone in distress, or violations of this Code of Conduct, even if they seem inconsequential.
- * Remember that community event venues may be shared with members of the public; please be respectful to all patrons of these locations.
+- Disrespect or discrimination of any form, particularly related to a person's LGBTQ+ status, race, religion, sexuality, or gender identity.
+- Harassment, public or private.
+- Using this community as a platform for inappropriate content or conduct.
-## 4. Unacceptable Behavior
+### Content Responsibility
-The following behaviors are considered harassment and are unacceptable within our community:
+While Androidacy will strive to maintain the community standards, we are not responsible for all community content. However, we'll make a best effort to moderate as per the guidelines, at our discretion.
- * Violence, threats of violence or violent language directed against another person.
- * Sexist, racist, homophobic, transphobic, ableist or otherwise discriminatory jokes and language.
- * Posting or displaying sexually explicit or violent material.
- * Posting or threatening to post other people's personally identifying information ("doxing").
- * Personal insults, particularly those related to gender, sexual orientation, race, religion, or disability.
- * Inappropriate photography or recording.
- * Inappropriate physical contact. You should have someone's consent before touching them.
- * Unwelcome sexual attention. This includes, sexualized comments or jokes; inappropriate touching, groping, and unwelcomed sexual advances.
- * Deliberate intimidation, stalking or following (online or in person).
- * Advocating for, or encouraging, any of the above behavior.
- * Sustained disruption of community events, including talks and presentations.
+## Reporting and Enforcement
-## 5. Weapons Policy
+If you are the subject of, or witness any violations of this Code of Conduct, please contact us by emailing community-relations@androidacy.com or via https://t.me/AndroidacySupport on Telegram. If necessary, Androidacy will respond as promptly as we can to address the issue.
-No weapons will be allowed at Webview Manager Module events, community spaces, or in other spaces covered by the scope of this Code of Conduct. Weapons include but are not limited to guns, explosives (including fireworks), and large knives such as those used for hunting or display, as well as any other item used for the purpose of causing injury or harm to others. Anyone seen in possession of one of these items will be asked to leave immediately, and will only be allowed to return without the weapon. Community members are further expected to comply with all state and local laws on this matter.
+We will maintain confidentiality with regard to the reporter of an incident. However, Androidacy reserves the right to moderate, delete, or censor any content or behavior that we find to be in violation of this Code of Conduct, at our discretion. We also have the ultimate say in interpreting and enforcing these rules, with no obligation to act on any report or complaint.
-## 6. Consequences of Unacceptable Behavior
+## Intellectual Property
-Unacceptable behavior from any community member, including sponsors and those with decision-making authority, will not be tolerated.
+All participants are expected to respect copyrights, trademarks, and other legal rights. Any contributions should be original or free from other license encumbrances.
-Anyone asked to stop unacceptable behavior is expected to comply immediately.
+### Code Contributions
-If a community member engages in unacceptable behavior, the community organizers may take any action they deem appropriate, up to and including a temporary ban or permanent expulsion from the community without warning (and without refund in the case of a paid event).
+Your submissions should follow existing code styles and be free of bugs and security vulnerabilities. By submitting your code, you grant Androidacy all rights to use and distribute your code, as long as it does not infringe any existing licenses.
-## 7. Reporting Guidelines
+## Legal
-If you are subject to or witness unacceptable behavior, or have any other concerns, please notify a community organizer as soon as possible. https://www.androidacy.com/contact/.
+Androidacy is not liable for any defamation, slander, or other claims arising from the operation of our public communities. Slander against Androidacy under any circumstance is not permissible.
-[Reporting guidelines](https://www.androidacy.com/contact/)
+## Conclusion
-Additionally, community organizers are available to help community members engage with local law enforcement or to otherwise help those experiencing unacceptable behavior feel safe. In the context of in-person events, organizers will also provide escorts as desired by the person experiencing distress.
+This Code of Conduct applies to all Androidacy communities and public spaces, both online and off, and also applies when an individual is officially representing Androidacy in public spaces. We hope that our community members will carry these principles with them into their everyday lives, helping make the world a better place for everyone.
-## 8. Addressing Grievances
-
-If you feel you have been falsely or unfairly accused of violating this Code of Conduct, you should notify Androidacy with a concise description of your grievance. Your grievance will be handled in accordance with our existing governing policies. [Policy](https://www.androidacy.com/terms/)
-
-All grievances will be addressed by a Community Manager or Moderator as soon as possible, in the order received.
-
-## 9. Scope
-
-We expect all community participants (contributors, paid or otherwise; sponsors; and other guests) to abide by this Code of Conduct in all community venues--online and in-person--as well as in all one-on-one communications pertaining to community business.
-
-This code of conduct and its related procedures also applies to unacceptable behavior occurring outside the scope of community activities when such behavior has the potential to adversely affect the safety and well-being of community members.
-
-## 10. Contact info
-
-https://www.androidacy.com/contact/
-
-## 11. License and attribution
-
-The Citizen Code of Conduct is distributed by [Stumptown Syndicate](http://stumptownsyndicate.org) under a [Creative Commons Attribution-ShareAlike license](http://creativecommons.org/licenses/by-sa/3.0/).
-
-Portions of text derived from the [Django Code of Conduct](https://www.djangoproject.com/conduct/) and the [Geek Feminism Anti-Harassment Policy](http://geekfeminism.wikia.com/wiki/Conference_anti-harassment/Policy).
-
-_Revision 2.3. Posted 6 March 2017._
-
-_Revision 2.2. Posted 4 February 2016._
-
-_Revision 2.1. Posted 23 June 2014._
-
-_Revision 2.0, adopted by the [Stumptown Syndicate](http://stumptownsyndicate.org) board on 10 January 2013. Posted 17 March 2013._
+By choosing to join and participate in Androidacy communities, you are committing to upholding these standards. Thank you for helping make our community welcoming and friendly to all.
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 46adda6..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,25 +0,0 @@
- Copyright 2021 Androidacy. All rights reserved unless otherwise specified.
-
- This work is licensed under the Androidacy Open Source License, hereafter referred to as the "AOSL".
-
- Androidacy believes strongly in the power of both free and open source software, and as such, our software is offered that way. We hereby grant you the license to look at, reuse, and share our works, with some limitations and requirements.
-
- Androidacy hereby grants you a irrevocable license to:
- - Obtain the publicly available source code of our Application
- - Modify the source as you see fit for personal use
- - Suggest changes to Androidacy, who is under no obligation to make them
-
- Under the terms of this license, you may not:
- - Resell our works, modified or unmodified, for a profit
- - Rebrand our work as your own
- - Republish our unmodified Software on any unofficial sources or mirror it
- - Request private source code.
- - Use this Software to harm or otherwise damage Androidacy or any of our clients
-
- Androidacy will make a best effort to include the source code of any components of the Software; however, we are under no obligation to, and will only publish code as we see fit. We also reserve the right to monetize our work as we see fit.
-
- In addition, if you use an open source compenent by Androidacy in your project, you are hereby obligated to share the source code and any modifications you make to it. You must also credit Androidacy for any code you reuse.
-
- THIS SOFTWARE IS OFFERED "AS-IS", WITH NO WARRANTIES EXPRESSED OR IMPLIED. IT IS OFFERED IN THE HOPE THAT IS FOUND USEFUL, BUT ANDROIDACY MAKES NO WARRANTIES OF MERCHANTABILITY FOR ANY PURPOSE WHATSOEVER.
-
-
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000..c1348d3
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,55 @@
+## Androidacy Open Source License V4
+
+### 1. Definitions
+
+_"Software"_ shall mean the original work of authorship.
+
+_"License"_ shall refer to this document, the Androidacy Open Source License V4.
+
+_"Licensor"_ shall refer to the copyright holder, Androidacy.
+
+_"User"_ or _"You"_ shall refer to the individual or entity exercising the rights granted by this License.
+
+_"Source Form"_ shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+_"Object Form"_ shall mean any form resulting from mechanical transformation or translation of a Source Form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+_"Work"_ shall mean the work of authorship, whether in Source or Object Form, made available under the License, as indicated by a copyright notice that is included in or attached to the work.
+
+### 2. Grant of Rights
+
+Subject to the terms of this License, the Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual license to:
+
+- Use the Software for personal and other non-commercial usage.
+- Reproduce the Software in Source Form or Object Form.
+- Modify the Software and create derivative works ("Modified Software") for personal and other non-commercial usage.
+
+### 3. Restrictions
+
+The license granted above is expressly made subject to and limited by the following restrictions:
+
+- You may not use any names, logos, or other trademarks associated with the Software for any purpose without the prior written consent of the Licensor.
+- You may not distribute verbatim copies of the Software without the prior written consent of the Licensor.
+- You may not sell, rent, lease, offer or deliver the Software or Modified Software, or any copies thereof, in exchange for any form of compensation.
+
+### 4. Attribution
+
+In any use of the Software, You must include the following attribution to the Licensor where applicable: "This software is based on the work of Androidacy."
+
+### 5. Disclaimer of Warranty
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANDROIDACY OR CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+### 6. Liability
+
+Under no circumstances will Androidacy or contributors be responsible for any usage of the Software or the consequences thereof. You assume all risk for your use of the Software.
+
+### 7. Termination
+
+This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License.
+
+### 8. General
+
+This License shall be governed by the laws of the country where the Licensor is located.
+
+If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
diff --git a/README.md b/README.md
index e7ba389..1408b15 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,8 @@
-# Webview Manager
-### The premier systemless solution for changing default browser and WebView.
+# Webview manager
+### The ultimate systemless solution for changing default browser and WebView
+
+**Do not directly download this repo.** Download from our website or FoxMMM only.
+
## Support
[](https://telegram.dog/androidacy_discussions)
diff --git a/common/addon/Volume-Key-Selector/install.sh b/common/addon/Volume-Key-Selector/install.sh
index f7c47b3..5bacfcc 100755
--- a/common/addon/Volume-Key-Selector/install.sh
+++ b/common/addon/Volume-Key-Selector/install.sh
@@ -1,24 +1,28 @@
-#!/bin/bash
-chmod -R 0755 $MODPATH/common/addon/Volume-Key-Selector/tools
+# shellcheck shell=dash
+# External Tools
+chmod -R 0755 "$MODPATH"/common/addon/Volume-Key-Selector/tools
+# shellcheck disable=SC2139
+alias keycheck="$MODPATH"/common/addon/Volume-Key-Selector/tools/"$ARCH"/keycheck
chooseport_legacy() {
# Keycheck binary by someone755 @Github, idea for code below by Zappo @xda-developers
# Calling it first time detects previous input. Calling it second time will do what we want
- [ "$1" ] && local delay=$1 || local delay=3
+ if [ -n "$1" ]; then
+ local delay=$1
+ else
+ local delay=5
+ fi
local error=false
while true; do
- timeout 0 $MODPATH/common/addon/Volume-Key-Selector/tools/$ARCH32/keycheck
- timeout $delay $MODPATH/common/addon/Volume-Key-Selector/tools/$ARCH32/keycheck
+ timeout 0 keycheck
+ timeout "$delay" keycheck
local sel=$?
if [ $sel -eq 42 ]; then
return 0
elif [ $sel -eq 41 ]; then
return 1
elif $error; then
- echo "Volume key could not be detected!"
- echo "Falling back to config file..."
- export KEYCHECK_FAIL=true
- return 0
+ abort "Volume key not detected!"
else
error=true
echo "Volume key not detected. Try again"
@@ -27,27 +31,35 @@ chooseport_legacy() {
}
chooseport() {
- # Original idea by chainfire and ianmacd @xda-developers
- [ "$1" ] && local delay=$1 || local delay=3
- local error=false
+ if [ -n "$1" ]; then
+ local delay=$1
+ else
+ local delay=5
+ fi
+ local error=false
while true; do
local count=0
while true; do
- timeout $delay /system/bin/getevent -lqc 1 2>&1 >$TMPDIR/events &
- sleep 1
+ if [ ! -d "$TMPDIR" ]; then
+ mkdir -p "$TMPDIR"
+ fi
+ if [ -f "$TMPDIR"/events ]; then
+ rm -f "$TMPDIR"/events
+ fi
+ timeout "$delay" /system/bin/getevent -lqc 1 > "$TMPDIR"/events 2>&1
count=$((count + 1))
- if ($(grep -q 'KEY_VOLUMEUP *DOWN' $TMPDIR/events)); then
+ if grep -q "KEY_VOLUMEUP *DOWN" "$TMPDIR"/events; then
return 0
- elif ($(grep -q 'KEY_VOLUMEDOWN *DOWN' $TMPDIR/events)); then
+ elif grep -q "KEY_VOLUMEDOWN *DOWN" "$TMPDIR"/events; then
return 1
fi
- [ $count -gt 5 ] && break
+ [ $count -gt 3 ] && break
done
if $error; then
# abort "Volume key not detected!"
- echo "Volume key not detected. Trying legacy method"
+ echo "Volume key not detected. Trying keycheck method"
export chooseport=chooseport_legacy VKSEL=chooseport_legacy
- chooseport_legacy $delay
+ chooseport_legacy "$delay"
return $?
else
error=true
@@ -55,6 +67,9 @@ chooseport() {
fi
done
}
-
+if [ ! -d "$TMPDIR" ]; then
+ mkdir -p "$TMPDIR"
+fi
+echo "" > "$TMPDIR"/events
# Keep old variable from previous versions of this
-VKSEL=chooseport
+VKSEL=chooseport
\ No newline at end of file
diff --git a/common/addon/Volume-Key-Selector/tools/arm64/keycheck b/common/addon/Volume-Key-Selector/tools/arm64/keycheck
new file mode 100644
index 0000000..fbbab22
Binary files /dev/null and b/common/addon/Volume-Key-Selector/tools/arm64/keycheck differ
diff --git a/common/addon/Volume-Key-Selector/tools/x86/keycheck b/common/addon/Volume-Key-Selector/tools/x86/keycheck
deleted file mode 100755
index 8852b0d..0000000
Binary files a/common/addon/Volume-Key-Selector/tools/x86/keycheck and /dev/null differ
diff --git a/common/config.sh b/common/config.sh
new file mode 100644
index 0000000..9eb6840
--- /dev/null
+++ b/common/config.sh
@@ -0,0 +1,22 @@
+# shellcheck shell=dash
+
+#######################################
+## WebView Manager Global Settings ##
+## You probably don't want to edit it #
+## directly! ##
+## ##
+## Instead, use the easy install mode #
+## with volume keys (optional) #
+#######################################
+
+# Do not touch this unless instructed by support
+export ANDROIDACY_API_SDK_DEBUG_STATUS="OFF"
+
+# false for any of these variables will disable the feature
+# Choose your webview. Options are bromite, chromium, mulch, or attempt to use browser
+export WEBVIEW_CONFIG="false"
+# Choose your browser. Options are chromium, brave, bromite, kiwi
+export BROWSER_CONFIG="false"
+# Master switch to use this file. Unless this is set to true, all values set above will not be used
+# Export this automatically when running this script
+export USE_CUSTOM_CONFIG=false
\ No newline at end of file
diff --git a/common/functions.sh b/common/functions.sh
index d93b46f..8bc0c11 100644
--- a/common/functions.sh
+++ b/common/functions.sh
@@ -1,6 +1,5 @@
-# shellcheck shell=ash
-# shellcheck disable=SC2061,SC3010,SC2166,SC2044,SC2046,SC2086,SC1090,SC2034,SC2155,SC1091
-# LETS FUCKING GOOOOOOO
+# shellcheck shell=ash disable=SC2061,SC3010,SC2166,SC2044,SC2046,SC2086,SC1090,SC2034,SC2155,SC1091,SC3020,SC2139
+
echo " __ __ _ _ "
echo " \ \ / /___ | |__ __ __(_) ___ __ __"
echo " \ \ /\ / // _ \| '_ \\\\\ \ / /| | / _ \\\\\ \ /\ / /"
@@ -13,8 +12,6 @@ echo " | | | || (_| || | | || (_| || (_| || __/| | "
echo " |_| |_| \__,_||_| |_| \__,_| \__, | \___||_| "
echo " |___/ "
unzip -o "$ZIPFILE" -x 'META-INF/*' 'common/functions.sh' -d $MODPATH >&2
-[ -f "$MODPATH/common/addon.tar.xz" ] && tar -xf $MODPATH/common/addon.tar.xz -C $MODPATH/common 2>/dev/null
-tar -xvf "$MODPATH/common/tools/tools.tar.xz" -C "$MODPATH/common/tools" >&2
it_failed() {
ui_print " "
ui_print "⚠ ⚠ ⚠ ⚠ ⚠ ⚠ ⚠ ⚠ ⚠ ⚠ ⚠ ⚠ ⚠ ⚠"
@@ -52,6 +49,15 @@ abort() {
rm -fr $TMPDIR 2>/dev/null
it_failed
}
+export abort
+# if $ARCH is not arm or arm64 we abort
+if [ "$ARCH" != "arm" ] && [ "$ARCH" != "arm64" ]; then
+ abort "✖ Your device isn't supported. ARCH found: [$ARCH], supported: [arm, arm64]."
+fi
+unzip "$MODPATH"/common/tools/tools.zip -q -d "$MODPATH"/common/tools
+chmod -R a+rx "$MODPATH"/common/tools
+alias jq="$MODPATH"/common/tools/jq-"$ARCH"
+alias curl="$MODPATH/common/tools/curl-$ARCH --dns-servers 1.1.1.1,1.0.0.1,8.8.8.8,8.8.4.4"
detect_ext_data() {
if touch /sdcard/.rw && rm /sdcard/.rw; then
export EXT_DATA="/sdcard/WebviewManager"
@@ -283,8 +289,11 @@ MODEL=$(getprop ro.product.model)
DEVICE=$(getprop ro.product.device)
ROM=$(getprop ro.build.display.id)
API=$(grep_prop ro.build.version.sdk)
+SDK=$API
+export BRAND MODEL DEVICE ROM API SDK
ui_print "ⓘ Logging verbosely to ${EXT_DATA}/logs"
+
### Logging functions
# Log
@@ -303,22 +312,17 @@ setup_logger() {
} >$LOGFILE
if test -f /sdcard/.androidacy-debug; then
set -x 2
- fi
+ fi
+ set -o pipefail
exec 2>>$LOGFILE
}
setup_logger
ui_print "ⓘ PLEASE NOTE: This module requires internet access!"
-alias aapt='$MODPATH/common/tools/$ARCH/aapt'
-alias curl='$MODPATH/common/tools/$ARCH/curl --dns-servers 1.1.1.1,1.0.0.1' # https://github.com/Zackptg5/Cross-Compiled-Binaries-Android/tree/master/build_script#dns-issues
-alias sign='$MODPATH/common/tools/zipsigner'
-chmod 755 "$MODPATH/common/tools/$ARCH/aapt"
-chmod 755 "$MODPATH/common/tools/$ARCH/curl"
-chmod 755 "$MODPATH/common/tools/zipsigner"
chmod 755 $MODPATH/common/tools/apiClient.sh
. $MODPATH/common/tools/apiClient.sh
-initClient
+initAPISDK
# Run addons
if [ "$(ls -A $MODPATH/common/addon/*/install.sh 2>/dev/null)" ]; then
@@ -333,6 +337,9 @@ ui_print "ⓘ Removing old files"
if [ -f $INFO ]; then
while read -r LINE; do
+ if case $LINE in /sdcard*) ;; *) false;; esac; then
+ continue
+ fi
if [ "$(echo -n $LINE | tail -c 1)" = "~" ]; then
continue
elif [ -f "$LINE~" ]; then
@@ -398,6 +405,7 @@ fi
# Set permissions
ui_print " "
ui_print "ⓘ Setting Permissions"
+set +x
set_perm_recursive $MODPATH 0 0 0755 0644
if [ -d $MODPATH/system/vendor ]; then
set_perm_recursive $MODPATH/system/vendor 0 0 0755 0644 u:object_r:vendor_file:s0
@@ -409,6 +417,7 @@ if [ -d $MODPATH/system/vendor ]; then
done
fi
set_permissions
+set -x 2
# Complete install
cleanup
diff --git a/common/install.sh b/common/install.sh
index 896bd9f..9d72254 100644
--- a/common/install.sh
+++ b/common/install.sh
@@ -1,529 +1,509 @@
-# shellcheck shell=ash
-# shellcheck disable=SC1091,SC1090,SC2139,SC2086,SC3010
+# shellcheck shell=ksh
+# shellcheck disable=SC1091,SC1090,SC2139,SC2086,SC3010,SC2034
+
TRY_COUNT=1
VF=0
VERIFY=true
-config_file="$EXT_DATA/config.conf"
+config_file="$EXT_DATA/config.sh"
+export webview=false
+export browser=false
A=$(resetprop ro.system.build.version.release || resetprop ro.build.version.release)
-ui_print "ⓘ $(echo "$DEVICE" | sed 's#%20#\ #g') with android $A, sdk$API, with an $ARCH cpu"
-ui_print "Checking for module updates..."
-updateChecker 'self'
-newVersion=$response
-log 'INFO' "Running update check with module $MODULE_VERSIONCODE and server version $newVersion"
-if test $MODULE_VERSIONCODE -lt $newVersion; then
- ui_print "Module update found! Please download the latest update manually, and flash in magisk manager."
- ui_print "Attempting to launch downloads page..."
- sleep 2
- am start -a android.intent.action.VIEW -d "https://www.androidacy.com/modules-repo/?utm_source=webvoewmanager&utm_medium=repo&utm_campaign=update_module#bromitewebview"
- ui_print "Exiting now!"
- exit 1
+# ui_print "Checking for module updates..."
+if ! dumpsys wifi | grep -q "Wi-Fi is enabled"; then
+ ui_print "You may not be connected to WiFi and may incur data charges!"
fi
-VEN=/system/vendor
-[ -L /system/vendor ] && VEN=/vendor
-if [ -f $VEN/build.prop ]; then
- export BUILDS="/system/build.prop $VEN/build.prop"
-else
- BUILDS="/system/build.prop"
-fi
-vol_sel() {
- log 'INFO' "Entering config"
- ui_print "ⓘ Starting config mode...."
- ui_print "ⓘ Press volume up now"
- export KEYCHECK_FAIL=false
- export USED_CONFIG=false
- if chooseport; then
- ui_print "ⓘ Press volume down now"
- if $KEYCHECK_FAIL || chooseport; then
- ui_print "Volume key not detected. Falling back to config file..."
- config_file_parse
- fi
- else
- ui_print "Volume key not detected or wrong key detected. Falling back to config file..."
- config_file_parse
- fi
- if ! $KEYCHECK_FAIL && ! $USED_CONFIG; then
- ui_print "ⓘ Press volume up to select, volume down for next option"
- sel_web() {
- unset WEBVIEW
- ui_print "-> Please choose your webview."
- ui_print "-> None"
- if chooseport; then
- WEBVIEW=0
- fi
- if [[ -z $WEBVIEW ]]; then
- ui_print " 1. Bromite (default)"
- if chooseport; then
- WEBVIEW=1
- fi
- fi
- if [[ -z $WEBVIEW ]]; then
- ui_print " 2. Chromium"
- if chooseport; then
- WEBVIEW=2
- fi
- fi
- if [[ -z $WEBVIEW ]]; then
- ui_print " 3. Ungoogled Chromium"
- if chooseport; then
- WEBVIEW=3
- fi
- fi
- if [[ -z $WEBVIEW ]]; then
- ui_print "-> No valid choice, using bromite"
- WEBVIEW=1
- fi
- }
- sel_browser() {
- unset BROWSER
- ui_print "-> Please choose your browser."
- ui_print "-> None"
- if chooseport; then
- BROWSER=0
- fi
- if [[ -z $BROWSER ]]; then
- ui_print " 1. Bromite"
- if chooseport; then
- BROWSER=1
- fi
- fi
- if [[ -z $BROWSER ]]; then
- ui_print " 2. Chromium"
- if chooseport; then
- BROWSER=2
- fi
- fi
- if [[ -z $BROWSER ]]; then
- ui_print " 3. Ungoogled Chromium"
- if chooseport; then
- BROWSER=3
- fi
- fi
- if [[ -z $BROWSER ]]; then
- ui_print "-> No valid choice, using bromite"
- BROWSER=1
- fi
- }
- sel_web
- sel_browser
- if test $WEBVIEW -ne 0; then
- download_webview
- fi
- if test $BROWSER -ne 0; then
- download_browser
- fi
- if test $WEBVIEW -eq 0 && $BROWSER -eq 0; then
- abort "No valid choice, bailing out!"
- fi
- fi
- log 'INFO' "User chose browser option $BROWSER, webview $WEBVIEW"
- # Edit the config file accordingly
- $USED_CONFIG || sed -i 's/^BROWSER=.*/BROWSER='"$BROWSER"'/gi' $config_file
- $USED_CONFIG || sed -i 's/^WEBVIEW=.*/WEBVIEW='"$WEBVIEW"'/gi' $config_file
- ui_print "ⓘ Config complete! Proceeding."
-}
-config_file_parse() {
- # Check if config file exists
- if [[ ! -f $config_file ]]; then
- cp -f "$MODDIR/config.conf" "$config_file"
- ui_print "Config file created at $config_file"
- ui_print "Proceeding with default settings: Bromite webview, Bromite browser"
- ui_print "If you want to change this, please edit the config file and reinsatll the module."
- sleep 3
- export BROWSER
- export WEBVIEW
- BROWSER=1
- WEBVIEW=1
- export USED_CONFIG=true
- else
- export BROWSER
- export WEBVIEW
- get_config_value 'BROWSER'
- BROWSER=$value
- get_config_value 'WEBVIEW'
- WEBVIEW=$value
- export USED_CONFIG=true
- fi
-}
-get_config_value() {
- local key=$1
- unset value
- export value
- value=$(<$config_file grep "^$key=" | cut -d '=' -f 2)
-}
-set_config() {
- ui_print "ⓘ Setting configs..."
- vol_sel
-}
-do_ungoogled_webview() {
- log 'INFO' 'Doing ungoogled-chromium webview'
- NAME="Ungoogled-Chromium"
- WV_PKG="com.android.webview"
- DIR='ugc-w'
- W_VER=$(updateChecker "$DIR")
-}
-do_ungoogled_browser() {
- log 'INFO' 'Doing ungoogled-chromium browser'
- NAME="Ungoogled-Chromium"
- DIR='ugc-b'
- B_VER=$(updateChecker "$DIR")
- if [[ $BROWSER -eq 3 ]]; then
- DIR='ugc-e'
- B_VER=$(updateChecker "$DIR")
- fi
-}
-do_vanilla_webview() {
- log 'INFO' 'Doing chromium webview'
- NAME="Chromium"
- WV_PKG="com.android.webview"
- DIR=chrm
- W_VER=$(updateChecker "$DIR")
-}
-do_vanilla_browser() {
- log 'INFO' 'Doing chromium browser'
- NAME="Chromium"
- DIR=chrm
- B_VER=$(updateChecker "$DIR")
-}
-do_bromite_webview() {
- log 'INFO' 'Doing bromite webview'
- NAME="Bromite"
- WV_PKG="org.bromite.webview"
- DIR=brm
- W_VER=$(updateChecker "$DIR")
+## Functions
+# Make sure all config values are what we expect them to be
+verify_config() {
+ local browser webview webview_custom browser_custom webview_type browser_type
+ $can_use_fmmm_apis && clearTerminal || echo ""
+ ui_print "Verifying config..."
+ $can_use_fmmm_apis && showLoading || echo ""
+ # So far everything is valid
+ . "$config_file"
+ # If USE_CUSTOM_CONFIG=false, then the user's config will not be used.
+ if $USE_CUSTOM_CONFIG; then
+ # Browser must be false, or set to chromium, brave, kiwi, or bromite
+ if [ "$BROWSER_CONFIG" = false ] || [ $BROWSER_CONFIG = chromium ] || [ $BROWSER_CONFIG = brave ] || [ $BROWSER_CONFIG = kiwi ] || [ $BROWSER_CONFIG = bromite ]; then
+ $can_use_fmmm_apis && hideLoading || echo ""
+ ui_print "Verified browser."
+ $can_use_fmmm_apis && showLoading || echo ""
+ browser=true
+ else
+ $can_use_fmmm_apis && hideLoading || echo ""
+ abort "⚠ BROWSER value was not valid."
+ fi
+ # Next, webview must be false, or set to chromium, mulch, or bromite
+ if [ "$WEBVIEW_CONFIG" = false ] || [ $WEBVIEW_CONFIG = chromium ] || [ $WEBVIEW_CONFIG = bromite ] || [ $WEBVIEW_CONFIG = mulch ]; then
+ $can_use_fmmm_apis && hideLoading || echo ""
+ ui_print "Verified webview choice."
+ $can_use_fmmm_apis && showLoading || echo ""
+ webview=true
+ else
+ $can_use_fmmm_apis && hideLoading || echo ""
+ abort "⚠ WEBVIEW value was not valid."
+ fi
+ # If both are false it's an invalid config
+ if [ "$browser" = false ] && [ "$webview" = false ]; then
+ $can_use_fmmm_apis && hideLoading || echo ""
+ abort "⚠ BROWSER and WEBVIEW were both set to false or invalid values."
+ fi
+ set_info "$BROWSER_CONFIG" "$WEBVIEW_CONFIG"
+ fi
+ ui_print "Verified config."
+ $can_use_fmmm_apis && hideLoading || echo ""
}
-do_bromite_browser() {
- log 'INFO' 'Doing bromite browser'
- NAME="Bromite"
- DIR=brm
- B_VER=$(updateChecker "$DIR")
+# Volume key selection logic
+volume_key_setup() {
+ # TODO: get a list of webviews and browsers from the API and present them to the user. Unfortunately, that could prevent us from sanely checking the config.
+ # First batch: WEBVIEW
+ $can_use_fmmm_apis && clearTerminal || echo ""
+ webview_chosen=false
+ need_browser_choice=false
+ KEYCHECK_FAIL=false
+ export webview_type webview browser_type browser
+ # First test the volume keys. Make user press up, then down, and make sure KEYCHECK_FAIL is not true.
+ ui_print "📈 Press volume UP."
+ if chooseport; then
+ if $KEYCHECK_FAIL; then
+ ui_print "- Vol keys Timed Out -"
+ abort "⚠ Timed out waiting for volume key events"
+ fi
+ ui_print "📉 Press volume DOWN."
+ if ! chooseport; then
+ if $KEYCHECK_FAIL; then
+ ui_print "- Vol keys Timed Out -"
+ abort "⚠ Timed out waiting for volume key events"
+ fi
+ ui_print " 👍 Setup volume keys successful!"
+ else
+ ui_print " 👎 Setup volume keys failed!"
+ abort "⚠ Unable to configure volume keys."
+ fi
+ else
+ ui_print " 👎 Setup volume keys failed!"
+ abort "⚠ Unable to configure volume keys."
+ fi
+ ui_print "Please select the webview you want to use. Custom and none can be selected after other options are shown."
+ ui_print "Option 1: Chromium"
+ # chooseport is how we detect volume key presses, we use it to detect which option is selected. Up is true, down is false
+ if chooseport; then
+ ui_print "Chose Chromium"
+ webview_type="chromium"
+ webview=true
+ webview_custom=false
+ webview_package="com.android.webview"
+ webview_chosen=true
+ fi
+ if [ "$webview_chosen" = false ]; then
+ ui_print "Option 2: Bromite"
+ if chooseport; then
+ ui_print "Chose Bromite"
+ webview_type="bromite"
+ webview=true
+ webview_custom=false
+ webview_package="org.bromite.webview"
+ webview_chosen=true
+ fi
+ fi
+ # Option 3 is mulch
+ if [ "$webview_chosen" = false ]; then
+ ui_print "Option 3: Mulch"
+ if chooseport; then
+ ui_print "Chose Mulch"
+ webview_type="mulch"
+ webview=true
+ webview_custom=false
+ webview_package="com.android.webview"
+ webview_chosen=true
+ fi
+ fi
+ # Option 4 is to try to use browser as webview
+ if [ "$webview_chosen" = false ]; then
+ ui_print "Option 4: Browser as webview"
+ if chooseport; then
+ ui_print "Chose Browser as webview"
+ webview_type="browser"
+ webview=true
+ webview_custom=false
+ webview_chosen=true
+ need_browser_choice=true
+ fi
+ fi
+ if [ "$webview_chosen" = false ]; then
+ ui_print "Option 5: None"
+ if chooseport; then
+ ui_print "Chose None"
+ webview=false
+ webview_custom=false
+ webview_chosen=true
+ fi
+ fi
+ # Second batch: BROWSER
+ # Choices are (in order): Chromium, Bromite, Brave, Kiwi, Custom, and None
+ # None cannot be selected if need_browser_choice is true
+ browser_chosen=false
+ ui_print "Please select the browser you want to use. Custom and none can be selected after other options are shown."
+ ui_print "Option 1: Chromium"
+ if chooseport; then
+ ui_print "Chose Chromium"
+ browser_type="chromium"
+ browser=true
+ browser_custom=false
+ browser_chosen=true
+ fi
+ if [ "$browser_chosen" = false ]; then
+ ui_print "Option 2: Bromite"
+ if chooseport; then
+ ui_print "Chose Bromite"
+ browser_type="bromite"
+ browser=true
+ browser_custom=false
+ browser_chosen=true
+ fi
+ fi
+ if [ "$browser_chosen" = false ]; then
+ ui_print "Option 3: Custom"
+ if chooseport; then
+ ui_print "Chose Custom"
+ browser_type="custom"
+ browser=true
+ browser_custom=true
+ browser_chosen=true
+ fi
+ fi
+ if [ "$need_browser_choice" = false ]; then
+ if [ "$browser_chosen" = false ]; then
+ ui_print "Option 4: None"
+ if chooseport; then
+ ui_print "Chose None"
+ browser=false
+ browser_custom=false
+ browser_chosen=true
+ fi
+ fi
+ # ui_print "ⓘ Saving config"
+ # set_config_values
+ if [ $webview ]; then
+ ui_print "ⓘ Setting up webviews..."
+ download_webview 'webview' $webview_type
+ detect_and_debloat
+ fi
+ if [ $browser ]; then
+ ui_print "ⓘ Setting up browser..."
+ download_webview 'browser' $browser_type
+ fi
+ else
+ ui_print "You chose to use browser as webview, but did not select a browser. Bailing."
+ abort "Browser as webview selected, but no browser selected"
+ fi
}
-# Get the available list of webviews and browsers
-get_available_list() {
- local available_wv_list
- getList "webviews"
- available_wv_list=$value
- local available_b_list
- getList "browsers"
- available_b_list=$value
- export available_wv_list
- export available_b_list
+set_info() {
+ # Similar to above, set some variables based on the passed in WEBVIEW_CONFIG and BROWSER_CONFIG strings
+ if [ "$2" = "chromium" ]; then
+ webview_type="chromium"
+ webview=true
+ webview_custom=false
+ webview_package="org.bromite.chrome"
+ webview_chosen=true
+ elif [ "$2" = "bromite" ]; then
+ webview_type="bromite"
+ webview=true
+ webview_custom=false
+ webview_package="org.bromite.bromite"
+ webview_chosen=true
+ elif [ "$2" = "browser" ]; then
+ webview_type="browser"
+ webview=true
+ webview_custom=false
+ webview_chosen=true
+ elif [ "$2" = "mulch" ]; then
+ webview_type="mulch"
+ webview=true
+ webview_custom=false
+ webview_package="com.android.webview"
+ webview_chosen=true
+ elif [ "$2" = "none" ]; then
+ webview=false
+ webview_custom=false
+ webview_chosen=true
+ else
+ ui_print "Unknown WEBVIEW_CONFIG value passed in... bailing"
+ abort "Unknown value for WEBVIEW_CONFIG passed in."
+ fi
+ # Same for browser
+ if [ "$1" = "chromium" ]; then
+ browser_type="chromium"
+ browser=true
+ browser_custom=false
+ browser_package="org.bromite.chrome"
+ browser_chosen=true
+ elif [ "$1" = "bromite" ]; then
+ browser_type="bromite"
+ browser=true
+ browser_custom=false
+ browser_package="org.bromite.bromite"
+ browser_chosen=true
+ elif [ "$1" = "browser" ]; then
+ browser_type="browser"
+ browser=true
+ browser_custom=false
+ browser_chosen=true
+ elif [ "$1" = "custom" ]; then
+ browser_type="custom"
+ browser=true
+ browser_custom=true
+ browser_chosen=true
+ elif [ "$1" = "none" ]; then
+ if $need_browser_choice; then
+ ui_print "You chose to use browser as webview but no browser was selected. Bailing."
+ abort "Browser as webview selected, but no browser selected."
+ else
+ browser=false
+ browser_custom=false
+ browser_chosen=true
+ fi
+ # return 0;
+ else
+ ui_print "Unknown BROWSER_CONFIG value passed in... bailing"
+ abort "Unknown value for BROWSER_CONFIG passed in."
+ fi
}
-# Iterate over webviews and browsers, prompting the user to choose one: chooseport being true means the user chose that, false means move on
-sel_web_v2() {
- local list=$available_wv_list
-}
-old_version() {
- local NAME=$1
- local TYPE=$2
- log 'INFO' 'Getting version information'
- ui_print "ⓘ Checking whether this is a new install...."
- if [ -f "${EXT_DATA}/apks/${NAME}${TYPE}.apk.version" ]; then
- ui_print "-> This is an old install, using existing version file"
- OLD_VER=$(cat "${EXT_DATA}/apks/${NAME}${TYPE}.apk.version")
- else
- ui_print "-> This is a new install, creating version file"
- OLD_VER=0
- echo "$OLD_VER" >"${EXT_DATA}/apks/${NAME}${TYPE}.apk.version"
- fi
- export OLD_VER
+use_cached_webview() {
+ export use_cached
+ use_cached=false
+ # check if "$EXT_DATA/apks/$which-$type.apk" and "$EXT_DATA/apks/$which-$type.apk.sha256sum" exist and are less than a day old
+ # if so, verify the sha256sum and set use_cached to true
+ local which type
+ type=$2
+ which=$1
+ if [ -f "$EXT_DATA/apks/$which-$type.apk" ] && [ -f "$EXT_DATA/apks/$which-$type.sha256sum" ]; then
+ local apk_sha256sum apk_sha256sum_new
+ apk_sha256sum=$(cat "$EXT_DATA/apks/$which-$type.sha256sum")
+ apk_sha256sum_new=$(sha256sum "$EXT_DATA/apks/$which-$type.apk" | cut -d ' ' -f 1)
+ if [ "$apk_sha256sum" = "$apk_sha256sum_new" ]; then
+ local apk_age=$(($(date +%s) - $(date +%s -r "$EXT_DATA/apks/$which-$type.apk")))
+ if [ $apk_age -lt 86400 ]; then
+ use_cached=true
+ fi
+ fi
+ fi
}
+# Downloads a webview using makeFileRequest and then extracts it using unzip.
download_webview() {
- log 'INFO' 'Downloading webview'
- cd "$TMPDIR" || return
- if [[ $WEBVIEW -eq 1 ]]; then
- do_bromite_webview
- elif [[ $WEBVIEW -eq 2 ]]; then
- do_vanilla_webview
- else
- do_ungoogled_webview
- fi
- if [[ "$VF" -eq 1 ]]; then
- ui_print "ⓘ Redownloading ${NAME} webview, attempt number ${TRY_COUNT}, please be patient..."
- downloadFile "$DIR" "webview${ARCH}" "apk" "${EXT_DATA}/apks/${NAME}Webview.apk"
- sed -i "/OLD_WEBVIEW/d" "$VERSIONFILE"
- echo "OLD_WEBVIEW=$(echo "$W_VER" | sed 's/[^0-9]*//g')" >>"$VERSIONFILE"
- else
- old_version "$NAME" "Webview"
- fi
- if [[ -f $EXT_DATA/apks/"$NAME"Webview.apk ]]; then
- if [[ $OLD_VER -lt "$(echo "$W_VER" | sed 's/[^0-9]*//g' | tr -d '.')" ]]; then
- ui_print "ⓘ Downloading update for ${NAME} webview, please be patient..."
- downloadFile "$DIR" "webview${ARCH}" "apk" "${EXT_DATA}/apks/${NAME}Webview.apk"
- "$(echo "$W_VER" | sed 's/[^0-9]*//g')" >"${EXT_DATA}/apks/${NAME}Webview.apk.version"
- else
- ui_print "☑ Not a version upgrade! Using existing ${NAME} webview apk"
- fi
- else
- ui_print "ⓘ No existing apk found for ${NAME} webview!"
- ui_print "ⓘ Downloading ${NAME} webview, please be patient..."
- downloadFile "$DIR" "webview${ARCH}" "apk" "${EXT_DATA}/apks/${NAME}Webview.apk"
- "$(echo "$W_VER" | sed 's/[^0-9]*//g')" >"${EXT_DATA}/apks/${NAME}Webview.apk.version"
- fi
- verify_w
-}
-download_browser() {
- og 'INFO' 'Downloading browser'
- cd "$TMPDIR" || return
- if [[ $BROWSER -eq 1 ]]; then
- do_bromite_browser
- elif [[ $BROWSER -eq 2 ]]; then
- do_vanilla_browser
- else
- do_ungoogled_browser
- fi
- if [[ "$VF" -eq 1 ]]; then
- ui_print "ⓘ Redownloading ${NAME} browser, please be patient..."
- downloadFile "$DIR" "browser${ARCH}" "apk" "${EXT_DATA}/apks/${NAME}Browser.apk"
- "$(echo "$B_VER" | sed 's/[^0-9]*//g')" >"${EXT_DATA}/apks/${NAME}Browser.apk.version"
- else
- old_version "$NAME" "Browser"
- fi
- if [[ -f $EXT_DATA/apks/"$NAME"Browser.apk ]]; then
- if [[ $OLD_VER -lt "$(echo "$B_VER" | sed 's/[^0-9]*//g' | tr -d '.')" ]]; then
- ui_print "ⓘ Downloading update for ${NAME} browser, please be patient..."
- downloadFile "$DIR" "browser${ARCH}" "apk" "${EXT_DATA}/apks/${NAME}Browser.apk"
- "$(echo "$B_VER" | sed 's/[^0-9]*//g')" >>"${EXT_DATA}/apks/${NAME}Browser.apk.version"
- else
- ui_print "☑ Not a version upgrade! Using existing ${NAME} browser apk"
- fi
- else
- ui_print "ⓘ No existing apk found for ${NAME} browser!"
- ui_print "ⓘ Downloading ${NAME} browser, please be patient..."
- downloadFile "$DIR" "browser${ARCH}" "apk" "${EXT_DATA}/apks/${NAME}Browser.apk"
- "$(echo "$B_VER" | sed 's/[^0-9]*//g')" >>"${EXT_DATA}/apks/${NAME}Browser.apk.version"
- fi
- verify_b
-}
-verify_w() {
- log 'INFO' 'Verifying webview'
- ui_print "ⓘ Verifying ${NAME} webview files..."
- if $VERIFY; then
- cd "$EXT_DATA"/apks || return
- O_S=$(/data/adb/magisk/busybox sha256sum "$NAME"Webview.apk | sed "s/\ $NAME.*//" | tr -d '[:space:]')
- getChecksum "$DIR" "webview${ARCH}" "apk"
- # shellcheck disable=SC2154
- T_S=$(echo "$response" | tr -d '[:space:]')
- if [ "$T_S" != "$O_S" ]; then
- log 'ERROR' 'Invalid webview file digest'
- ui_print "⚠ Verification failed, retrying download"
- rm -f "$EXT_DATA"/apks/*Webview.apk
- TRY_COUNT=$((TRY_COUNT + 1))
- VF=1
- if [[ ${TRY_COUNT} -gt 3 ]]; then
- it_failed
- else
- cd "$TMPDIR" || return
- download_webview
- fi
- else
- ui_print "☑ Verified successfully. Proceeding..."
- VF=0
- rm -fr -- *"$ARCH"*.apk
- extract_webview
- fi
- else
- ui_print "⚠ ${NAME} cannot be verified, as they don't publish sha256sums."
- fi
- cd "$TMPDIR" || return
-}
-verify_b() {
- log 'INFO' 'Verifying browser'
- ui_print "ⓘ Verifying ${NAME} browser files..."
- if $VERIFY; then
- cd "$EXT_DATA"/apks || return
- O_S=$(/data/adb/magisk/busybox sha256sum "$NAME"Browser.apk | sed "s/\ $NAME.*//" | tr -d '[:space:]')
- getChecksum "$DIR" "browser${ARCH}" "apk"
- T_S=$(echo "$response" | tr -d '[:space:]')
- if [ "$T_S" != "$O_S" ]; then
- log 'ERROR' 'Invalid browser file digest'
- ui_print "⚠ Verification failed, retrying download"
- rm -f "$EXT_DATA"/apks/*Browser.apk
- TRY_COUNT=$((TRY_COUNT + 1))
- VF=1
- if [[ ${TRY_COUNT} -gt 3 ]]; then
- it_failed
- else
- cd "$TMPDIR" || return
- download_browser
- fi
- else
- ui_print "☑ Verified successfully. Proceeding..."
- VF=0
- rm -fr -- *"$ARCH"*.apk
- extract_browser
- fi
- else
- ui_print "⚠ ${NAME} cannot be verified, as they don't publish sha256sums."
- extract_browser
- fi
- cd "$TMPDIR" || return
-}
-create_overlay() {
- log 'INFO' 'Creating overlays'
- cd "$TMPDIR" || return
- # We have to replace ##WV_NAME## with the name of the webview and ##WV_PKG## with the package name of the webview
- ui_print "ⓘ Fixing system webview whitelist"
- if [[ "${API}" -ge "29" ]]; then
- sed -i "s/##WV_NAME##/${NAME}/g" "$MODPATH"/common/overlay10/res/xml/config_webview_packages.xml
- sed -i "s/##WV_PKG##/${WV_PKG}/g" "$MODPATH"/common/overlay10/res/xml/config_webview_packages.xml
- aapt p -f -v -M "$MODPATH"/common/overlay10/AndroidManifest.xml -I /system/framework/framework-res.apk -S "$MODPATH"/common/overlay10/res -F "$MODPATH"/unsigned.apk >"$MODPATH"/logs/aapt.log
- else
- sed -i "s/##WV_NAME##/${NAME}/g" "$MODPATH"/common/overlay9/res/xml/config_webview_packages.xml
- sed -i "s/##WV_PKG##/${WV_PKG}/g" "$MODPATH"/common/overlay9/res/xml/config_webview_packages.xml
- aapt p -f -v -M "$MODPATH"/common/overlay9/AndroidManifest.xml -I /system/framework/framework-res.apk -S "$MODPATH"/common/overlay9/res -F "$MODPATH"/unsigned.apk >"$MODPATH"/logs/aapt.log
- fi
- if [[ -f "$MODPATH"/unsigned.apk ]]; then
- sign "$MODPATH"/unsigned.apk "$MODPATH"/signed.apk
- cp -rf "$MODPATH"/signed.apk "$MODPATH"/common/WebviewOverlay.apk
- rm -rf "$MODPATH"/signed.apk "$MODPATH"/unsigned.apk
- else
- log 'ERROR' 'Could not create overlay'
- ui_print "⚠ Overlay creation has failed! Poorly designed ROMs have this issue"
- ui_print "⚠ Compatibility is unlikely, please report this to your ROM developer."
- ui_print "⚠ Some ROMs need a patch to fix this."
- ui_print "⚠ Do NOT report this issue to us."
- sleep 1
- fi
- cp -f "$MODPATH"/logs/aapt.log "$EXT_DATA"/logs
- if [ -d /system_ext/overlay ]; then
- OLP=/system/system_ext/overlay
- elif [ -d /product/overlay ]; then
- OLP=/system/product/overlay
- elif [ -d /vendor/overlay ]; then
- OLP=/system/vendor/overlay
- elif [ -d /system/overlay ]; then
- OLP=/system/overlay
- fi
- mkdir -p "$MODPATH""$OLP"
- cp_ch "$MODPATH"/common/WebviewOverlay.apk "$MODPATH""$OLP"
- echo "$OLP" >"$MODPATH"/overlay.txt
+ # Make sure which was passed as first argument and type as second arg
+ if [ -z "$1" ] || [ -z "$2" ]; then
+ abort "No webview type passed to download_webview"
+ fi
+ local type=$2
+ local which=$1
+ $can_use_fmmm_apis && showLoading || echo ""
+ use_cached_webview $which $type
+ # Make a temporary directory to download the webview to
+ webview_tmp_dir="/data/local/tmp/$which-tmp"
+ if [ -d "$webview_tmp_dir" ]; then
+ rm -rf $webview_tmp_dir
+ mkdir -p $webview_tmp_dir
+ else
+ mkdir -p $webview_tmp_dir
+ fi
+ if ! $use_cached; then
+ ui_print "Downloading $which..."
+ makeFileRequest "/modules/webviewmanager/$which/download/$type" 'GET' "arch=$ARCH" "$webview_tmp_dir/$type.apk"
+ # Next, verify and install the webview
+ if [ ! -f "$webview_tmp_dir/$type.apk" ]; then
+ ui_print "Download failed"
+ abort "Download failed"
+ fi
+ else
+ ui_print "Using cached $which..."
+ cp_ch $EXT_DATA/apks/$which-$type.apk $webview_tmp_dir/$type.apk
+ fi
+ $can_use_fmmm_apis && hideLoading || echo ""
+ ui_print "Download successful"
+ verify_and_install_webview $webview_tmp_dir/$type.apk $which $type
}
-extract_webview() {
- log 'INFO' 'Extracting webview package'
- WPATH="/system/app/${NAME}Webview"
- ui_print "ⓘ Installing ${NAME} Webview"
- # Replace all existing webviews. This is a workaround for the fact that the ROMs may prefer to use a different webview
- for i in "com.android.chrome" "com.android.webview" "com.google.android.webview"; do
- local path
- unsanitized_path=$(cmd package dump "$i" | grep codePath)
- path=${unsanitized_path##*=}
- if [ -d "$path" ]; then
- mktouch "$MODPATH""$PATH"/.replace
- fi
- done
- mktouch "$MODPATH"$WPATH/.replace
- cp_ch "$EXT_DATA"/apks/"$NAME"Webview.apk "$MODPATH"$WPATH/webview.apk || cp_ch "$EXT_DATA"/apks/webview.apk "$MODPATH"$WPATH/webview.apk
- cp "$MODPATH"$WPATH/webview.apk "$TMPDIR"/webview.zip
- mkdir -p "$TMPDIR"/webview "$MODPATH"$WPATH/lib/arm64 "$MODPATH"$WPATH/lib/arm
- unzip -d "$TMPDIR"/webview "$TMPDIR"/webview.zip >/dev/null
- cp -rf "$TMPDIR"/webview/lib/arm64-v8a/* "$MODPATH"$WPATH/lib/arm64
- cp -rf "$TMPDIR"/webview/lib/armeabi-v7a/* "$MODPATH"$WPATH/lib/arm
- rm -rf "$TMPDIR"/webview "$TMPDIR"/webview.zip
- create_overlay
+# Verifies and installs a webview
+verify_and_install_webview() {
+ # Make sure which was passed as second argument and type as third arg
+ if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then
+ abort "No webview type passed to verify_and_install_webview"
+ fi
+ local type=$3
+ local which=$2
+ local apk=$1
+ ui_print "Verifying $which..."
+ $can_use_fmmm_apis && showLoading || echo ""
+ # Get the SHA256 hash of the webview
+ local sha256
+ # use busybox from magisk to get sha256sum
+ if [ -f "/sbin/sha256sum" ]; then
+ sha256=$(/sbin/sha256sum $apk | cut -d' ' -f1)
+ else
+ sha256=$(sha256sum $apk | cut -d' ' -f1)
+ fi
+ # POST the hash to the server to get the hash of the webview to compare with
+ local status
+ status=$(makeJSONRequest "/modules/webviewmanager/verify/$which/$type" "arch=$ARCH&client_hash=$sha256" 'GET' 'verified')
+ # Make sure status is true
+ if [ "$status" = "true" ]; then
+ ui_print "Verification successful"
+ $can_use_fmmm_apis && hideLoading || echo ""
+ ui_print "Installing $which..."
+ $can_use_fmmm_apis && showLoading || echo ""
+ # Install the webview
+ mkdir -p $MODPATH/system/app/$which-$type/lib
+ mkdir -p $MODPATH/system/app/$which-$type/lib/arm
+ mkdir -p $MODPATH/system/app/$which-$type/lib/arm64
+ unzip -q $apk 'lib/*' -d $webview_tmp_dir/$type
+ cp_ch -r $webview_tmp_dir/$type/lib/arm64-v8a/* $MODPATH/system/app/$which-$type/lib/arm64/
+ cp_ch -r $webview_tmp_dir/$type/lib/armeabi-v7a/* $MODPATH/system/app/$which-$type/lib/arm/
+ cp_ch $apk "$MODPATH/system/app/$which-$type/$type.apk"
+ cp_ch $MODPATH/system/app/$which-$type/$type.apk "$EXT_DATA/apks/$which-$type.apk"
+ # echo the expected sha256 hash to a file
+ echo $sha256 >"$EXT_DATA/apks/$which-$type.sha256sum"
+ mktouch $MODPATH/system/app/$which-$type/.replace
+ if [ "$which" == 'webview' ]; then
+ detect_and_debloat
+ generate_overlay
+ fi
+ $can_use_fmmm_apis && hideLoading || echo ""
+ ui_print "Installation complete"
+ else
+ ui_print "Verification failed: $status"
+ abort "Verification failed"
+ fi
}
-extract_browser() {
- log 'INFO' 'Extracting browser package'
- BPATH="/system/app/${NAME}Browser"
- ui_print "ⓘ Installing ${NAME} Browser"
- for i in "com.android.chrome" "com.android.browser" "org.lineageos.jelly"; do
- local path
- unsanitized_path=$(cmd package dump "$i" | grep codePath)
- path=${unsanitized_path##*=}
- if [ -d "$path" ]; then
- mktouch "$MODPATH""$PATH"/.replace
- fi
- done
- mktouch "$MODPATH""$BPATH"/.replace
- cp_ch "$EXT_DATA"/apks/"$NAME"Browser.apk "$MODPATH"$BPATH/browser.apk || cp_ch "$EXT_DATA"/apks/browser.apk "$MODPATH"$BPATH/browser.apk
- cp_ch "$MODPATH"$BPATH/browser.apk "$TMPDIR"/browser.zip
- mkdir -p "$TMPDIR"/browser "$MODPATH"$BPATH/lib/arm64 "$MODPATH"$BPATH/lib/arm
- unzip -d "$TMPDIR"/browser "$TMPDIR"/browser.zip >/dev/null
- cp -rf "$TMPDIR"/browser/lib/arm64-v8a/* "$MODPATH"$BPATH/lib/arm64
- cp -rf "$TMPDIR"/browser/lib/armeabi-v7a/* "$MODPATH"$BPATH/lib/arm
- rm -rf "$TMPDIR"/browser "$TMPDIR"/browser.zip
+# Detect and debloat any existing webview
+detect_and_debloat() {
+ for item in "com.android.webvview" "com.google.android.webview" "org.mozilla.webview_shell" "com.android.chrome"; do
+ local is_installed path
+ is_installed=$(cmd package dump "$i" | grep codePath)
+ if [ -n "$is_installed" ]; then
+ path_name=$(echo $i | awk -F\. '{print $1}')
+ ui_print "Webview $item detected"
+ ui_print "Debloating $item"
+ path=${is_installed##*=}
+ mktouch $MODPATH/$path_name/.replace
+ fi
+ done
}
-online_install() {
- ui_print "☑ Awesome, you have internet"
- if [[ $WEBVIEW -ne 0 ]]; then
- download_webview
- fi
- if [[ $BROWSER -ne 0 ]]; then
- download_browser
- fi
+# This is actually really cool because all overlay generation is server side - we just need to tell the server what to make an overlay for by including sdk version, arch, which webview we used, and send over our framework-res.apk
+# This may take a minute or two, because it's 50mb+ uploads+downloads, but for now we don't throttle this part of the process which depending on resulting server load may change. Nonetheless, moving generation server side leads to more consistent results and opens up a lot more scalable possibilities for the future.
+generate_overlay() {
+ # Dynamically determine overlay path. Order of preference is /product/overlay -> /system_ext/overlay -> /system/overlay
+ if [ -d /product/overlay ]; then
+ device_overlay_path="$MODPATH/product/overlay"
+ elif [ -d /system_ext/overlay ]; then
+ device_overlay_path="$MODPATH/system_ext/overlay"
+ elif [ -d /system/overlay ]; then
+ device_overlay_path="$MODPATH/system/overlay"
+ else
+ ui_print "Unable to find a correct overlay path. Weird."
+ abort "Device has no valid overlay path?"
+ fi
+ $can_use_fmmm_apis && showLoading || echo ""
+ ui_print "Installing system overlay. Please be patient, this may take awhile..."
+ if [ ! -d $device_overlay_path ]; then
+ mkdir -p $device_overlay_path
+ fi
+ tar -caf fw.tar.bz2 framework-res.apk -C /system/framework 2>/dev/null
+ makeFileRequest "/modules/webviewmanager/$webview_type/generateOverlay?sdk=$SDK&arch=$ARCH" 'POST' "framework-res=@fw.tar.bz2" $device_overlay_path/AndroidacyWebViewOverlay.apk
+ if [ -f $device_overlay_path/AndroidacyWebViewOverlay.apk ]; then
+ $can_use_fmmm_apis && hideLoading || echo ""
+ ui_print "Overlay installed!"
+ ui_print ""
+ ui_print "Enjoy using a modern, updated webview! This should greatly improve browser"
+ ui_print "and app performance and stability."
+ else
+ ui_print "Overlay installation failed - this may be due to your device not supporting this feature"
+ ui_print "Continuing, but compatibility is not guaranteed"
+ fi
}
-do_install() {
- log 'INFO' 'Starting install'
- set_config
- if ! "$BOOTMODE"; then
- ui_print "ⓘ Detected recovery install! Aborting!"
- it_failed 1
- else
- online_install
- fi
- do_cleanup
+# Set the values in config.sh to what the user selected
+set_config_values() {
+ # Make sure config.sh exists
+ if [ ! -f "$config_file" ]; then
+ ui_print "No config.sh found"
+ abort "No config.sh found"
+ fi
+ # Set the values in the config.sh
+ $can_use_fmmm_apis && showLoading || echo ""
+ # Use sed to set the values in the config.sh
+ # Loop through WEBVIEW, BROWSER, WEBVIEW_TYPE, and BROWSER_TYPE
+ for i in WEBVIEW BROWSER WEBVIEW_TYPE BROWSER_TYPE; do
+ # Set the value in the config.sh by replacing the line containing the key with the new value
+ # Get value of the variable $i is set to
+ value=$(eval echo $i)
+ set_config_value $i $value
+ done
+ # Remove comma from second to last line in config.sh
+ $can_use_fmmm_apis && hideLoading || echo ""
+ ui_print "Config values set"
}
-clean_dalvik() {
- ui_print "⚠ Dalvik cache will be cleared next boot"
- ui_print "⚠ Expect longer boot time"
+
+# Checks for updates
+isUpdated() {
+ local ourVersion
+ # Get our current version defined in module.prop
+ ourVersion=$(grep_prop versionCode $TMPDIR/module.prop)
+ # Request the api for the version number of bromitewebview (our codename)
+ local status
+ status=$(makeJSONRequest "/modules/webviewmanager/versionCheck" "version=$ourVersion&device=$DEVICE&sdk=$SDK" "GET" ".status")
+ # If status is "error", then our version is out of date
+ if [ "$status" = "error" ]; then
+ ui_print "You are running an outdated version of this module"
+ ui_print "Update to get the latest and greatest features!"
+ # Launch browser with update url
+ am start -a android.intent.action.VIEW -d "https://www.androidacy.com/magisk-modules-repository/#bromiewebview" >/dev/null
+ abort
+ fi
}
-do_cleanup() {
- log 'INFO' 'Running cleanup'
- ui_print "ⓘ Cleaning up..."
- {
- echo "Heres some useful links:"
- echo " "
- echo "Website: https://www.androidacy.com"
- echo "Donate: https://www.androidacy.com/donate/"
- echo "Support and contact: https://www.anroidacy.com/contact/"
- } >"$EXT_DATA"/README.txt
- rm -f "$MODPATH"/system/app/placeholder
- rm -f "$MODPATH"/*.md
- ui_print "ⓘ Backing up important stuffs to module directory"
- mkdir -p "$MODPATH"/backup/
- cp /data/system/overlays.xml "$MODPATH"/backup/
- if [[ -d "$MODPATH"/product ]]; then
- if [[ -d "$MODPATH"/system/product ]]; then
- cp -rf "$MODPATH"/product/* "$MODPATH"/system/product/
- rm -fr "$MODPATH"/product/
- else
- mv "$MODPATH"/product/ "$MODPATH"/system/
- fi
- fi
- if [[ -d "$MODPATH"/system_ext ]]; then
- if [[ -d "$MODPATH"/system/systen_ext ]]; then
- cp -rf "$MODPATH"/system_ext/ "$MODPATH"/system/
- rm -fr "$MODPATH"/system_ext/
- else
- mv "$MODPATH"/system_ext/ "$MODPATH"/system/
- fi
- fi
- clean_dalvik
-}
-if [[ ${TRY_COUNT} -ge "3" ]]; then
- it_failed
+isUpdated
+## Install logic
+# Master switch for allowing FoxMMM APIs to be used
+export can_use_fmmm_apis
+if [ -n "$MMM_EXT_SUPPORT" ]; then
+ ui_print "Installing in FoxMMM mode..."
+ can_use_fmmm_apis=true
+else
+ ui_print "Installing in normal mode..."
+ can_use_fmmm_apis=false
+fi
+
+# Source the config if it exists
+if [ -f $config_file ]; then
+ . $config_file
+ ignore_config=false
+else
+ # cp_ch "$MODPATH/common/config.sh" $config_file
+ ignore_config=true
+fi
+if [ "$ignore_config" = true ]; then
+ ui_print "ⓘ Config file not found, starting setup..."
+ volume_key_setup
else
- do_install
+ ui_print "ⓘ Config file found! If you don't want to use it, delete it and restart the installation."
+ ui_print "ⓘ Verifying config file..."
+ verify_config
+ if $USE_CONFIG; then
+ ui_print "ⓘ Using config file..."
+ # Set the values in the config.sh to the values in the config file
+ if [ $webview ]; then
+ ui_print "ⓘ Setting up webviews..."
+ download_webview 'webview' $webview_type
+ detect_and_debloat
+ fi
+ if [ $browser ]; then
+ ui_print "ⓘ Setting up browser..."
+ download_webview 'browser' $browser_type
+ fi
+ else
+ ui_print "ⓘ Starting setup..."
+ volume_key_setup
+ ui_print "ⓘ Completed setup"
+ fi
+ if [ ! $webview ] && [ ! $browser ]; then
+ abort "Nothing chosen!"
+ fi
fi
-ui_print ' '
-ui_print "ⓘ Some stock apps have been systemlessly debloated"
-sleep 0.25
-ui_print "ⓘ Anything debloated is known to cause conflicts"
-sleep 0.25
-ui_print "ⓘ Such as Chrome, Google WebView, etc"
-sleep 0.25
-ui_print "ⓘ It is recommended not to reinstall them"
-sleep 0.25
-ui_print " "
-sleep 0.25
-ui_print ">>> Webview Manager | By Androidacy <<<"
-sleep 0.25
-ui_print " "
-sleep 0.25
-ui_print "☑ Donate at https://www.androidacy.com/donate/"
-sleep 0.25
-ui_print "☑ Website, how to get support and blog is at https://www.androidacy.com"
-sleep 0.25
-ui_print "☑ Install apparently succeeded, please reboot ASAP"
-am start -a android.intent.action.VIEW -d "https://www.androidacy.com/install-done/?f=wvm_module&r=wmi&v=$MODULE_VERSION" &>/dev/null
-sleep 0.25
-ui_print " "
diff --git a/common/overlay10/AndroidManifest.xml b/common/overlay10/AndroidManifest.xml
deleted file mode 100644
index 84dd513..0000000
--- a/common/overlay10/AndroidManifest.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
diff --git a/common/overlay10/res/xml/config_webview_packages.xml b/common/overlay10/res/xml/config_webview_packages.xml
deleted file mode 100644
index 537417b..0000000
--- a/common/overlay10/res/xml/config_webview_packages.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
- 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
-
-
-
diff --git a/common/overlay9/AndroidManifest.xml b/common/overlay9/AndroidManifest.xml
deleted file mode 100644
index 9d32029..0000000
--- a/common/overlay9/AndroidManifest.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/common/overlay9/res/xml/config_webview_packages.xml b/common/overlay9/res/xml/config_webview_packages.xml
deleted file mode 100644
index 7a316d8..0000000
--- a/common/overlay9/res/xml/config_webview_packages.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
- 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
-
-
-
-
diff --git a/common/tools/apiClient.sh b/common/tools/apiClient.sh
index cec6f64..2d35ddf 100644
--- a/common/tools/apiClient.sh
+++ b/common/tools/apiClient.sh
@@ -1,294 +1,147 @@
-#!/bin/bash
+# shellcheck shell=ash disable=SC3045
+VERSION="1.3"
-# Title: Androidacy API shell client
-# Description: Provides an interface to the Androidacy API
-# License: AOSL (Androidacy Open Source License)
-# Version: 2.4.1
-# Author: Androidacy or it's partners
+# Ensure curl is installed as we'll be using it
+if ! curl --version >/dev/null; then
+ echo "curl not found. Your magisk installation may be corrupt. Please reinstall Magisk."
+ abort
+fi
+
+# Attempt to ping productions API. If we cannot, it means our API is down or users don't have internet.
+status=$(curl --http2-prior-knowledge -sL --output /dev/null -w "%{http_code}" https://production-api.androidacy.com/ping)
+if [ "$status" != "200" ] && [ "$status" != "204" ]; then
+ echo "Unable to ping API server: $?. Please try again later."
+ abort
+fi
-__api_tries=0
-# JSON parser
-# NOTE TO INTERNAL TEAM: Please don't waste your time trying to understand or improve this. It Just Works(tm)
+# if abort is not defined, alias it to exit 1
+if [ -z "$(LC_ALL=C type -t abort)" ] || [ ! "$(LC_ALL=C type -t abort)" = function ]; then
+ alias abort="exit 1"
+fi
+
+# Wrap jq in a parseJSON function so that the logic is hidden
parseJSON() {
- echo "$1" | sed 's/[{}]/''/g' | awk -v k="text" '{n=split($0,a,","); for (i=1; i<=n; i++) print a[i]}' | sed 's/\"\:\"/\|/g' | sed 's/[\,]/ /g' | sed 's/\"//g' | grep -w "$2" | cut -d"|" -f2
+ local pattern
+ # prepend . if not present
+ first_char="$(printf %.1s "$1")"
+ if [ "$first_char" != "." ]; then
+ pattern=".$1"
+ else
+ pattern="$1"
+ fi
+ local json
+ json=$(cat -)
+ echo "$json" | jq "$pattern" 2>/dev/null;
}
-# Handles API errors.
-# Delete the /sdcard/.androidacy file/folder if it exists, and try this three times.
-# If it still doesn't work, then exit.
-handleError() {
- if test $__api_tries -lt 3; then
- __api_tries=$((__api_tries + 1))
- rm -rf /sdcard/.aapi/.credentials
- sleep 0.5
- initTokens
- echo "[WARNING] We encountered an error. Trying again..."
- else
- echo "[ERROR] Looks like we hit a snag. Please try again later, and if this error persists, please contact Androidacy support."
- exit 1
- fi
-}
-# Initiliaze API logging. Currently, nothing is sent off device, but this may change in the future.
-export logfile android device lang
-if [ ! -d /sdcard/.aapi ]; then
- mkdir -p /sdcard/.aapi
+# Ensure ANDROIDACY_API_KEY and ANDROIDACY_CLIENT_ID are both set, otherwise, exit
+if [ -z "$ANDROIDACY_API_KEY" ] || [ -z "$ANDROIDACY_CLIENT_ID" ]; then
+ echo "ANDROIDACY_API_KEY or ANDROIDACY_CLIENT_ID is not set. Please redownload the module from official sources and try again."
+ abort
fi
-logfile="/sdcard/.aapi/api.log"
-android=$(resetprop ro.system.build.version.release || resetprop ro.build.version.release)
-device=$(resetprop ro.product.model | sed 's#\n#%20#g' || resetprop ro.product.device | sed 's#\n#%20#g' || resetprop ro.product.vendor.device | sed 's#\n#%20#g' || resetprop ro.product.system.model | sed 's#\n#%20#g' || resetprop ro.product.vendor.model | sed 's#\n#%20#g' || resetprop ro.product.name | sed 's#\n#%20#g')
-# Internal beta testers only: enables translated strings
-get_translations() {
- ## PLACEHOLDER_REPLACE_FOR_TESTS ##
- true
-}
-get_translations
-lang=$(resetprop persist.sys.locale | sed 's#\n#%20#g' || resetprop ro.product.locale | sed 's#\n#%20#g')
-{
- echo "=== Device info ==="
- echo "Device: $device"
- echo "Android: $android"
- echo "Lang: $lang"
- echo "==================="
-} >$logfile
-api_log() {
- local message=$2
- echo "$message" >>$logfile
-}
-# Initiliaze the API
-initClient() {
- # We need to get the module codename and version
- # We have to extract this from module.prop
- # Make sure $api_mpath is set
- if [ -n "$MODPATH" ]; then
- export api_mpath=$MODPATH
- else
- export api_mpath
- api_mpath="echo $(dirname "$0") | sed 's/\//\ /g' | awk '{print $4}'"
- fi
- # Hack to ensure the old .androidacy FILE is deleted
- if [ -f /sdcard/.androidacy ]; then
- rm -rf /sdcard/.androidacy
- fi
- export MODULE_CODENAME MODULE_VERSION MODULE_VERSIONCODE fail_count
- fail_count=0
- MODULE_CODENAME=$(grep "id=" "$api_mpath"/module.prop | cut -d"=" -f2)
- MODULE_VERSION=$(grep "version=" "$api_mpath"/module.prop | cut -d"=" -f2)
- MODULE_VERSIONCODE=$(grep "versionCode=" "$api_mpath"/module.prop | cut -d"=" -f2)
- api_log 'INFO' "Initializing API with paramaters: $1, $2"
- # Warn if they pass arguments to initClient, as this is legacy behaviour
- if [ "$1" != "" ] || [ "$2" != "" ]; then
- api_log 'WARN' "initClient() has been called with arguments, this is legacy behaviour and will be removed in the future"
- fi
- export __api_url='https://api.androidacy.com'
- ping_api
- buildClient
- initTokens
- export __init_complete=true
+# Lets the user know they rae doing something they shouldn't be doing. Exit upon completion
+__doing_it_wrong() {
+ if [ -e "$1" ] && [ -e "$2" ]; then
+ echo "☢️ Whoa there! In function $1, you passed $2 which isn't supported anymore. Please check if it can be removed or if you can substitute it with something else. Also, read the documentation for more information. ☢️"
+ fi
+ abort
}
-ping_api() {
- # Ping the API to ensure it's up
- api_log 'INFO' "Pinging API"
- code=$(curl -A "Mozilla/5.0 (Linux; Android $android; $device) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Mobile Safari/537.36 [$MODULE_CODENAME/$MODULE_VERSIONCODE]" -s -o /dev/null -w "%{http_code}" "$__api_url/ping")
- if [ "$code" != "204" || "$code" != "200" ]; then
- api_log 'ERROR' "API is not responding. Code: $code"
- abort "API is unreachable. Check your connection and try again later."
- fi
-}
+# Initialization function.
+# Sets the user agent based on the device and the module and version, and makes a call to our servers to verify the api key and client id is correct
+initAPISDK() {
+ # If any parameter is passed, show error message
+ if [ "$#" -ge 1 ]; then
+ __doing_it_wrong "initAPISDK" "$(echo "$@" | tr ',' ' ')"
+ fi
+ export ANDROID_VERSION ANDROID_OEM ANDROID_MODEL USER_AGENT DEVICE_ID
+ ANDROID_VERSION=$(resetprop ro.build.version.release | cut -d '.' -f 1)
+ ANDROID_OEM=$(resetprop ro.product.manufacturer)
+ ANDROID_MODEL=$(resetprop ro.product.model)
-# Build client requests
-buildClient() {
- api_log 'INFO' "Building client and exporting variables"
- export API_UA="Mozilla/5.0 (Linux; Android $android; $device) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Mobile Safari/537.36 [$MODULE_CODENAME/$MODULE_VERSIONCODE]"
- export API_LANG=$lang
-}
+ # Generate a device ID to uniquely identify our device
+ # We do this by hashing other device model, serial number and device OEM
+ DEVICE_ID=$(echo "$(resetprop ro.product.model)""$(resetprop ro.product.serialno)""$(resetprop ro.product.manufacturer)" | sha256sum | cut -d ' ' -f 1)
-# Tokens init
-initTokens() {
- api_log 'INFO' "Starting tokens initialization"
- if test -f /sdcard/.aapi/.credentials; then
- api_credentials=$(cat /sdcard/.aapi/.credentials)
- else
- api_log 'WARN' "Couldn't find API credentials. If this is a first run, this warning can be safely ignored."
- curl -kLsS -A "$API_UA" -H "Accept-Language: $API_LANG" -X POST "https://api.androidacy.com/auth/register" -o /sdcard/.aapi/.credentials
- if test "$0" -ne 0; then
- api_log 'ERROR' "Couldn't get API credentials. Exiting..."
- echo "Can't communicate with the API. Please check your internet connection and try again."
- exit 1
- fi
- api_credentials="$(cat /sdcard/.aapi/.credentials)"
- sleep 0.5
- fi
- api_log 'INFO' "Exporting token"
- export api_credentials
- sleep 1
- validateTokens "$api_credentials"
-}
+ USER_AGENT="Mozilla/5.0 (Linux; Android ${ANDROID_VERSION}; ${ANDROID_OEM} ${ANDROID_MODEL}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Mobile Safari/537.36 AndroidacySDK/${VERSION} (https://www.androidacy.com)"
-# Check that we have a valid token
-validateTokens() {
- api_log 'INFO' "Starting tokens validation"
- if test "$#" -ne 1; then
- api_log 'ERROR' 'Caught error in validateTokens: wrong arguments passed'
- echo "Illegal number of parameters passed. Expected one, got $#"
- abort
- else
- local tier
- tier=$(parseJSON "$(curl -kLsS -A "$API_UA" -b "USER=$api_credentials" -H "Accept-Language: $API_LANG" "$__api_url/auth/me")" 'level' | sed 's/level://g')
- if test $? -ne 0; then
- api_log 'WARN' "Got invalid response when trying to validate token!"
- handleError
- initTokens
- else
- # Pass the appropriate API access level back to the caller
- export tier
- fi
- fi
- if test "$tier" -lt 3; then
- export sleep=1
- else
- export sleep=0.25
- fi
- export __api_url='https://api.androidacy.com'
-}
+ LANGUAGE=$(resetprop persist.sys.locale)
+ export LANGUAGE
-# Handle and decode file list JSON
-getList() {
- api_log 'INFO' "getList called with parameter: $1"
- if test "$#" -ne 1; then
- api_log 'ERROR' 'Caught error in getList: wrong arguments passed'
- echo "Illegal number of parameters passed. Expected one, got $#"
- abort
- else
- if ! $__init_complete; then
- api_log 'ERROR' 'Make sure you initialize the api client via initClient before trying to call API methods'
- echo "Tried to call getList without first initializing the API client!"
- abort
- fi
- local app=$MODULE_CODENAME
- local cat=$1
- if test "$app" = 'beta' && test tier -lt 4; then
- echo "Error! Access denied for beta."
- abort
- fi
- response="$(curl -kLsS -A "$API_UA" -b "USER=$api_credentials" -H "Accept-Language: $API_LANG" "$__api_url/downloads/list/v2?app=$app&category=$cat&simple=true")"
- if test $? -ne 0; then
- handleError
- getList "$cat"
- fi
- sleep $sleep
- # shellcheck disable=SC2001
- parsedList=$(echo "$response" | sed 's/[^a-zA-Z0-9]/ /g')
- response="$parsedList"
- fi
+ # Make a call to our servers /auth/me to check if the API key and Client ID is valid
+ if ! curl --http2-prior-knowledge --fail -sL -o- -A "${USER_AGENT}" -H "Accept-Language: ${LANGUAGE}" -H "Authorization: Bearer ${ANDROIDACY_API_KEY}" -H "X-Android-SDK-Version: $VERSION" -H "Client-ID: $ANDROIDACY_CLIENT_ID" -H "Accept: application/json" -H "Sec-Fetch-Dest: empty" -H "Device-ID: ${DEVICE_ID}" -c cookies.txt https://production-api.androidacy.com/auth/me >/dev/null; then
+ echo "API Key or Client ID is invalid or exceeded usage limits. Please redownload the module from official sources and try again."
+ abort
+ fi
}
-# Handle file downloads
-downloadFile() {
- api_log 'INFO' "downloadFile called with parameters: $1 $2 $3 $4"
- if test "$#" -ne 4; then
- api_log 'ERROR' 'Caught error in downloadFile: wrong arguments passed'
- echo "Illegal number of parameters passed. Expected four, got $#"
- abort
- if ! $__init_complete; then
- api_log 'ERROR' 'Make sure you initialize the api client via initClient before trying to call API methods'
- echo "Tried to call downloadFile without first initializing the API client!"
- abort
- fi
- else
- local cat=$1
- local file=$2
- local format=$3
- local location=$4
- local app=$MODULE_CODENAME
- local link
- link=$(parseJSON "$(curl -kLsS -A "$API_UA" -b "USER=$api_credentials" -H "Accept-Language: $API_LANG" "$__api_url/downloads/link/v2?app=$app&category=$cat&file=$file.$format")" 'link')
- sleep $sleep
- curl -kLsS -A "$API_UA" -b "USER=$api_credentials" -H "Accept-Language: $API_LANG" "$(echo "$link" | sed 's/\\//gi' | sed 's/\ //gi')" -o "$location"
- if test $? -ne 0; then
- handleError
- downloadFile "$cat" "$file" "$format" "$location"
- fi
- sleep $sleep
- fi
+# Makes a request that is expected to return JSON and then tries to parse it and return in a format that can be used in other shell scripts
+# $1: The URL to make the request to
+# $2: The data to send to the server
+# $3: The HTTP method to use
+# $4: The JSON key to parse
+makeJSONRequest() {
+ # Arguments should be path with variables, data to send, method and key to get value of
+ if [ "$#" -ne 4 ]; then
+ __doing_it_wrong "makeJSONRequest" "$(echo "$@" | tr ',' ' ')"
+ fi
+ local url method request_params value
+ # Build URL
+ url="https://production-api.androidacy.com$1"
+ # Show what request to servers
+ # shellcheck disable=SC2154
+ if [ "$ANDROIDACY_API_SDK_DEBUG_STATUS" = "ON" ]; then
+ echo "Requesting: ${url}"
+ echo "$method" "${url}"
+ fi
+ # Same headers and options as init request, except add the form encoded
+ export value
+ # For POST requests, send data as form encoded data. For GET requests, attach data as parameters in the URL
+ if [ "$3" = "POST" ]; then
+ value=$(curl --http2-prior-knowledge --fail -sL -H "Accept: application/json" -H "Authorization: Bearer ${ANDROIDACY_API_KEY}" -H "X-Android-SDK-Version: ${VERSION}" -H "Client-ID: ${ANDROIDACY_CLIENT_ID}" -H "Sec-Fetch-Dest: empty" -A "${USER_AGENT}" -H "Accept-Language: ${LANGUAGE}" -H "Device-ID: $DEVICE_ID" -X "$3" -c cookies.txt -d "$2" "$url" | parseJSON "$4")
+ else
+ url="$url?$2"
+ value=$(curl --http2-prior-knowledge --fail -sL -H "Accept: application/json" -H "Authorization: Bearer ${ANDROIDACY_API_KEY}" -H "X-Android-SDK-Version: ${VERSION}" -H "Client-ID: ${ANDROIDACY_CLIENT_ID}" -H "Sec-Fetch-Dest: empty" -A "${USER_AGENT}" -H "Accept-Language: ${LANGUAGE}" -H "Device-ID: $DEVICE_ID" -X "$3" -c cookies.txt "$url" | parseJSON "$4")
+ fi
+ # shellcheck disable=SC2181
+ if [ "$?" -ne 0 ]; then
+ echo "Invalid JSON response. Please try again later."
+ abort
+ else
+ echo "$value"
+ fi
}
-# Handle uptdates checking
-updateChecker() {
- api_log 'INFO' "updateChecker called with parameter: $1"
- if test "$#" -ne 1; then
- api_log 'ERROR' 'Caught error in updateChecker: wrong arguments passed'
- echo "Illegal number of parameters passed. Expected one, got $#"
- abort
- if ! $__init_complete; then
- api_log 'ERROR' 'Make sure you initialize the api client via initClient before trying to call API methods'
- echo "Tried to call updateChecker without first initializing the API client!"
- abort
- fi
- else
- local cat=$1 || 'self'
- local app=$MODULE_CODENAME
- response=$(curl -kLsS -A "$API_UA" -b "USER=$api_credentials" -H "Accept-Language: $API_LANG" "$__api_url/downloads/updates?app=$app&category=$cat")
- if test $? -ne 0; then
- handleError
- updateChecker "$cat"
- fi
- sleep $sleep
- # shellcheck disable=SC2001
- response=$(parseJSON "$response" "version")
+# Makes a request that is expected to return a file. Downloads it to a specified path
+# $1: The URL to make the request to
+# $2: The HTTP method to use
+# $3: The data to send to the server
+# $4: The path to save the file to
+makeFileRequest() {
+ # Arguments should be path, method, data and fileToSave to
+ if [ "$#" -ne 4 ]; then
+ __doing_it_wrong "makeFileRequest" "$(echo "$@" | tr ',' ' ')"
fi
-}
-
-# Handle checksums
-getChecksum() {
- api_log 'INFO' "getChecksum called with parameters: $1 $2 $3"
- if test "$#" -ne 3; then
- api_log 'ERROR' 'Caught error in getChecksum: wrong arguments passed'
- echo "Illegal number of parameters passed. Expected three, got $#"
- abort
- if ! $__init_complete; then
- api_log 'ERROR' 'Make sure you initialize the api client via initClient before trying to call API methods'
- echo "Tried to call getChecksum without first initializing the API client!"
- abort
- fi
+ local url method
+ local request_params=""
+ # param 4 is the file to save to. it cannot be empty or -
+ if [ -z "$4" ] || [ "$4" = "-" ]; then
+ __doing_it_wrong "makeFileRequest" "$(echo "$@" | tr ',' ' ')"
+ fi
+ # Build URL
+ url="https://production-api.androidacy.com""$1"
+ # For POST requests, send data as form encoded data. For GET requests, attach data as parameters in the URL
+ if [ "$2" = "POST" ]; then
+ curl --http2-prior-knowledge --create-dirs --fail -X "$2" -L -s -H "Accept: application/octet-stream" -H "X-Android-SDK-Version: ${VERSION}" -H "Client-ID: ${ANDROIDACY_CLIENT_ID}" -H "Sec-Fetch-Dest: empty" -A "${USER_AGENT}" -H "Accept-Language: ${LANGUAGE}" -H "Device-ID: ${DEVICE_ID}" -H "Authorization: Bearer ${ANDROIDACY_API_KEY}" -c cookies.txt -F "$3" "$url" > "$4"
else
- local cat=$1
- local file=$2
- local format=$3
- local app=$MODULE_CODENAME
- res=$(curl -kLsS -A "$API_UA" -b "USER=$api_credentials" -H "Accept-Language: $API_LANG" "$__api_url/checksum/get?app=$app&category=$cat&request=$file&format=$format")
- if test $? -ne 0; then
- handleError
- getChecksum "$cat" "$file" "$format"
- fi
- sleep $sleep
- response=$(parseJSON "$res" 'checksum')
+ url="$url?$3"
+ curl --http2-prior-knowledge --create-dirs --fail -X "$2" -L -s -H "Accept: application/octet-stream" -H "X-Android-SDK-Version: ${VERSION}" -H "Client-ID: ${ANDROIDACY_CLIENT_ID}" -H "Sec-Fetch-Dest: empty" -A "${USER_AGENT}" -H "Accept-Language: ${LANGUAGE}" -H "Device-ID: ${DEVICE_ID}" -H "Authorization: Bearer ${ANDROIDACY_API_KEY}" -c cookies.txt "$url" > "$4"
fi
-}
-
-# Log uploader
-# PLEASE NOTE: Do NOT upload potentially sensitive data to the log server. We don't need GDPR up our you-know-what.
-# That means no app info, no API keys, no passwords, no device info, no anything that could be used to identify you.
-logUploader() {
- api_log 'INFO' "logUploader called with parameter: $1"
- if test "$#" -ne 1; then
- api_log 'ERROR' 'Caught error in logUploader: wrong arguments passed'
- echo "Illegal number of parameters passed. Expected one, got $#"
+ # Same headers and options as init request, except add the form encoded $ANDROIDACY_API_SDK_DEBUG_STATUS
+ # shellcheck disable=SC2181
+ if [ $? -ne 0 ]; then
+ echo "Invalid file response. Please try again later."
abort
- if ! $__init_complete; then
- api_log 'ERROR' 'Make sure you initialize the api client via initClient before trying to call API methods'
- echo "Tried to call logUploader without first initializing the API client!"
- abort
- fi
- else
- local log=$1
- local app=$MODULE_CODENAME
- curl -kLsS -A "$API_UA" -b "USER=$api_credentials" -H "Accept-Language: $API_LANG" -F "log=@$1" "$__api_url/logs/upload" &>/dev/null
- if test $? -ne 0; then
- handleError
- logUploader "$log"
- fi
- sleep $sleep
fi
}
diff --git a/common/tools/tools.tar.xz b/common/tools/tools.tar.xz
deleted file mode 100644
index b4f513f..0000000
Binary files a/common/tools/tools.tar.xz and /dev/null differ
diff --git a/common/tools/tools.zip b/common/tools/tools.zip
new file mode 100644
index 0000000..280d687
Binary files /dev/null and b/common/tools/tools.zip differ
diff --git a/common/tools/zipsigner b/common/tools/zipsigner
deleted file mode 100644
index 3d3d96b..0000000
--- a/common/tools/zipsigner
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/system/bin/sh
-# zipsigner: wrapper to run zipsigner.jar from terminal
-# osm0sis @ xda-developers
-
-dir="$(cd "$(dirname "$0")"; pwd)";
-
-dalvikvm -Djava.io.tmpdir=. -Xnodex2oat -Xnoimage-dex2oat -cp $dir/zipsigner-*.jar com.topjohnwu.utils.ZipSigner "$@" 2>/dev/null \
- || dalvikvm -Djava.io.tmpdir=. -Xnoimage-dex2oat -cp $dir/zipsigner-*.jar com.topjohnwu.utils.ZipSigner "$@";
diff --git a/common/tools/zipsigner-3.0-dexed.jar b/common/tools/zipsigner-3.0-dexed.jar
deleted file mode 100644
index e109f61..0000000
Binary files a/common/tools/zipsigner-3.0-dexed.jar and /dev/null differ
diff --git a/config.conf b/config.conf
deleted file mode 100644
index 128515f..0000000
--- a/config.conf
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copy this file to /sdcard/WebviewManager/config.conf and edit it to your needs.
-# This file will ONLY be used as a fallback if volume key selection fails. Most users will likely never have to edit this file.
-[Browser]
-# Choose which browser you want:
-# 0: None
-# 1. Bromite
-# 2. Chromium (vanilla)
-# 3. Ungoogled Chromium
-BROWSER=1
-
-[WebView]
-# Choose which webview you want:
-# 0. None
-# 1. Bromite
-# 2. Chromium (Vanilla)
-# 3. Ungoogled Chromium
-WEBVIEW=1
diff --git a/module.prop b/module.prop
index 3c3a8cc..d3fd7f0 100644
--- a/module.prop
+++ b/module.prop
@@ -1,6 +1,8 @@
id=bromitewebview
name=Webview Manager
-version=10.5.3
-versionCode=5057
+version=11.0.1_alpha1
+versionCode=6001
author=Androidacy
-description=Change your WebView and browser systemless-ly. Block ads and fingerprinting, increase privacy, and more. Website and how to get support: https://www.androidacy.com/?f=wmv%20prop. Check out our new magisk module repo: https://www.androidacy.com/modules-repo/?f=wmv%20prop
+description=Change your WebView and browser systemless-ly. Block ads and fingerprinting, increase privacy, and more. Website @ androidacy.com
+donate=https://www.androidacy.com/membership-join/
+support=https://t.me/androidacy_discussions
diff --git a/service.sh b/service.sh
index b3003ee..973c029 100644
--- a/service.sh
+++ b/service.sh
@@ -1,28 +1,14 @@
#!/data/adb/magisk/busybox ash
+# bashsupport disable=SpellCheckingInspection
# shellcheck shell=dash
# shellcheck disable=SC2034
ASH_STANDALONE=1
SH=$(readlink -f "$0")
MODDIR=$(dirname "$SH")
it_failed() {
- ui_print " "
- ui_print "⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠"
- ui_print " "
- ui_print " Uh-oh, the installer encountered an issue!"
- ui_print " It's probably one of these reasons:"
- ui_print " 1) Installer is corrupt"
- ui_print " 2) You didn't follow instructions"
- ui_print " 3) You have an unstable internet connection"
- ui_print " 4) Your ROM is broken"
- ui_print " 5) There's a *tiny* chance we screwed up"
- ui_print " Please fix any issues and retry."
- ui_print " If you feel this is a bug or need assistance, head to our telegram"
mv "${EXT_DATA}"/logs "${TMPDIR}"
rm -rf "${EXT_DATA:?}"/*
mv "${TMPDIR}"/logs "${EXT_DATA}"/
- ui_print " "
- ui_print "⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠"
- ui_print " "
exit 1
}
INSTALL=false
diff --git a/status.txt b/status.txt
index be69e59..765d177 100644
--- a/status.txt
+++ b/status.txt
@@ -1,2 +1,2 @@
-# DO NOT EDIT THIS FILE, SERIOUSLY
+# DO NOT EDIT THIS FILE
# Automatically updated by the installer
\ No newline at end of file
diff --git a/tests.sh b/tests.sh
new file mode 100755
index 0000000..cb7b2c2
--- /dev/null
+++ b/tests.sh
@@ -0,0 +1,40 @@
+#!/usr/bin/env bash
+
+# Zips the current directory (excluding .git), checks if a device is connected, and copies the zip to the device. Then we use adb shell to run the magisk --install command on the device.
+zip=$(which zip)
+adb=$(which adb)
+
+if [ -z "$zip" ]; then
+ echo "zip not found"
+ exit 1
+fi
+if [ -z "$adb" ]; then
+ echo "adb not found"
+ exit 1
+fi
+
+# Check if a device is connected. one device should be connected.
+if ! grep -q "device" <($adb devices); then
+ echo "No device connected. Please make sure test infrastructure is set up correctly. See androidacy/infra#test-device-setup"
+ exit 1
+fi
+echo "Checks passed"
+# Check if magisk is installed via adb shell and magisk -V
+if ! grep -q "MAGISK" <($adb shell su -c "magisk -v"); then
+ # for debugging, output magisk -V and magisk -v
+ echo $($adb shell su -c "magisk -V")
+ echo $($adb shell su -c "magisk -v")
+ echo "Magisk not installed"
+ exit 1
+fi
+echo "Magisk installed"
+# get timestamp
+timestamp=$(date +%Y%m%d-%H%M%S)
+echo "Timestamp: $timestamp"
+rm -f wvm-*.zip
+echo "Removed old zip(s)"
+zip -qr8 "wvm-$timestamp.zip" . -x ".git/*" "build.sh" "README.md" "LICENSE"
+echo "Created zip"
+$adb push "wvm-$timestamp.zip" /sdcard/
+echo "Pushed zip to /sdcard/"
+$adb shell su -c "magisk --install-module /sdcard/\"wvm-$timestamp.zip\""
\ No newline at end of file