mirror of
https://github.com/MustardChef/WSABuilds.git
synced 2024-12-24 18:31:49 +01:00
All work done in local host.
Remove Action.
This commit is contained in:
parent
79f2d86677
commit
555c643c2f
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
* text eol=lf
|
||||
*.exe binary
|
718
.github/workflows/magisk.yml
vendored
718
.github/workflows/magisk.yml
vendored
@ -1,718 +0,0 @@
|
||||
name: Build WSA
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
arch:
|
||||
description: "Build arch"
|
||||
required: true
|
||||
default: "x64 & arm64"
|
||||
type: choice
|
||||
options:
|
||||
- x64
|
||||
- arm64
|
||||
- x64 & arm64
|
||||
release_type:
|
||||
description: "WSA release type"
|
||||
required: true
|
||||
default: "retail"
|
||||
type: choice
|
||||
options:
|
||||
- retail
|
||||
- release preview
|
||||
- insider slow
|
||||
- insider fast
|
||||
magisk_apk:
|
||||
description: "Magisk version"
|
||||
required: true
|
||||
default: "stable"
|
||||
type: choice
|
||||
options:
|
||||
- stable
|
||||
- beta
|
||||
- canary
|
||||
- debug
|
||||
gapps_variant:
|
||||
description: "Variants of gapps"
|
||||
required: true
|
||||
default: "none"
|
||||
type: choice
|
||||
options:
|
||||
- none
|
||||
- super
|
||||
- stock
|
||||
- full
|
||||
- mini
|
||||
- micro
|
||||
- nano
|
||||
- pico
|
||||
- tvstock
|
||||
- tvmini
|
||||
remove_amazon:
|
||||
description: "Remove Amazon AppStore"
|
||||
required: true
|
||||
default: "keep"
|
||||
type: choice
|
||||
options:
|
||||
- keep
|
||||
- remove
|
||||
root_sol:
|
||||
description: "Root solution"
|
||||
required: true
|
||||
default: "magisk"
|
||||
type: choice
|
||||
options:
|
||||
- magisk
|
||||
- none
|
||||
|
||||
jobs:
|
||||
matrix:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
matrix: ${{ steps.set-matrix.outputs.matrix }}
|
||||
steps:
|
||||
- name: Generate build matrix
|
||||
id: set-matrix
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
let matrix = {};
|
||||
let arch = "${{ github.event.inputs.arch }}"
|
||||
switch ( arch ) {
|
||||
case "x64":
|
||||
matrix.arch = ["x64"];
|
||||
break;
|
||||
case "arm64":
|
||||
matrix.arch = ["arm64"];
|
||||
break;
|
||||
default:
|
||||
matrix.arch = ["x64", "arm64"];
|
||||
break;
|
||||
}
|
||||
core.setOutput("matrix",JSON.stringify(matrix));
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-20.04
|
||||
needs: matrix
|
||||
strategy:
|
||||
matrix: ${{fromJson(needs.matrix.outputs.matrix)}}
|
||||
steps:
|
||||
- name: Dependencies
|
||||
run: |
|
||||
sudo apt-get update && sudo apt-get install setools lzip wine winetricks patchelf
|
||||
wget -qO- "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/archive/$GITHUB_REF.tar.gz" | sudo tar --wildcards -zxvf- -C ~ --strip-component=2 '*/wine/*' '*/linker/*' '*/xml/*'
|
||||
winetricks msxml6
|
||||
- name: Download WSA
|
||||
shell: python
|
||||
run: |
|
||||
import requests
|
||||
from xml.dom import minidom
|
||||
import html
|
||||
import warnings
|
||||
import re
|
||||
import zipfile
|
||||
import os
|
||||
import urllib.request
|
||||
from pathlib import Path
|
||||
|
||||
warnings.filterwarnings("ignore")
|
||||
|
||||
arch = "${{ matrix.arch }}"
|
||||
release_type_map = {"retail": "Retail", "release preview": "RP", "insider slow": "WIS", "insider fast": "WIF"}
|
||||
release_type = release_type_map["${{ github.event.inputs.release_type }}"] if "${{ github.event.inputs.release_type }}" != "" else "Retail"
|
||||
|
||||
cat_id = '858014f3-3934-4abe-8078-4aa193e74ca8'
|
||||
|
||||
with open(Path.home() / "GetCookie.xml", "r") as f:
|
||||
cookie_content = f.read()
|
||||
|
||||
out = requests.post(
|
||||
'https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx',
|
||||
data=cookie_content,
|
||||
headers={'Content-Type': 'application/soap+xml; charset=utf-8'},
|
||||
verify=False
|
||||
)
|
||||
doc = minidom.parseString(out.text)
|
||||
cookie = doc.getElementsByTagName('EncryptedData')[0].firstChild.nodeValue
|
||||
|
||||
print(cookie)
|
||||
|
||||
with open(Path.home() / "WUIDRequest.xml", "r") as f:
|
||||
cat_id_content = f.read().format(cookie, cat_id, release_type)
|
||||
|
||||
out = requests.post(
|
||||
'https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx',
|
||||
data=cat_id_content,
|
||||
headers={'Content-Type': 'application/soap+xml; charset=utf-8'},
|
||||
verify=False
|
||||
)
|
||||
|
||||
doc = minidom.parseString(html.unescape(out.text))
|
||||
|
||||
filenames = {}
|
||||
for node in doc.getElementsByTagName('Files'):
|
||||
filenames[node.parentNode.parentNode.getElementsByTagName('ID')[0].firstChild.nodeValue] = f"{node.firstChild.attributes['InstallerSpecificIdentifier'].value}_{node.firstChild.attributes['FileName'].value}"
|
||||
pass
|
||||
|
||||
identities = []
|
||||
for node in doc.getElementsByTagName('SecuredFragment'):
|
||||
filename = filenames[node.parentNode.parentNode.parentNode.getElementsByTagName('ID')[0].firstChild.nodeValue]
|
||||
update_identity = node.parentNode.parentNode.firstChild
|
||||
identities += [(update_identity.attributes['UpdateID'].value, update_identity.attributes['RevisionNumber'].value, filename)]
|
||||
|
||||
with open(Path.home() / "FE3FileUrl.xml", "r") as f:
|
||||
file_content = f.read()
|
||||
|
||||
for i, v, f in identities:
|
||||
if re.match(f"Microsoft\.UI\.Xaml\..*_{arch}_.*\.appx", f):
|
||||
out_file = "xaml.appx"
|
||||
elif re.match(f"Microsoft\.VCLibs\..*_{arch}_.*\.appx", f):
|
||||
out_file = "vclibs.appx"
|
||||
elif re.match(f"MicrosoftCorporationII\.WindowsSubsystemForAndroid_.*\.msixbundle", f):
|
||||
out_file = "wsa.zip"
|
||||
else:
|
||||
continue
|
||||
out = requests.post(
|
||||
'https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx/secured',
|
||||
data=file_content.format(i, v, release_type),
|
||||
headers={'Content-Type': 'application/soap+xml; charset=utf-8'},
|
||||
verify=False
|
||||
)
|
||||
doc = minidom.parseString(out.text)
|
||||
for l in doc.getElementsByTagName("FileLocation"):
|
||||
url = l.getElementsByTagName("Url")[0].firstChild.nodeValue
|
||||
if len(url) != 99:
|
||||
if not os.path.isfile(out_file):
|
||||
print(f"downloading link: {url} to {out_file}", flush=True)
|
||||
urllib.request.urlretrieve(url, out_file)
|
||||
|
||||
zip_name = ""
|
||||
with zipfile.ZipFile("wsa.zip") as zip:
|
||||
for f in zip.filelist:
|
||||
if arch in f.filename.lower():
|
||||
zip_name = f.filename
|
||||
if not os.path.isfile(zip_name):
|
||||
print(f"unzipping to {zip_name}", flush=True)
|
||||
zip.extract(f)
|
||||
ver_no = zip_name.split("_")
|
||||
long_ver = ver_no[1]
|
||||
ver=long_ver.split(".")
|
||||
main_ver=ver[0]
|
||||
with open(os.environ['GITHUB_ENV'], 'a') as g:
|
||||
g.write(f'WSA_VER={long_ver}\n')
|
||||
with open(os.environ['GITHUB_ENV'], 'a') as g:
|
||||
g.write(f'WSA_MAIN_VER={main_ver}\n')
|
||||
rel = ver_no[3].split(".")
|
||||
rell = str(rel[0])
|
||||
with open(os.environ['GITHUB_ENV'], 'a') as g:
|
||||
g.write(f'WSA_REL={rell}\n')
|
||||
if 'language' in f.filename.lower() or 'scale' in f.filename.lower():
|
||||
name = f.filename.split("-", 1)[1].split(".")[0]
|
||||
zip.extract(f)
|
||||
with zipfile.ZipFile(f.filename) as l:
|
||||
for g in l.filelist:
|
||||
if g.filename == 'resources.pri':
|
||||
g.filename = f'{name}.pri'
|
||||
l.extract(g, 'pri')
|
||||
print(f"extract resource pack {g.filename}")
|
||||
elif g.filename == 'AppxManifest.xml':
|
||||
g.filename = f'{name}.xml'
|
||||
l.extract(g, 'xml')
|
||||
|
||||
with zipfile.ZipFile(zip_name) as zip:
|
||||
if not os.path.isdir(arch):
|
||||
print(f"unzipping from {zip_name}", flush=True)
|
||||
zip.extractall(arch)
|
||||
|
||||
print("done", flush=True)
|
||||
- name: Download Magisk
|
||||
shell: python
|
||||
run: |
|
||||
import urllib.request
|
||||
import zipfile
|
||||
import os
|
||||
import json
|
||||
import requests
|
||||
|
||||
magisk_apk = """${{ github.event.inputs.magisk_apk }}"""
|
||||
|
||||
if not magisk_apk:
|
||||
magisk_apk = "stable"
|
||||
if magisk_apk == "stable" or magisk_apk == "beta" or magisk_apk == "canary" or magisk_apk == "debug":
|
||||
magisk_apk = json.loads(requests.get(f"https://github.com/topjohnwu/magisk-files/raw/master/{magisk_apk}.json").content)['magisk']['link']
|
||||
|
||||
out_file = "magisk.zip"
|
||||
|
||||
arch = "${{ matrix.arch }}"
|
||||
|
||||
abi_map={"x64" : ["x86_64", "x86"], "arm64" : ["arm64-v8a", "armeabi-v7a"]}
|
||||
|
||||
if not os.path.isfile(out_file):
|
||||
urllib.request.urlretrieve(magisk_apk, out_file)
|
||||
|
||||
def extract_as(zip, name, as_name, dir):
|
||||
info = zip.getinfo(name)
|
||||
info.filename = as_name
|
||||
zip.extract(info, dir)
|
||||
|
||||
with zipfile.ZipFile(out_file) as zip:
|
||||
extract_as(zip, f"lib/{ abi_map[arch][0] }/libmagisk64.so", "magisk64", "magisk")
|
||||
extract_as(zip, f"lib/{ abi_map[arch][1] }/libmagisk32.so", "magisk32", "magisk")
|
||||
standalone_policy = False
|
||||
try:
|
||||
zip.getinfo(f"lib/{ abi_map[arch][0] }/libmagiskpolicy.so")
|
||||
standalone_policy = True
|
||||
except:
|
||||
pass
|
||||
extract_as(zip, f"lib/{ abi_map[arch][0] }/libmagiskinit.so", "magiskinit", "magisk")
|
||||
if standalone_policy:
|
||||
extract_as(zip, f"lib/{ abi_map[arch][0] }/libmagiskpolicy.so", "magiskpolicy", "magisk")
|
||||
else:
|
||||
extract_as(zip, f"lib/{ abi_map[arch][0] }/libmagiskinit.so", "magiskpolicy", "magisk")
|
||||
extract_as(zip, f"lib/{ abi_map[arch][0] }/libmagiskboot.so", "magiskboot", "magisk")
|
||||
extract_as(zip, f"lib/{ abi_map[arch][0] }/libbusybox.so", "busybox", "magisk")
|
||||
if standalone_policy:
|
||||
extract_as(zip, f"lib/{ abi_map['x64'][0] }/libmagiskpolicy.so", "magiskpolicy", ".")
|
||||
else:
|
||||
extract_as(zip, f"lib/{ abi_map['x64'][0] }/libmagiskinit.so", "magiskpolicy", ".")
|
||||
extract_as(zip, f"assets/boot_patch.sh", "boot_patch.sh", "magisk")
|
||||
extract_as(zip, f"assets/util_functions.sh", "util_functions.sh", "magisk")
|
||||
- name: Download OpenGApps
|
||||
if: ${{ github.event.inputs.gapps_variant != 'none' && github.event.inputs.gapps_variant != '' }}
|
||||
shell: python
|
||||
run: |
|
||||
import requests
|
||||
import zipfile
|
||||
import os
|
||||
import urllib.request
|
||||
import json
|
||||
import re
|
||||
|
||||
arch = "${{ matrix.arch }}"
|
||||
# TODO: if it's an Android 12.1 base WSA keep it pico since other variants of opengapps are unable to boot successfully
|
||||
variant = "${{ github.event.inputs.gapps_variant }}" if int("${{ env.WSA_MAIN_VER }}") < 2204 else "pico"
|
||||
abi_map = {"x64" : "x86_64", "arm64": "arm64"}
|
||||
# TODO: keep it 11.0 since opengapps does not support 12+ yet
|
||||
# As soon as opengapps is available for 12+, we need to get the sdk/release from build.prop and
|
||||
# download the corresponding version
|
||||
release = "11.0"
|
||||
try:
|
||||
res = requests.get(f"https://api.opengapps.org/list")
|
||||
j = json.loads(res.content)
|
||||
link = {i["name"]: i for i in j["archs"][abi_map[arch]]["apis"][release]["variants"]}[variant]["zip"]
|
||||
except Exception:
|
||||
print("Failed to fetch from opengapps api, fallbacking to sourceforge rss...")
|
||||
res = requests.get(f'https://sourceforge.net/projects/opengapps/rss?path=/{abi_map[arch]}&limit=100')
|
||||
link = re.search(f'https://.*{abi_map[arch]}/.*{release}.*{variant}.*\.zip/download', res.text).group().replace('.zip/download', '.zip').replace('sourceforge.net/projects/opengapps/files', 'downloads.sourceforge.net/project/opengapps')
|
||||
|
||||
print(f"downloading link: {link}", flush=True)
|
||||
|
||||
out_file = "gapps.zip"
|
||||
|
||||
if not os.path.isfile(out_file):
|
||||
urllib.request.urlretrieve(link, out_file)
|
||||
print("done", flush=True)
|
||||
|
||||
- name: Extract GApps
|
||||
if: ${{ github.event.inputs.gapps_variant != 'none' && github.event.inputs.gapps_variant != '' }}
|
||||
run: |
|
||||
mkdir gapps
|
||||
unzip -p gapps.zip {Core,GApps}/'*.lz' | tar --lzip -C gapps -xvf - -i --strip-components=2 --exclude='setupwizardtablet-x86_64' --exclude='packageinstallergoogle-all' --exclude='speech-common' --exclude='markup-lib-arm' --exclude='markup-lib-arm64' --exclude='markup-all' --exclude='setupwizarddefault-x86_64' --exclude='pixellauncher-all' --exclude='pixellauncher-common'
|
||||
|
||||
- name: Expand images
|
||||
run: |
|
||||
e2fsck -yf ${{ matrix.arch }}/system_ext.img
|
||||
system_ext_size=$(( $(du -sB512 ${{ matrix.arch }}/system_ext.img | cut -f1) + 20000 ))
|
||||
resize2fs ${{ matrix.arch }}/system_ext.img "$system_ext_size"s
|
||||
e2fsck -yf ${{ matrix.arch }}/product.img
|
||||
product_size=$(( $(du -sB512 ${{ matrix.arch }}/product.img | cut -f1) + 20000 ))
|
||||
if [ -d gapps/product ]; then
|
||||
product_size=$(( $product_size + $(du -sB512 gapps/product | cut -f1) ))
|
||||
fi
|
||||
resize2fs ${{ matrix.arch }}/product.img "$product_size"s
|
||||
e2fsck -yf ${{ matrix.arch }}/system.img
|
||||
system_size=$(( $(du -sB512 ${{ matrix.arch }}/system.img | cut -f1) + 20000 ))
|
||||
if [ -d gapps ]; then
|
||||
system_size=$(( $system_size + $(du -sB512 gapps | cut -f1) - $(du -sB512 gapps/product | cut -f1) ))
|
||||
fi
|
||||
if [ -d magisk ]; then
|
||||
system_size=$(( $system_size +$(du -sB512 magisk | cut -f1) ))
|
||||
fi
|
||||
if [ -f magisk.zip ]; then
|
||||
system_size=$(( $system_size +$(du -sB512 magisk.zip | cut -f1) ))
|
||||
fi
|
||||
resize2fs ${{ matrix.arch }}/system.img "$system_size"s
|
||||
e2fsck -yf ${{ matrix.arch }}/vendor.img
|
||||
vendor_size=$(( $(du -sB512 ${{ matrix.arch }}/vendor.img | cut -f1) + 20000 ))
|
||||
resize2fs ${{ matrix.arch }}/vendor.img "$vendor_size"s
|
||||
- name: Mount images
|
||||
run: |
|
||||
sudo mkdir system
|
||||
sudo mount -o loop ${{ matrix.arch }}/system.img system
|
||||
sudo mount -o loop ${{ matrix.arch }}/vendor.img system/vendor
|
||||
sudo mount -o loop ${{ matrix.arch }}/product.img system/product
|
||||
sudo mount -o loop ${{ matrix.arch }}/system_ext.img system/system_ext
|
||||
- name: Remove Amazon AppStore
|
||||
if: ${{ github.event.inputs.remove_amazon == 'remove' }}
|
||||
run: |
|
||||
find system/product/{etc/permissions,etc/sysconfig,framework,priv-app} | grep -e amazon -e venezia | sudo xargs rm -rf
|
||||
- name: Integrate Magisk
|
||||
if: ${{ github.event.inputs.root_sol == 'magisk' || github.event.inputs.root_sol == '' }}
|
||||
run: |
|
||||
sudo mkdir system/sbin
|
||||
sudo chcon --reference system/init.environ.rc system/sbin
|
||||
sudo chown root:root system/sbin
|
||||
sudo chmod 0700 system/sbin
|
||||
sudo cp magisk/* system/sbin/
|
||||
sudo cp magisk.zip system/sbin/magisk.apk
|
||||
sudo tee -a system/sbin/loadpolicy.sh <<EOF
|
||||
#!/system/bin/sh
|
||||
mkdir -p /data/adb/magisk
|
||||
cp /sbin/* /data/adb/magisk/
|
||||
chmod -R 755 /data/adb/magisk
|
||||
restorecon -R /data/adb/magisk
|
||||
for module in \$(ls /data/adb/modules); do
|
||||
if ! [ -f "/data/adb/modules/\$module/disable" ] && [ -f "/data/adb/modules/\$module/sepolicy.rule" ]; then
|
||||
/sbin/magiskpolicy --live --apply "/data/adb/modules/\$module/sepolicy.rule"
|
||||
fi
|
||||
done
|
||||
EOF
|
||||
sudo find system/sbin -type f -exec chmod 0755 {} \;
|
||||
sudo find system/sbin -type f -exec chown root:root {} \;
|
||||
sudo find system/sbin -type f -exec chcon --reference system/product {} \;
|
||||
sudo patchelf --replace-needed libc.so "${HOME}/libc.so" ./magiskpolicy || true
|
||||
sudo patchelf --replace-needed libm.so "${HOME}/libm.so" ./magiskpolicy || true
|
||||
sudo patchelf --replace-needed libdl.so "${HOME}/libdl.so" ./magiskpolicy || true
|
||||
sudo patchelf --set-interpreter "${HOME}/linker64" ./magiskpolicy || true
|
||||
chmod +x ./magiskpolicy
|
||||
echo '/dev/wsa-magisk(/.*)? u:object_r:magisk_file:s0' | sudo tee -a system/vendor/etc/selinux/vendor_file_contexts
|
||||
echo '/data/adb/magisk(/.*)? u:object_r:magisk_file:s0' | sudo tee -a system/vendor/etc/selinux/vendor_file_contexts
|
||||
sudo ./magiskpolicy --load system/vendor/etc/selinux/precompiled_sepolicy --save system/vendor/etc/selinux/precompiled_sepolicy --magisk "allow * magisk_file lnk_file *"
|
||||
sudo tee -a system/system/etc/init/hw/init.rc <<EOF
|
||||
|
||||
on post-fs-data
|
||||
start logd
|
||||
start adbd
|
||||
mkdir /dev/wsa-magisk
|
||||
mount tmpfs tmpfs /dev/wsa-magisk mode=0755
|
||||
copy /sbin/magisk64 /dev/wsa-magisk/magisk64
|
||||
chmod 0755 /dev/wsa-magisk/magisk64
|
||||
symlink ./magisk64 /dev/wsa-magisk/magisk
|
||||
symlink ./magisk64 /dev/wsa-magisk/su
|
||||
symlink ./magisk64 /dev/wsa-magisk/resetprop
|
||||
copy /sbin/magisk32 /dev/wsa-magisk/magisk32
|
||||
chmod 0755 /dev/wsa-magisk/magisk32
|
||||
copy /sbin/magiskinit /dev/wsa-magisk/magiskinit
|
||||
chmod 0755 /dev/wsa-magisk/magiskinit
|
||||
copy /sbin/magiskpolicy /dev/wsa-magisk/magiskpolicy
|
||||
chmod 0755 /dev/wsa-magisk/magiskpolicy
|
||||
mkdir /dev/wsa-magisk/.magisk 700
|
||||
mkdir /dev/wsa-magisk/.magisk/mirror 700
|
||||
mkdir /dev/wsa-magisk/.magisk/block 700
|
||||
copy /sbin/magisk.apk /dev/wsa-magisk/stub.apk
|
||||
rm /dev/.magisk_unblock
|
||||
start IhhslLhHYfse
|
||||
start FAhW7H9G5sf
|
||||
wait /dev/.magisk_unblock 40
|
||||
rm /dev/.magisk_unblock
|
||||
|
||||
service IhhslLhHYfse /system/bin/sh /sbin/loadpolicy.sh
|
||||
user root
|
||||
seclabel u:r:magisk:s0
|
||||
oneshot
|
||||
|
||||
service FAhW7H9G5sf /dev/wsa-magisk/magisk --post-fs-data
|
||||
user root
|
||||
seclabel u:r:magisk:s0
|
||||
oneshot
|
||||
|
||||
service HLiFsR1HtIXVN6 /dev/wsa-magisk/magisk --service
|
||||
class late_start
|
||||
user root
|
||||
seclabel u:r:magisk:s0
|
||||
oneshot
|
||||
|
||||
on property:sys.boot_completed=1
|
||||
mkdir /data/adb/magisk 755
|
||||
copy /sbin/magisk.apk /data/adb/magisk/magisk.apk
|
||||
start YqCTLTppv3ML
|
||||
|
||||
service YqCTLTppv3ML /dev/wsa-magisk/magisk --boot-complete
|
||||
user root
|
||||
seclabel u:r:magisk:s0
|
||||
oneshot
|
||||
EOF
|
||||
- name: Merge Language Resources
|
||||
run: |
|
||||
cp ${{ matrix.arch }}/resources.pri pri/en-us.pri
|
||||
cp ${{ matrix.arch }}/AppxManifest.xml xml/en-us.xml
|
||||
tee priconfig.xml <<EOF
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<resources targetOsVersion="10.0.0" majorVersion="1">
|
||||
<index root="\" startIndexAt="\">
|
||||
<indexer-config type="folder" foldernameAsQualifier="true" filenameAsQualifier="true" qualifierDelimiter="."/>
|
||||
<indexer-config type="PRI"/>
|
||||
</index>
|
||||
</resources>
|
||||
EOF
|
||||
wine64 ~/makepri.exe new /pr pri /in MicrosoftCorporationII.WindowsSubsystemForAndroid /cf priconfig.xml /of ${{ matrix.arch }}/resources.pri /o
|
||||
sed -i -zE "s/<Resources.*Resources>/<Resources>\n$(cat xml/* | grep -Po '<Resource [^>]*/>' | sed ':a;N;$!ba;s/\n/\\n/g' | sed 's/\$/\\$/g' | sed 's/\//\\\//g')\n<\/Resources>/g" ${{ matrix.arch }}/AppxManifest.xml
|
||||
- name: Add extra packages
|
||||
run: |
|
||||
wget -qO- "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/archive/$GITHUB_REF.tar.gz" | sudo tar --wildcards -zxvf- --strip-component=2 '*/${{ matrix.arch }}/system/*'
|
||||
sudo find system/system/priv-app -type d -exec chmod 0755 {} \;
|
||||
sudo find system/system/priv-app -type f -exec chmod 0644 {} \;
|
||||
sudo find system/system/priv-app -exec chcon --reference=system/system/priv-app {} \;
|
||||
- name: Integrate GApps
|
||||
if: ${{ github.event.inputs.gapps_variant != 'none' && github.event.inputs.gapps_variant != '' }}
|
||||
run: |
|
||||
wget -qO- "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/archive/$GITHUB_REF.tar.gz" | sudo tar --wildcards -zxvf- --strip-component=2 '*/${{ matrix.arch }}/gapps/*'
|
||||
shopt -s extglob
|
||||
sudo cp -vr gapps/!(product) system/system
|
||||
sudo cp -vr gapps/product/* system/product/
|
||||
|
||||
sudo find system/system/{app,etc,framework,priv-app} -exec chown root:root {} \;
|
||||
sudo find system/product/{app,etc,overlay,priv-app} -exec chown root:root {} \;
|
||||
|
||||
sudo find system/system/{app,etc,framework,priv-app} -type d -exec chmod 0755 {} \;
|
||||
sudo find system/product/{app,etc,overlay,priv-app} -type d -exec chmod 0755 {} \;
|
||||
|
||||
sudo find system/system/{app,framework,priv-app} -type f -exec chmod 0644 {} \;
|
||||
ls gapps/etc/ | xargs -n 1 -I dir sudo find system/system/etc/dir -type f -exec chmod 0644 {} \;
|
||||
sudo find system/product/{app,etc,overlay,priv-app} -type f -exec chmod 0644 {} \;
|
||||
|
||||
sudo find system/system/{app,framework,priv-app} -type d -exec chcon --reference=system/system/app {} \;
|
||||
sudo find system/product/{app,etc,overlay,priv-app} -type d -exec chcon --reference=system/product/app {} \;
|
||||
ls gapps/etc/ | xargs -n 1 -I dir sudo find system/system/etc/dir -type d -exec chcon --reference=system/system/etc/permissions {} \;
|
||||
|
||||
sudo find system/system/{app,framework,priv-app} -type f -exec chcon --reference=system/system/framework/ext.jar {} \;
|
||||
ls gapps/etc/ | xargs -n 1 -I dir sudo find system/system/etc/dir -type f -exec chcon --reference=system/system/etc/permissions {} \;
|
||||
sudo find system/product/{app,etc,overlay,priv-app} -type f -exec chcon --reference=system/product/etc/permissions/com.android.settings.intelligence.xml {} \;
|
||||
sudo patchelf --replace-needed libc.so "${HOME}/libc.so" ./magiskpolicy || true
|
||||
sudo patchelf --replace-needed libm.so "${HOME}/libm.so" ./magiskpolicy || true
|
||||
sudo patchelf --replace-needed libdl.so "${HOME}/libdl.so" ./magiskpolicy || true
|
||||
sudo patchelf --set-interpreter "${HOME}/linker64" ./magiskpolicy || true
|
||||
chmod +x ./magiskpolicy
|
||||
sudo ./magiskpolicy --load system/vendor/etc/selinux/precompiled_sepolicy --save system/vendor/etc/selinux/precompiled_sepolicy "allow gmscore_app gmscore_app vsock_socket { create connect write read }" "allow gmscore_app device_config_runtime_native_boot_prop file read" "allow gmscore_app system_server_tmpfs dir search" "allow gmscore_app system_server_tmpfs file open"
|
||||
- name: Fix GApps prop
|
||||
if: ${{ github.event.inputs.gapps_variant != 'none' && github.event.inputs.gapps_variant != '' }}
|
||||
shell: sudo python {0}
|
||||
run: |
|
||||
from __future__ import annotations
|
||||
from io import TextIOWrapper
|
||||
from os import system, path
|
||||
from typing import OrderedDict
|
||||
|
||||
|
||||
class Prop(OrderedDict):
|
||||
def __init__(self, file: TextIOWrapper) -> None:
|
||||
super().__init__()
|
||||
for i, line in enumerate(file.read().splitlines(False)):
|
||||
if '=' in line:
|
||||
k, v = line.split('=', 2)
|
||||
self[k] = v
|
||||
else:
|
||||
self[f".{i}"] = line
|
||||
|
||||
def __str__(self) -> str:
|
||||
return '\n'.join([v if k.startswith('.') else f"{k}={v}" for k, v in self.items()])
|
||||
|
||||
def __iadd__(self, other: str) -> Prop:
|
||||
self[f".{len(self)}"] = other
|
||||
return self
|
||||
|
||||
|
||||
new_props = {
|
||||
("product", "brand"): "google",
|
||||
("product", "manufacturer"): "Google",
|
||||
("build", "product"): "redfin",
|
||||
("product", "name"): "redfin",
|
||||
("product", "device"): "redfin",
|
||||
("product", "model"): "Pixel 5",
|
||||
("build", "flavor"): "redfin-user"
|
||||
}
|
||||
|
||||
|
||||
def description(sec: str, p: Prop) -> str:
|
||||
return f"{p[f'ro.{sec}.build.flavor']} {p[f'ro.{sec}.build.version.release_or_codename']} {p[f'ro.{sec}.build.id']} {p[f'ro.{sec}.build.version.incremental']} {p[f'ro.{sec}.build.tags']}"
|
||||
|
||||
|
||||
def fingerprint(sec: str, p: Prop) -> str:
|
||||
return f"""{p[f"ro.product.{sec}.brand"]}/{p[f"ro.product.{sec}.name"]}/{p[f"ro.product.{sec}.device"]}:{p[f"ro.{sec}.build.version.release"]}/{p[f"ro.{sec}.build.id"]}/{p[f"ro.{sec}.build.version.incremental"]}:{p[f"ro.{sec}.build.type"]}/{p[f"ro.{sec}.build.tags"]}"""
|
||||
|
||||
|
||||
def fix_prop(sec, prop):
|
||||
if not path.exists(prop):
|
||||
return
|
||||
|
||||
print(f"fixing {prop}", flush=True)
|
||||
with open(prop, 'r') as f:
|
||||
p = Prop(f)
|
||||
|
||||
p += "# extra prop added by MagiskOnWSA"
|
||||
|
||||
for k, v in new_props.items():
|
||||
p[f"ro.{k[0]}.{k[1]}"] = v
|
||||
|
||||
if k[0] == "build":
|
||||
p[f"ro.{sec}.{k[0]}.{k[1]}"] = v
|
||||
elif k[0] == "product":
|
||||
p[f"ro.{k[0]}.{sec}.{k[1]}"] = v
|
||||
|
||||
p["ro.build.description"] = description(sec, p)
|
||||
p[f"ro.build.fingerprint"] = fingerprint(sec, p)
|
||||
p[f"ro.{sec}.build.description"] = description(sec, p)
|
||||
p[f"ro.{sec}.build.fingerprint"] = fingerprint(sec, p)
|
||||
p[f"ro.bootimage.build.fingerprint"] = fingerprint(sec, p)
|
||||
|
||||
with open(prop, 'w') as f:
|
||||
f.write(str(p))
|
||||
|
||||
for sec, prop in {"system": "system/system/build.prop", "product": "system/product/build.prop", "system_ext": "system/system_ext/build.prop", "vendor": "system/vendor/build.prop", "odm": "system/vendor/odm/etc/build.prop"}.items():
|
||||
fix_prop(sec, prop)
|
||||
- name: Umount images
|
||||
run: |
|
||||
sudo find system -exec touch -amt 200901010000.00 {} \;> /dev/null 2>&1
|
||||
sudo umount system/vendor
|
||||
sudo umount system/product
|
||||
sudo umount system/system_ext
|
||||
sudo umount system
|
||||
- name: Shrink images
|
||||
run: |
|
||||
e2fsck -yf ${{ matrix.arch }}/system.img
|
||||
resize2fs -M ${{ matrix.arch }}/system.img
|
||||
e2fsck -yf ${{ matrix.arch }}/vendor.img
|
||||
resize2fs -M ${{ matrix.arch }}/vendor.img
|
||||
e2fsck -yf ${{ matrix.arch }}/product.img
|
||||
resize2fs -M ${{ matrix.arch }}/product.img
|
||||
e2fsck -yf ${{ matrix.arch }}/system_ext.img
|
||||
resize2fs -M ${{ matrix.arch }}/system_ext.img
|
||||
- name: Remove signature and add scripts
|
||||
run: |
|
||||
rm -rf ${{ matrix.arch }}/\[Content_Types\].xml ${{ matrix.arch }}/AppxBlockMap.xml ${{ matrix.arch }}/AppxSignature.p7x ${{ matrix.arch }}/AppxMetadata
|
||||
cp vclibs.appx xaml.appx ${{ matrix.arch }}
|
||||
tee ${{ matrix.arch }}/Install.ps1 <<EOF
|
||||
# Automated Install script by Mioki
|
||||
# http://github.com/okibcn
|
||||
function Test-Administrator {
|
||||
[OutputType([bool])]
|
||||
param()
|
||||
process {
|
||||
[Security.Principal.WindowsPrincipal]\$user = [Security.Principal.WindowsIdentity]::GetCurrent();
|
||||
return \$user.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator);
|
||||
}
|
||||
}
|
||||
|
||||
function Finish {
|
||||
Clear-Host
|
||||
Start-Process "wsa://com.topjohnwu.magisk"
|
||||
Start-Process "wsa://com.android.vending"
|
||||
}
|
||||
|
||||
if (-not (Test-Administrator)) {
|
||||
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass -Force
|
||||
\$proc = Start-Process -PassThru -WindowStyle Hidden -Verb RunAs powershell.exe -Args "-executionpolicy bypass -command Set-Location '\$PSScriptRoot'; &'\$PSCommandPath' EVAL"
|
||||
\$proc.WaitForExit()
|
||||
if (\$proc.ExitCode -ne 0) {
|
||||
Clear-Host
|
||||
Write-Warning "Failed to launch start as Administrator\`r\`nPress any key to exit"
|
||||
\$null = \$Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
|
||||
}
|
||||
exit
|
||||
}
|
||||
elseif ((\$args.Count -eq 1) -and (\$args[0] -eq "EVAL")) {
|
||||
Start-Process powershell.exe -Args "-executionpolicy bypass -command Set-Location '\$PSScriptRoot'; &'\$PSCommandPath'"
|
||||
exit
|
||||
}
|
||||
|
||||
if (((Test-Path -Path $(ls -Q ./${{ matrix.arch }} | paste -sd "," -)) -eq \$false).Count) {
|
||||
Write-Error "Some files are missing in the zip. Please try to download it again from the browser downloader, or try to run the workflow again. Press any key to exist"
|
||||
\$null = \$Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
|
||||
exit 1
|
||||
}
|
||||
|
||||
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" /t REG_DWORD /f /v "AllowDevelopmentWithoutDevLicense" /d "1"
|
||||
|
||||
\$VMP = Get-WindowsOptionalFeature -Online -FeatureName 'VirtualMachinePlatform'
|
||||
if (\$VMP.State -ne "Enabled") {
|
||||
Enable-WindowsOptionalFeature -Online -NoRestart -FeatureName 'VirtualMachinePlatform'
|
||||
Clear-Host
|
||||
Write-Warning "Need restart to enable virtual machine platform\`r\`nPress y to restart or press any key to exit"
|
||||
\$key = \$Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
|
||||
If ("y" -eq \$key.Character) {
|
||||
Restart-Computer -Confirm
|
||||
}
|
||||
Else {
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
Add-AppxPackage -ForceApplicationShutdown -ForceUpdateFromAnyVersion -Path vclibs.appx
|
||||
Add-AppxPackage -ForceApplicationShutdown -ForceUpdateFromAnyVersion -Path xaml.appx
|
||||
|
||||
\$Installed = \$null
|
||||
\$Installed = Get-AppxPackage -Name 'MicrosoftCorporationII.WindowsSubsystemForAndroid'
|
||||
|
||||
If ((\$null -ne \$Installed) -and (-not (\$Installed.IsDevelopmentMode))) {
|
||||
Clear-Host
|
||||
Write-Warning "There is already one installed WSA. Please uninstall it first.\`r\`nPress y to uninstall existing WSA or press any key to exit"
|
||||
\$key = \$Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
|
||||
If ("y" -eq \$key.Character) {
|
||||
Remove-AppxPackage -Package \$Installed.PackageFullName
|
||||
}
|
||||
Else {
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
Clear-Host
|
||||
Write-Host "Installing MagiskOnWSA..."
|
||||
Stop-Process -Name "wsaclient" -ErrorAction "silentlycontinue"
|
||||
Add-AppxPackage -ForceApplicationShutdown -ForceUpdateFromAnyVersion -Register .\AppxManifest.xml
|
||||
if (\$?) {
|
||||
Finish
|
||||
}
|
||||
Elseif (\$null -ne \$Installed) {
|
||||
Clear-Host
|
||||
Write-Host "Failed to update, try to uninstall existing installation while preserving userdata..."
|
||||
Remove-AppxPackage -PreserveApplicationData -Package \$Installed.PackageFullName
|
||||
Add-AppxPackage -ForceApplicationShutdown -ForceUpdateFromAnyVersion -Register .\AppxManifest.xml
|
||||
if (\$?) {
|
||||
Finish
|
||||
}
|
||||
}
|
||||
Write-Host "All Done\`r\`nPress any key to exit"
|
||||
\$null = \$Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
|
||||
EOF
|
||||
- name: Generate artifact name
|
||||
run: |
|
||||
variant="${{ github.event.inputs.gapps_variant }}"
|
||||
root="${{ github.event.inputs.root_sol }}"
|
||||
if [[ "$root" = "none" ]]; then
|
||||
name1=""
|
||||
elif [[ "$root" = "" ]]; then
|
||||
name1="-with-magisk"
|
||||
else
|
||||
name1="-with-${root}"
|
||||
fi
|
||||
if [[ "$variant" = "none" || "$variant" = "" ]]; then
|
||||
name2="-NoGApps"
|
||||
else
|
||||
if [[ ${{ env.WSA_MAIN_VER }} -ge 2204 && "$variant" != "pico" ]]; then
|
||||
echo "### MagiskOnWSA" >> $GITHUB_STEP_SUMMARY
|
||||
echo ":warning: Since OpenGapps doesn't officially support Android 12.1 yet, lock the variant to pico!" >> $GITHUB_STEP_SUMMARY
|
||||
variant="pico"
|
||||
fi
|
||||
name2="-GApps-${variant}"
|
||||
fi
|
||||
echo "artifact_name=WSA${name1}${name2}_${{ env.WSA_VER }}_${{ matrix.arch }}_${{ env.WSA_REL }}" >> $GITHUB_ENV
|
||||
- name: Upload WSA
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ env.artifact_name }}
|
||||
path: "./${{ matrix.arch }}/*"
|
||||
- name: Delete workflow runs
|
||||
uses: Mattraks/delete-workflow-runs@v2
|
||||
with:
|
||||
token: ${{ github.token }}
|
||||
repository: ${{ github.repository }}
|
||||
retain_days: 0
|
||||
keep_minimum_runs: 0
|
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
download
|
||||
output
|
43
README.md
43
README.md
@ -14,25 +14,15 @@
|
||||
- Merged all language packs
|
||||
- Support managing start menu icons (manually installing [WSAHelper](https://github.com/LSPosed/WSAHelper/releases/latest) to use this feature)
|
||||
|
||||
## Video Guide
|
||||
|
||||
https://user-images.githubusercontent.com/5022927/145696886-e13ebfc1-ff25-4410-893e-d3e517af70ea.mp4
|
||||
|
||||
## Text Guide
|
||||
|
||||
1. Star (if you like) and fork this repo (keep it PUBLIC, private repo is not supported)
|
||||
1. Go to the **Action** tab in your forked repo
|
||||
![Action Tab](https://docs.github.com/assets/images/help/repository/actions-tab.png)
|
||||
1. In the left sidebar, click the **Build WSA** workflow.
|
||||
![Workflow](https://docs.github.com/assets/images/actions-select-workflow.png)
|
||||
1. Above the list of workflow runs, select **Run workflow**
|
||||
![Run Workflow](https://docs.github.com/assets/images/actions-workflow-dispatch.png)
|
||||
1. Select the version of Magisk and select the [OpenGApps variant](https://github.com/opengapps/opengapps/wiki#variants) (none is no OpenGApps) you like, select the root solution (none means no root), select WSA version and its architecture (mostly x64) and click **Run workflow**
|
||||
![Run Workflow](https://docs.github.com/assets/images/actions-manually-run-workflow.png)
|
||||
1. Wait for the action to complete and download the artifact **DO NOT download it via multithread downloaders like IDM or ADM**
|
||||
![Download](https://docs.github.com/assets/images/help/repository/artifact-drop-down-updated.png)
|
||||
1. Unzip the artifact
|
||||
- The size shown in the webpage is uncompressed size and the zip you download will be compressed. So the size of the zip will be much less than the size shown in the webpage.
|
||||
1. Clone the repo to local
|
||||
1. Run `scripts/run.sh`
|
||||
1. Select the version of Magisk and select the [OpenGApps variant](https://github.com/opengapps/opengapps/wiki#variants) you like, select the root solution (none means no root), select WSA version and its architecture (mostly x64)
|
||||
1. Wait for the script to complete and the artifact will in `output` folder
|
||||
|
||||
1. Move the artifact to a places you like
|
||||
1. Right-click `Install.ps1` and select `Run with PowerShell`
|
||||
- If you previously have a MagiskOnWSA installation, it will automatically uninstall the previous while **preserving all userdata** and install the new one, so don't worry about your data.
|
||||
- If you have an official WSA installation, you should uninstall it first. (In case you want to preserve your data, you can backup `%LOCALAPPDATA%\Packages\MicrosoftCorporationII.WindowsSubsystemForAndroid_8wekyb3d8bbwe\LocalCache\userdata.vhdx` before uninstallation and restore it after installation.) (If you want to restore the icons to start menu, please install and use [WSAHelper](https://github.com/LSPosed/WSAHelper/releases/latest).)
|
||||
@ -46,26 +36,13 @@ https://user-images.githubusercontent.com/5022927/145696886-e13ebfc1-ff25-4410-8
|
||||
|
||||
## FAQ
|
||||
|
||||
- Actions workflow task `Delete workflow runs` run Failed
|
||||
|
||||
Check workflow permissions, should be `Read and write permissions`
|
||||
|
||||
![permissions](https://user-images.githubusercontent.com/40033067/168649322-dadaafc9-dd31-4922-afe1-8aa933b7b036.png)
|
||||
|
||||
Read the [Github Docs](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#configuring-the-default-github_token-permissions) to find out how to change this setting
|
||||
|
||||
- Why should we delete old workflow runs?
|
||||
|
||||
Keeping old workflow runs can take up a lot of storage resources and is suspected to be abusive, which can lead to banning.
|
||||
- Can I delete the unzipped folder?
|
||||
- Can I delete the installed folder?
|
||||
|
||||
No.
|
||||
- Why the size of the zip does not match the one shown?
|
||||
|
||||
The zip you downloaded is compressed and Github is showing the uncompressed size.
|
||||
- How can I update WSA to new version?
|
||||
|
||||
Rerun the Github action, download the new artifact, replace the content of your previous installation and rerun `Install.ps1`. Don't worry, your data will be preserved.
|
||||
Delete `download` folder
|
||||
Rerun the script, replace the content of your previous installation and rerun `Install.ps1`. Don't worry, your data will be preserved.
|
||||
- How can I get the logcat from WSA?
|
||||
|
||||
`%LOCALAPPDATA%\Packages\MicrosoftCorporationII.WindowsSubsystemForAndroid_8wekyb3d8bbwe\LocalState\diagnostics\logcat`
|
||||
@ -93,7 +70,7 @@ https://user-images.githubusercontent.com/5022927/145696886-e13ebfc1-ff25-4410-8
|
||||
- How can I get rid of Magisk?
|
||||
|
||||
Choose `none` as root solution.
|
||||
- Github Action script is updated, how can I synchronize it?
|
||||
- Github script is updated, how can I synchronize it?
|
||||
|
||||
1. In your fork repository, click `fetch upstream`
|
||||
![fetch](https://docs.github.com/assets/cb-33284/images/help/repository/fetch-upstream-drop-down.png)
|
||||
|
43
scripts/downloadGapps.py
Normal file
43
scripts/downloadGapps.py
Normal file
@ -0,0 +1,43 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
|
||||
import requests
|
||||
import zipfile
|
||||
import os
|
||||
import urllib.request
|
||||
import json
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
if not os.path.exists(Path.cwd().parent / "download"):
|
||||
os.makedirs(Path.cwd().parent / "download")
|
||||
download_dir = Path.cwd().parent / "download"
|
||||
|
||||
arch = sys.argv[1]
|
||||
# TODO: Keep it pico since other variants of opengapps are unable to boot successfully
|
||||
variant = sys.argv[2] if 0 else "pico"
|
||||
abi_map = {"x64": "x86_64", "arm64": "arm64"}
|
||||
# TODO: keep it 11.0 since opengapps does not support 12+ yet
|
||||
# As soon as opengapps is available for 12+, we need to get the sdk/release from build.prop and
|
||||
# download the corresponding version
|
||||
release = "11.0"
|
||||
try:
|
||||
res = requests.get(f"https://api.opengapps.org/list")
|
||||
j = json.loads(res.content)
|
||||
link = {i["name"]: i for i in j["archs"][abi_map[arch]]
|
||||
["apis"][release]["variants"]}[variant]["zip"]
|
||||
except Exception:
|
||||
print("Failed to fetch from opengapps api, fallbacking to sourceforge rss...")
|
||||
res = requests.get(
|
||||
f'https://sourceforge.net/projects/opengapps/rss?path=/{abi_map[arch]}&limit=100')
|
||||
link = re.search(f'https://.*{abi_map[arch]}/.*{release}.*{variant}.*\.zip/download', res.text).group().replace(
|
||||
'.zip/download', '.zip').replace('sourceforge.net/projects/opengapps/files', 'downloads.sourceforge.net/project/opengapps')
|
||||
|
||||
print(f"downloading link: {link}", flush=True)
|
||||
|
||||
out_file = download_dir / "gapps.zip"
|
||||
|
||||
if not os.path.isfile(out_file):
|
||||
urllib.request.urlretrieve(link, out_file)
|
||||
print("done", flush=True)
|
75
scripts/downloadMagisk.py
Normal file
75
scripts/downloadMagisk.py
Normal file
@ -0,0 +1,75 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
|
||||
import urllib.request
|
||||
import zipfile
|
||||
import os
|
||||
import json
|
||||
import requests
|
||||
from pathlib import Path
|
||||
|
||||
magisk_apk = sys.argv[2]
|
||||
|
||||
if not os.path.exists(Path.cwd().parent / "download"):
|
||||
os.makedirs(Path.cwd().parent / "download")
|
||||
download_dir = Path.cwd().parent / "download"
|
||||
|
||||
if not os.path.exists(Path.cwd().parent / "workdir" / "magisk"):
|
||||
os.makedirs(Path.cwd().parent / "workdir" / "magisk")
|
||||
workdir = Path.cwd().parent / "workdir" / "magisk"
|
||||
|
||||
if not magisk_apk:
|
||||
magisk_apk = "stable"
|
||||
if magisk_apk == "stable" or magisk_apk == "beta" or magisk_apk == "canary" or magisk_apk == "debug":
|
||||
magisk_apk = json.loads(requests.get(
|
||||
f"https://github.com/topjohnwu/magisk-files/raw/master/{magisk_apk}.json").content)['magisk']['link']
|
||||
|
||||
out_file = download_dir / "magisk.zip"
|
||||
|
||||
arch = sys.argv[1]
|
||||
|
||||
abi_map = {"x64": ["x86_64", "x86"], "arm64": ["arm64-v8a", "armeabi-v7a"]}
|
||||
|
||||
if not os.path.isfile(out_file):
|
||||
urllib.request.urlretrieve(magisk_apk, out_file)
|
||||
|
||||
|
||||
def extract_as(zip, name, as_name, dir):
|
||||
info = zip.getinfo(name)
|
||||
info.filename = as_name
|
||||
zip.extract(info, workdir / dir)
|
||||
|
||||
|
||||
with zipfile.ZipFile(out_file) as zip:
|
||||
extract_as(
|
||||
zip, f"lib/{ abi_map[arch][0] }/libmagisk64.so", "magisk64", "magisk")
|
||||
extract_as(
|
||||
zip, f"lib/{ abi_map[arch][1] }/libmagisk32.so", "magisk32", "magisk")
|
||||
standalone_policy = False
|
||||
try:
|
||||
zip.getinfo(f"lib/{ abi_map[arch][0] }/libmagiskpolicy.so")
|
||||
standalone_policy = True
|
||||
except:
|
||||
pass
|
||||
extract_as(
|
||||
zip, f"lib/{ abi_map[arch][0] }/libmagiskinit.so", "magiskinit", "magisk")
|
||||
if standalone_policy:
|
||||
extract_as(
|
||||
zip, f"lib/{ abi_map[arch][0] }/libmagiskpolicy.so", "magiskpolicy", "magisk")
|
||||
else:
|
||||
extract_as(
|
||||
zip, f"lib/{ abi_map[arch][0] }/libmagiskinit.so", "magiskpolicy", "magisk")
|
||||
extract_as(
|
||||
zip, f"lib/{ abi_map[arch][0] }/libmagiskboot.so", "magiskboot", "magisk")
|
||||
extract_as(
|
||||
zip, f"lib/{ abi_map[arch][0] }/libbusybox.so", "busybox", "magisk")
|
||||
if standalone_policy:
|
||||
extract_as(
|
||||
zip, f"lib/{ abi_map['x64'][0] }/libmagiskpolicy.so", "magiskpolicy", ".")
|
||||
else:
|
||||
extract_as(
|
||||
zip, f"lib/{ abi_map['x64'][0] }/libmagiskinit.so", "magiskpolicy", ".")
|
||||
extract_as(zip, f"assets/boot_patch.sh", "boot_patch.sh", "magisk")
|
||||
extract_as(zip, f"assets/util_functions.sh",
|
||||
"util_functions.sh", "magisk")
|
90
scripts/downloadWSA.py
Normal file
90
scripts/downloadWSA.py
Normal file
@ -0,0 +1,90 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
|
||||
import requests
|
||||
from xml.dom import minidom
|
||||
import html
|
||||
import warnings
|
||||
import re
|
||||
import zipfile
|
||||
import os
|
||||
import urllib.request
|
||||
from pathlib import Path
|
||||
|
||||
warnings.filterwarnings("ignore")
|
||||
|
||||
arch = sys.argv[1]
|
||||
release_type_map = {"retail": "Retail", "release preview": "RP",
|
||||
"insider slow": "WIS", "insider fast": "WIF"}
|
||||
release_type = release_type_map[sys.argv[2]] if sys.argv[2] != "" else "Retail"
|
||||
|
||||
cat_id = '858014f3-3934-4abe-8078-4aa193e74ca8'
|
||||
print("arch=" + arch + " release_type=" + release_type)
|
||||
|
||||
with open(Path.cwd().parent / ("xml/GetCookie.xml"), "r") as f:
|
||||
cookie_content = f.read()
|
||||
|
||||
out = requests.post(
|
||||
'https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx',
|
||||
data=cookie_content,
|
||||
headers={'Content-Type': 'application/soap+xml; charset=utf-8'},
|
||||
verify=False
|
||||
)
|
||||
doc = minidom.parseString(out.text)
|
||||
cookie = doc.getElementsByTagName('EncryptedData')[0].firstChild.nodeValue
|
||||
|
||||
print(cookie)
|
||||
|
||||
with open(Path.cwd().parent / "xml/WUIDRequest.xml", "r") as f:
|
||||
cat_id_content = f.read().format(cookie, cat_id, release_type)
|
||||
|
||||
out = requests.post(
|
||||
'https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx',
|
||||
data=cat_id_content,
|
||||
headers={'Content-Type': 'application/soap+xml; charset=utf-8'},
|
||||
verify=False
|
||||
)
|
||||
|
||||
doc = minidom.parseString(html.unescape(out.text))
|
||||
|
||||
filenames = {}
|
||||
for node in doc.getElementsByTagName('Files'):
|
||||
filenames[node.parentNode.parentNode.getElementsByTagName(
|
||||
'ID')[0].firstChild.nodeValue] = f"{node.firstChild.attributes['InstallerSpecificIdentifier'].value}_{node.firstChild.attributes['FileName'].value}"
|
||||
pass
|
||||
|
||||
identities = []
|
||||
for node in doc.getElementsByTagName('SecuredFragment'):
|
||||
filename = filenames[node.parentNode.parentNode.parentNode.getElementsByTagName('ID')[
|
||||
0].firstChild.nodeValue]
|
||||
update_identity = node.parentNode.parentNode.firstChild
|
||||
identities += [(update_identity.attributes['UpdateID'].value,
|
||||
update_identity.attributes['RevisionNumber'].value, filename)]
|
||||
|
||||
with open(Path.cwd().parent / "xml/FE3FileUrl.xml", "r") as f:
|
||||
file_content = f.read()
|
||||
if not os.path.exists(Path.cwd().parent / "download"):
|
||||
os.makedirs(Path.cwd().parent / "download")
|
||||
for i, v, f in identities:
|
||||
if re.match(f"Microsoft\.UI\.Xaml\..*_{arch}_.*\.appx", f):
|
||||
out_file = Path.cwd().parent / "download/xaml.appx"
|
||||
elif re.match(f"Microsoft\.VCLibs\..*_{arch}_.*\.appx", f):
|
||||
out_file = Path.cwd().parent / "download/vclibs.appx"
|
||||
elif re.match(f"MicrosoftCorporationII\.WindowsSubsystemForAndroid_.*\.msixbundle", f):
|
||||
out_file = Path.cwd().parent / "download/wsa.zip"
|
||||
else:
|
||||
continue
|
||||
out = requests.post(
|
||||
'https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx/secured',
|
||||
data=file_content.format(i, v, release_type),
|
||||
headers={'Content-Type': 'application/soap+xml; charset=utf-8'},
|
||||
verify=False
|
||||
)
|
||||
doc = minidom.parseString(out.text)
|
||||
for l in doc.getElementsByTagName("FileLocation"):
|
||||
url = l.getElementsByTagName("Url")[0].firstChild.nodeValue
|
||||
if len(url) != 99:
|
||||
if not os.path.isfile(out_file):
|
||||
print(f"downloading link: {url} to {out_file}", flush=True)
|
||||
urllib.request.urlretrieve(url, out_file)
|
60
scripts/extractWSA.py
Normal file
60
scripts/extractWSA.py
Normal file
@ -0,0 +1,60 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
|
||||
import requests
|
||||
from xml.dom import minidom
|
||||
import html
|
||||
import warnings
|
||||
import re
|
||||
import zipfile
|
||||
import os
|
||||
import urllib.request
|
||||
from pathlib import Path
|
||||
|
||||
warnings.filterwarnings("ignore")
|
||||
|
||||
arch = sys.argv[1]
|
||||
|
||||
if not os.path.exists(Path.cwd().parent / "workdir" / "wsa"):
|
||||
os.makedirs(Path.cwd().parent / "workdir" / "wsa")
|
||||
zip_name = ""
|
||||
workdir = Path.cwd().parent / "workdir" / "wsa"
|
||||
with zipfile.ZipFile(Path.cwd().parent / "download/wsa.zip") as zip:
|
||||
for f in zip.filelist:
|
||||
if arch in f.filename.lower():
|
||||
zip_name = f.filename
|
||||
if not os.path.isfile(workdir / zip_name):
|
||||
zip_path = workdir / zip_name
|
||||
print(f"unzipping to {workdir}", flush=True)
|
||||
zip.extract(f, workdir)
|
||||
ver_no = zip_name.split("_")
|
||||
long_ver = ver_no[1]
|
||||
ver = long_ver.split(".")
|
||||
main_ver = ver[0]
|
||||
with open(os.environ['WSA_WORK_ENV'], 'a') as g:
|
||||
g.write(f'WSA_VER={long_ver}\n')
|
||||
with open(os.environ['WSA_WORK_ENV'], 'a') as g:
|
||||
g.write(f'WSA_MAIN_VER={main_ver}\n')
|
||||
rel = ver_no[3].split(".")
|
||||
rell = str(rel[0])
|
||||
with open(os.environ['WSA_WORK_ENV'], 'a') as g:
|
||||
g.write(f'WSA_REL={rell}\n')
|
||||
if 'language' in f.filename.lower() or 'scale' in f.filename.lower():
|
||||
name = f.filename.split("-", 1)[1].split(".")[0]
|
||||
zip.extract(f, workdir)
|
||||
with zipfile.ZipFile(workdir / f.filename) as l:
|
||||
for g in l.filelist:
|
||||
if g.filename == 'resources.pri':
|
||||
g.filename = f'{name}.pri'
|
||||
l.extract(g, workdir / 'pri')
|
||||
print(f"extract resource pack {g.filename}")
|
||||
elif g.filename == 'AppxManifest.xml':
|
||||
g.filename = f'{name}.xml'
|
||||
l.extract(g, workdir / 'xml')
|
||||
with zipfile.ZipFile(zip_path) as zip:
|
||||
if not os.path.isdir(workdir / arch):
|
||||
print(f"unzipping from {zip_path}", flush=True)
|
||||
zip.extractall(workdir / arch)
|
||||
|
||||
print("done", flush=True)
|
73
scripts/fixGappsProp.py
Normal file
73
scripts/fixGappsProp.py
Normal file
@ -0,0 +1,73 @@
|
||||
from __future__ import annotations
|
||||
from io import TextIOWrapper
|
||||
from os import system, path
|
||||
from typing import OrderedDict
|
||||
import sys
|
||||
class Prop(OrderedDict):
|
||||
def __init__(self, file: TextIOWrapper) -> None:
|
||||
super().__init__()
|
||||
for i, line in enumerate(file.read().splitlines(False)):
|
||||
if '=' in line:
|
||||
k, v = line.split('=', 2)
|
||||
self[k] = v
|
||||
else:
|
||||
self[f".{i}"] = line
|
||||
|
||||
def __str__(self) -> str:
|
||||
return '\n'.join([v if k.startswith('.') else f"{k}={v}" for k, v in self.items()])
|
||||
|
||||
def __iadd__(self, other: str) -> Prop:
|
||||
self[f".{len(self)}"] = other
|
||||
return self
|
||||
|
||||
|
||||
new_props = {
|
||||
("product", "brand"): "google",
|
||||
("product", "manufacturer"): "Google",
|
||||
("build", "product"): "redfin",
|
||||
("product", "name"): "redfin",
|
||||
("product", "device"): "redfin",
|
||||
("product", "model"): "Pixel 5",
|
||||
("build", "flavor"): "redfin-user"
|
||||
}
|
||||
|
||||
|
||||
def description(sec: str, p: Prop) -> str:
|
||||
return f"{p[f'ro.{sec}.build.flavor']} {p[f'ro.{sec}.build.version.release_or_codename']} {p[f'ro.{sec}.build.id']} {p[f'ro.{sec}.build.version.incremental']} {p[f'ro.{sec}.build.tags']}"
|
||||
|
||||
|
||||
def fingerprint(sec: str, p: Prop) -> str:
|
||||
return f"""{p[f"ro.product.{sec}.brand"]}/{p[f"ro.product.{sec}.name"]}/{p[f"ro.product.{sec}.device"]}:{p[f"ro.{sec}.build.version.release"]}/{p[f"ro.{sec}.build.id"]}/{p[f"ro.{sec}.build.version.incremental"]}:{p[f"ro.{sec}.build.type"]}/{p[f"ro.{sec}.build.tags"]}"""
|
||||
|
||||
|
||||
def fix_prop(sec, prop):
|
||||
if not path.exists(prop):
|
||||
return
|
||||
|
||||
print(f"fixing {prop}", flush=True)
|
||||
with open(prop, 'r') as f:
|
||||
p = Prop(f)
|
||||
|
||||
p += "# extra prop added by MagiskOnWSA"
|
||||
|
||||
for k, v in new_props.items():
|
||||
p[f"ro.{k[0]}.{k[1]}"] = v
|
||||
|
||||
if k[0] == "build":
|
||||
p[f"ro.{sec}.{k[0]}.{k[1]}"] = v
|
||||
elif k[0] == "product":
|
||||
p[f"ro.{k[0]}.{sec}.{k[1]}"] = v
|
||||
|
||||
p["ro.build.description"] = description(sec, p)
|
||||
p[f"ro.build.fingerprint"] = fingerprint(sec, p)
|
||||
p[f"ro.{sec}.build.description"] = description(sec, p)
|
||||
p[f"ro.{sec}.build.fingerprint"] = fingerprint(sec, p)
|
||||
p[f"ro.bootimage.build.fingerprint"] = fingerprint(sec, p)
|
||||
|
||||
with open(prop, 'w') as f:
|
||||
f.write(str(p))
|
||||
|
||||
|
||||
sys_path = sys.argv[1]
|
||||
for sec, prop in {"system": sys_path+"/system/build.prop", "product": sys_path+"/product/build.prop", "system_ext": sys_path+"/system_ext/build.prop", "vendor": sys_path+"/vendor/build.prop", "odm": sys_path+"/vendor/odm/etc/build.prop"}.items():
|
||||
fix_prop(sec, prop)
|
435
scripts/run.sh
Normal file
435
scripts/run.sh
Normal file
@ -0,0 +1,435 @@
|
||||
#!/bin/bash
|
||||
|
||||
function Radiolist {
|
||||
declare -A o="$1"
|
||||
shift
|
||||
whiptail --nocancel --radiolist "${o[title]}" \
|
||||
0 0 0 "$@" 3>&1 1>&2 2>&3
|
||||
if [ $? != 0 ]; then
|
||||
echo "${o[default]}"
|
||||
fi
|
||||
}
|
||||
|
||||
function YesNoBox {
|
||||
declare -A o="$1"
|
||||
shift
|
||||
whiptail --title "${o[title]}" --yesno "${o[text]}" 0 0
|
||||
}
|
||||
|
||||
echo "Dependencies"
|
||||
sudo apt update && sudo apt -y install setools lzip wine winetricks patchelf
|
||||
cp -r ../wine/.cache/* ~/.cache
|
||||
winetricks msxml6
|
||||
|
||||
# ARCH=$(whiptail --nocancel --separate-output --checklist 'Build arch' 0 0 0 'x64' "X86_64" 'on' 'arm64' "AArch64" 'off' 3>&1 1>&2 2>&3)
|
||||
# if [ $? != 0 ]; then
|
||||
# ARCH=x64
|
||||
# fi
|
||||
|
||||
ARCH=$(
|
||||
Radiolist '([title]="Build arch"
|
||||
[default]="x64")' \
|
||||
\
|
||||
'x64' "X86_64" 'on' \
|
||||
'arm64' "AArch64" 'off'
|
||||
)
|
||||
|
||||
RELEASE_TYPE=$(
|
||||
Radiolist '([title]="WSA release type"
|
||||
[default]="retail")' \
|
||||
\
|
||||
'retail' "Stable Channel" 'on' \
|
||||
'release preview' "Release Preview Channel" 'off' \
|
||||
'insider slow' "Beta Channel" 'off' \
|
||||
'insider fast' "Dev Channel" 'off'
|
||||
)
|
||||
|
||||
MAGISK_VER=$(
|
||||
Radiolist '([title]="Magisk version"
|
||||
[default]="stable")' \
|
||||
\
|
||||
'stable' "Stable Channel" 'on' \
|
||||
'beta' "Beta Channel" 'off' \
|
||||
'canary' "Canary Channel" 'off' \
|
||||
'debug' "Canary Channel Debug Build" 'off'
|
||||
)
|
||||
if (YesNoBox '([title]="Install Gapps" [text]="Do you want to install gapps?")'); then
|
||||
GAPPS_VARIANT=$(
|
||||
Radiolist '([title]="Variants of gapps"
|
||||
[default]="pico")' \
|
||||
\
|
||||
'super' "" 'off' \
|
||||
'stock' "" 'off' \
|
||||
'full' "" 'off' \
|
||||
'mini' "" 'off' \
|
||||
'micro' "" 'off' \
|
||||
'nano' "" 'off' \
|
||||
'pico' "" 'on' \
|
||||
'tvstock' "" 'off' \
|
||||
'tvmini' "" 'off'
|
||||
)
|
||||
else
|
||||
GAPPS_VARIANT="none"
|
||||
fi
|
||||
|
||||
if (YesNoBox '([title]="Remove Amazon AppStore" [text]="Do you want to remove amazon appStore?")'); then
|
||||
REMOVE_AMAZON="remove"
|
||||
else
|
||||
REMOVE_AMAZON="keep"
|
||||
fi
|
||||
|
||||
ROOT_SOL=$(
|
||||
Radiolist '([title]="Root solution"
|
||||
[default]="magisk")' \
|
||||
\
|
||||
'magisk' "" 'on' \
|
||||
'none' "" 'off'
|
||||
)
|
||||
|
||||
clear
|
||||
echo -e "ARCH=$ARCH\nRELEASE_TYPE=$RELEASE_TYPE\nMAGISK_VER=$MAGISK_VER\nGAPPS_VARIANT=$GAPPS_VARIANT\nREMOVE_AMAZON=$REMOVE_AMAZON\nROOT_SOL=$ROOT_SOL"
|
||||
|
||||
echo "Download WSA"
|
||||
python3 downloadWSA.py "$ARCH" "$RELEASE_TYPE"
|
||||
|
||||
echo "extractWSA"
|
||||
WSA_WORK_ENV=../workdir/ENV
|
||||
if [ -f $WSA_WORK_ENV ]; then rm -f $WSA_WORK_ENV; fi
|
||||
export WSA_WORK_ENV
|
||||
python3 extractWSA.py "$ARCH"
|
||||
|
||||
echo "Download Magisk"
|
||||
python3 downloadMagisk.py "$ARCH" "$MAGISK_VER"
|
||||
|
||||
echo "Download OpenGApps"
|
||||
python3 downloadGapps.py "$ARCH" "$MAGISK_VER"
|
||||
|
||||
echo "Extract GApps"
|
||||
if [ $GAPPS_VARIANT != 'none' ] && [ $GAPPS_VARIANT != '' ]; then
|
||||
mkdir ../workdir/gapps
|
||||
unzip -p ../download/gapps.zip {Core,GApps}/'*.lz' | tar --lzip -C ../workdir/gapps -xvf - -i --strip-components=2 --exclude='setupwizardtablet-x86_64' --exclude='packageinstallergoogle-all' --exclude='speech-common' --exclude='markup-lib-arm' --exclude='markup-lib-arm64' --exclude='markup-all' --exclude='setupwizarddefault-x86_64' --exclude='pixellauncher-all' --exclude='pixellauncher-common'
|
||||
fi
|
||||
|
||||
echo "Expand images"
|
||||
|
||||
e2fsck -yf ../workdir/wsa/$ARCH/system_ext.img
|
||||
SYSTEM_EXT_SIZE=$(($(du -sB512 ../workdir/wsa/$ARCH/system_ext.img | cut -f1) + 20000))
|
||||
resize2fs ../workdir/wsa/$ARCH/system_ext.img "$SYSTEM_EXT_SIZE"s
|
||||
|
||||
e2fsck -yf ../workdir/wsa/$ARCH/product.img
|
||||
PRODUCT_SIZE=$(($(du -sB512 ../workdir/wsa/$ARCH/product.img | cut -f1) + 20000))
|
||||
if [ -d ../workdir/gapps/product ]; then
|
||||
PRODUCT_SIZE=$(($PRODUCT_SIZE + $(du -sB512 ../workdir/gapps/product | cut -f1)))
|
||||
fi
|
||||
resize2fs ../workdir/wsa/$ARCH/product.img "$PRODUCT_SIZE"s
|
||||
|
||||
e2fsck -yf ../workdir/wsa/$ARCH/system.img
|
||||
SYSTEM_SIZE=$(($(du -sB512 ../workdir/wsa/$ARCH/system.img | cut -f1) + 20000))
|
||||
if [ -d ../workdir/gapps ]; then
|
||||
SYSTEM_SIZE=$(($SYSTEM_SIZE + $(du -sB512 ../workdir/gapps | cut -f1) - $(du -sB512 ../workdir/gapps/product | cut -f1)))
|
||||
fi
|
||||
if [ -d ../workdir/magisk ]; then
|
||||
SYSTEM_SIZE=$(($SYSTEM_SIZE + $(du -sB512 ../workdir/magisk/magisk | cut -f1)))
|
||||
fi
|
||||
if [ -f ../download/magisk.zip ]; then
|
||||
SYSTEM_SIZE=$(($SYSTEM_SIZE + $(du -sB512 ../download/magisk.zip | cut -f1)))
|
||||
fi
|
||||
resize2fs ../workdir/wsa/$ARCH/system.img "$SYSTEM_SIZE"s
|
||||
|
||||
e2fsck -yf ../workdir/wsa/$ARCH/vendor.img
|
||||
VENDOR_SIZE=$(($(du -sB512 ../workdir/wsa/$ARCH/vendor.img | cut -f1) + 20000))
|
||||
resize2fs ../workdir/wsa/$ARCH/vendor.img "$VENDOR_SIZE"s
|
||||
|
||||
echo "Mount images"
|
||||
MOUNT_DIR=../workdir/system
|
||||
sudo mkdir $MOUNT_DIR
|
||||
sudo mount -o loop ../workdir/wsa/$ARCH/system.img $MOUNT_DIR
|
||||
sudo mount -o loop ../workdir/wsa/$ARCH/vendor.img $MOUNT_DIR/vendor
|
||||
sudo mount -o loop ../workdir/wsa/$ARCH/product.img $MOUNT_DIR/product
|
||||
sudo mount -o loop ../workdir/wsa/$ARCH/system_ext.img $MOUNT_DIR/system_ext
|
||||
|
||||
echo "Remove Amazon AppStore"
|
||||
if [ $REMOVE_AMAZON = 'remove' ]; then
|
||||
find $MOUNT_DIR/product/{etc/permissions,etc/sysconfig,framework,priv-app} | grep -e amazon -e venezia | sudo xargs rm -rf
|
||||
fi
|
||||
|
||||
echo "Integrate Magisk"
|
||||
if [ $ROOT_SOL = 'magisk' ] || [ $ROOT_SOL = '' ]; then
|
||||
sudo mkdir $MOUNT_DIR/sbin
|
||||
sudo chcon --reference $MOUNT_DIR/init.environ.rc $MOUNT_DIR/sbin
|
||||
sudo chown root:root $MOUNT_DIR/sbin
|
||||
sudo chmod 0700 $MOUNT_DIR/sbin
|
||||
sudo cp ../workdir/magisk/magisk/* $MOUNT_DIR/sbin/
|
||||
sudo cp ../download/magisk.zip $MOUNT_DIR/sbin/magisk.apk
|
||||
sudo tee -a $MOUNT_DIR/sbin/loadpolicy.sh <<EOF
|
||||
#!/system/bin/sh
|
||||
mkdir -p /data/adb/magisk
|
||||
cp /sbin/* /data/adb/magisk/
|
||||
chmod -R 755 /data/adb/magisk
|
||||
restorecon -R /data/adb/magisk
|
||||
for module in \$(ls /data/adb/modules); do
|
||||
if ! [ -f "/data/adb/modules/\$module/disable" ] && [ -f "/data/adb/modules/\$module/sepolicy.rule" ]; then
|
||||
/sbin/magiskpolicy --live --apply "/data/adb/modules/\$module/sepolicy.rule"
|
||||
fi
|
||||
done
|
||||
EOF
|
||||
|
||||
sudo find $MOUNT_DIR/sbin -type f -exec chmod 0755 {} \;
|
||||
sudo find $MOUNT_DIR/sbin -type f -exec chown root:root {} \;
|
||||
sudo find $MOUNT_DIR/sbin -type f -exec chcon --reference $MOUNT_DIR/product {} \;
|
||||
sudo patchelf --replace-needed libc.so "../linker/libc.so" ../workdir/magisk/magiskpolicy || true
|
||||
sudo patchelf --replace-needed libm.so "../linker/libm.so" ../workdir/magisk/magiskpolicy || true
|
||||
sudo patchelf --replace-needed libdl.so "../linker/libdl.so" ../workdir/magisk/magiskpolicy || true
|
||||
sudo patchelf --set-interpreter "../linker/linker64" ../workdir/magisk/magiskpolicy || true
|
||||
chmod +x ../workdir/magisk/magiskpolicy
|
||||
echo '/dev/wsa-magisk(/.*)? u:object_r:magisk_file:s0' | sudo tee -a $MOUNT_DIR/vendor/etc/selinux/vendor_file_contexts
|
||||
echo '/data/adb/magisk(/.*)? u:object_r:magisk_file:s0' | sudo tee -a $MOUNT_DIR/vendor/etc/selinux/vendor_file_contexts
|
||||
sudo ../workdir/magisk/magiskpolicy --load $MOUNT_DIR/vendor/etc/selinux/precompiled_sepolicy --save $MOUNT_DIR/vendor/etc/selinux/precompiled_sepolicy --magisk "allow * magisk_file lnk_file *"
|
||||
sudo tee -a $MOUNT_DIR/system/etc/init/hw/init.rc <<EOF
|
||||
on post-fs-data
|
||||
start logd
|
||||
start adbd
|
||||
mkdir /dev/wsa-magisk
|
||||
mount tmpfs tmpfs /dev/wsa-magisk mode=0755
|
||||
copy /sbin/magisk64 /dev/wsa-magisk/magisk64
|
||||
chmod 0755 /dev/wsa-magisk/magisk64
|
||||
symlink ./magisk64 /dev/wsa-magisk/magisk
|
||||
symlink ./magisk64 /dev/wsa-magisk/su
|
||||
symlink ./magisk64 /dev/wsa-magisk/resetprop
|
||||
copy /sbin/magisk32 /dev/wsa-magisk/magisk32
|
||||
chmod 0755 /dev/wsa-magisk/magisk32
|
||||
copy /sbin/magiskinit /dev/wsa-magisk/magiskinit
|
||||
chmod 0755 /dev/wsa-magisk/magiskinit
|
||||
copy /sbin/magiskpolicy /dev/wsa-magisk/magiskpolicy
|
||||
chmod 0755 /dev/wsa-magisk/magiskpolicy
|
||||
mkdir /dev/wsa-magisk/.magisk 700
|
||||
mkdir /dev/wsa-magisk/.magisk/mirror 700
|
||||
mkdir /dev/wsa-magisk/.magisk/block 700
|
||||
copy /sbin/magisk.apk /dev/wsa-magisk/stub.apk
|
||||
rm /dev/.magisk_unblock
|
||||
start IhhslLhHYfse
|
||||
start FAhW7H9G5sf
|
||||
wait /dev/.magisk_unblock 40
|
||||
rm /dev/.magisk_unblock
|
||||
|
||||
service IhhslLhHYfse /system/bin/sh /sbin/loadpolicy.sh
|
||||
user root
|
||||
seclabel u:r:magisk:s0
|
||||
oneshot
|
||||
|
||||
service FAhW7H9G5sf /dev/wsa-magisk/magisk --post-fs-data
|
||||
user root
|
||||
seclabel u:r:magisk:s0
|
||||
oneshot
|
||||
|
||||
service HLiFsR1HtIXVN6 /dev/wsa-magisk/magisk --service
|
||||
class late_start
|
||||
user root
|
||||
seclabel u:r:magisk:s0
|
||||
oneshot
|
||||
|
||||
on property:sys.boot_completed=1
|
||||
mkdir /data/adb/magisk 755
|
||||
copy /sbin/magisk.apk /data/adb/magisk/magisk.apk
|
||||
start YqCTLTppv3ML
|
||||
|
||||
service YqCTLTppv3ML /dev/wsa-magisk/magisk --boot-complete
|
||||
user root
|
||||
seclabel u:r:magisk:s0
|
||||
oneshot
|
||||
EOF
|
||||
fi
|
||||
|
||||
echo "Merge Language Resources"
|
||||
cp ../workdir/wsa/$ARCH/resources.pri ../workdir/wsa/pri/en-us.pri
|
||||
cp ../workdir/wsa/$ARCH/AppxManifest.xml ../workdir/wsa/xml/en-us.xml
|
||||
tee ../workdir/wsa/priconfig.xml <<EOF
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<resources targetOsVersion="10.0.0" majorVersion="1">
|
||||
<index root="\" startIndexAt="\">
|
||||
<indexer-config type="folder" foldernameAsQualifier="true" filenameAsQualifier="true" qualifierDelimiter="."/>
|
||||
<indexer-config type="PRI"/>
|
||||
</index>
|
||||
</resources>
|
||||
EOF
|
||||
wine64 ../wine/makepri.exe new /pr ../workdir/wsa/pri /in MicrosoftCorporationII.WindowsSubsystemForAndroid /cf ../workdir/wsa/priconfig.xml /of ../workdir/wsa/$ARCH/resources.pri /o
|
||||
sed -i -zE "s/<Resources.*Resources>/<Resources>\n$(cat ../workdir/wsa/xml/* | grep -Po '<Resource [^>]*/>' | sed ':a;N;$!ba;s/\n/\\n/g' | sed 's/\$/\\$/g' | sed 's/\//\\\//g')\n<\/Resources>/g" ../workdir/wsa/$ARCH/AppxManifest.xml
|
||||
|
||||
echo "Add extra packages"
|
||||
sudo cp -r ""../$ARCH/system/*"" $MOUNT_DIR
|
||||
sudo find $MOUNT_DIR/system/priv-app -type d -exec chmod 0755 {} \;
|
||||
sudo find $MOUNT_DIR/system/priv-app -type f -exec chmod 0644 {} \;
|
||||
sudo find $MOUNT_DIR/system/priv-app -exec chcon --reference=$MOUNT_DIR/system/priv-app {} \;
|
||||
|
||||
echo "Integrate GApps"
|
||||
if [ $GAPPS_VARIANT != 'none' ] && [ $GAPPS_VARIANT != '' ]; then
|
||||
cp -r ../$ARCH/gapps/* ../workdir/gapps
|
||||
shopt -s extglob
|
||||
sudo cp -vr ../workdir/gapps/product/* $MOUNT_DIR/product/
|
||||
rm -rf ../workdir/gapps/product
|
||||
sudo cp -vr ../workdir/gapps/* $MOUNT_DIR/system
|
||||
|
||||
sudo find $MOUNT_DIR/system/{app,etc,framework,priv-app} -exec chown root:root {} \;
|
||||
sudo find $MOUNT_DIR/product/{app,etc,overlay,priv-app} -exec chown root:root {} \;
|
||||
|
||||
sudo find $MOUNT_DIR/system/{app,etc,framework,priv-app} -type d -exec chmod 0755 {} \;
|
||||
sudo find $MOUNT_DIR/product/{app,etc,overlay,priv-app} -type d -exec chmod 0755 {} \;
|
||||
|
||||
sudo find $MOUNT_DIR/system/{app,framework,priv-app} -type f -exec chmod 0644 {} \;
|
||||
ls ../workdir/gapps/etc/ | xargs -n 1 -I dir sudo find $MOUNT_DIR/system/etc/dir -type f -exec chmod 0644 {} \;
|
||||
sudo find $MOUNT_DIR/product/{app,etc,overlay,priv-app} -type f -exec chmod 0644 {} \;
|
||||
|
||||
sudo find $MOUNT_DIR/system/{app,framework,priv-app} -type d -exec chcon --reference=$MOUNT_DIR/system/app {} \;
|
||||
sudo find $MOUNT_DIR/product/{app,etc,overlay,priv-app} -type d -exec chcon --reference=$MOUNT_DIR/product/app {} \;
|
||||
ls ../workdir/gapps/etc/ | xargs -n 1 -I dir sudo find $MOUNT_DIR/system/etc/dir -type d -exec chcon --reference=$MOUNT_DIR/system/etc/permissions {} \;
|
||||
|
||||
sudo find $MOUNT_DIR/system/{app,framework,priv-app} -type f -exec chcon --reference=$MOUNT_DIR/system/framework/ext.jar {} \;
|
||||
ls ../workdir/gapps/etc/ | xargs -n 1 -I dir sudo find $MOUNT_DIR/system/etc/dir -type f -exec chcon --reference=$MOUNT_DIR/system/etc/permissions {} \;
|
||||
sudo find $MOUNT_DIR/product/{app,etc,overlay,priv-app} -type f -exec chcon --reference=$MOUNT_DIR/product/etc/permissions/com.android.settings.intelligence.xml {} \;
|
||||
sudo patchelf --replace-needed libc.so "../linker/libc.so" ../workdir/magisk/magiskpolicy || true
|
||||
sudo patchelf --replace-needed libm.so "../linker/libm.so" ../workdir/magisk/magiskpolicy || true
|
||||
sudo patchelf --replace-needed libdl.so "../linker/libdl.so" ../workdir/magisk/magiskpolicy || true
|
||||
sudo patchelf --set-interpreter "../linker/linker64" ../workdir/magisk/magiskpolicy || true
|
||||
chmod +x ../workdir/magisk/magiskpolicy
|
||||
sudo ../workdir/magisk/magiskpolicy --load $MOUNT_DIR/vendor/etc/selinux/precompiled_sepolicy --save $MOUNT_DIR/vendor/etc/selinux/precompiled_sepolicy "allow gmscore_app gmscore_app vsock_socket { create connect write read }" "allow gmscore_app device_config_runtime_native_boot_prop file read" "allow gmscore_app system_server_tmpfs dir search" "allow gmscore_app system_server_tmpfs file open"
|
||||
|
||||
fi
|
||||
echo "Fix GApps prop"
|
||||
if [ $GAPPS_VARIANT != 'none' ] && [ $GAPPS_VARIANT != '' ]; then
|
||||
sudo python3 fixGappsProp.py $MOUNT_DIR
|
||||
fi
|
||||
|
||||
echo "Umount images"
|
||||
sudo find $MOUNT_DIR -exec touch -amt 200901010000.00 {} \; >/dev/null 2>&1
|
||||
sudo umount $MOUNT_DIR/vendor
|
||||
sudo umount $MOUNT_DIR/product
|
||||
sudo umount $MOUNT_DIR/system_ext
|
||||
sudo umount $MOUNT_DIR
|
||||
|
||||
echo "Shrink images"
|
||||
e2fsck -yf ../workdir/wsa/$ARCH/system.img
|
||||
resize2fs -M ../workdir/wsa/$ARCH/system.img
|
||||
e2fsck -yf ../workdir/wsa/$ARCH/vendor.img
|
||||
resize2fs -M ../workdir/wsa/$ARCH/vendor.img
|
||||
e2fsck -yf ../workdir/wsa/$ARCH/product.img
|
||||
resize2fs -M ../workdir/wsa/$ARCH/product.img
|
||||
e2fsck -yf ../workdir/wsa/$ARCH/system_ext.img
|
||||
resize2fs -M ../workdir/wsa/$ARCH/system_ext.img
|
||||
|
||||
echo "Remove signature and add scripts"
|
||||
rm -rf ../workdir/wsa/$ARCH/\[Content_Types\].xml ../workdir/wsa/$ARCH/AppxBlockMap.xml ../workdir/wsa/$ARCH/AppxSignature.p7x ../workdir/wsa/$ARCH/AppxMetadata
|
||||
cp ../download/vclibs.appx ../download/xaml.appx ../workdir/wsa/$ARCH
|
||||
tee ../workdir/wsa/$ARCH/Install.ps1 <<EOF
|
||||
# Automated Install script by Mioki
|
||||
# http://github.com/okibcn
|
||||
function Test-Administrator {
|
||||
[OutputType([bool])]
|
||||
param()
|
||||
process {
|
||||
[Security.Principal.WindowsPrincipal]\$user = [Security.Principal.WindowsIdentity]::GetCurrent();
|
||||
return \$user.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator);
|
||||
}
|
||||
}
|
||||
|
||||
function Finish {
|
||||
Clear-Host
|
||||
Start-Process "wsa://com.topjohnwu.magisk"
|
||||
Start-Process "wsa://com.android.vending"
|
||||
}
|
||||
|
||||
if (-not (Test-Administrator)) {
|
||||
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass -Force
|
||||
\$proc = Start-Process -PassThru -WindowStyle Hidden -Verb RunAs powershell.exe -Args "-executionpolicy bypass -command Set-Location '\$PSScriptRoot'; &'\$PSCommandPath' EVAL"
|
||||
\$proc.WaitForExit()
|
||||
if (\$proc.ExitCode -ne 0) {
|
||||
Clear-Host
|
||||
Write-Warning "Failed to launch start as Administrator\`r\`nPress any key to exit"
|
||||
\$null = \$Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
|
||||
}
|
||||
exit
|
||||
}
|
||||
elseif ((\$args.Count -eq 1) -and (\$args[0] -eq "EVAL")) {
|
||||
Start-Process powershell.exe -Args "-executionpolicy bypass -command Set-Location '\$PSScriptRoot'; &'\$PSCommandPath'"
|
||||
exit
|
||||
}
|
||||
|
||||
if (((Test-Path -Path $(ls -Q ../workdir/wsa/$ARCH | paste -sd "," -)) -eq \$false).Count) {
|
||||
Write-Error "Some files are missing in the zip. Please try to download it again from the browser downloader, or try to run the workflow again. Press any key to exist"
|
||||
\$null = \$Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
|
||||
exit 1
|
||||
}
|
||||
|
||||
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" /t REG_DWORD /f /v "AllowDevelopmentWithoutDevLicense" /d "1"
|
||||
|
||||
\$VMP = Get-WindowsOptionalFeature -Online -FeatureName 'VirtualMachinePlatform'
|
||||
if (\$VMP.State -ne "Enabled") {
|
||||
Enable-WindowsOptionalFeature -Online -NoRestart -FeatureName 'VirtualMachinePlatform'
|
||||
Clear-Host
|
||||
Write-Warning "Need restart to enable virtual machine platform\`r\`nPress y to restart or press any key to exit"
|
||||
\$key = \$Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
|
||||
If ("y" -eq \$key.Character) {
|
||||
Restart-Computer -Confirm
|
||||
}
|
||||
Else {
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
Add-AppxPackage -ForceApplicationShutdown -ForceUpdateFromAnyVersion -Path vclibs.appx
|
||||
Add-AppxPackage -ForceApplicationShutdown -ForceUpdateFromAnyVersion -Path xaml.appx
|
||||
|
||||
\$Installed = \$null
|
||||
\$Installed = Get-AppxPackage -Name 'MicrosoftCorporationII.WindowsSubsystemForAndroid'
|
||||
|
||||
If ((\$null -ne \$Installed) -and (-not (\$Installed.IsDevelopmentMode))) {
|
||||
Clear-Host
|
||||
Write-Warning "There is already one installed WSA. Please uninstall it first.\`r\`nPress y to uninstall existing WSA or press any key to exit"
|
||||
\$key = \$Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
|
||||
If ("y" -eq \$key.Character) {
|
||||
Remove-AppxPackage -Package \$Installed.PackageFullName
|
||||
}
|
||||
Else {
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
Clear-Host
|
||||
Write-Host "Installing MagiskOnWSA..."
|
||||
Stop-Process -Name "wsaclient" -ErrorAction "silentlycontinue"
|
||||
Add-AppxPackage -ForceApplicationShutdown -ForceUpdateFromAnyVersion -Register .\AppxManifest.xml
|
||||
if (\$?) {
|
||||
Finish
|
||||
}
|
||||
Elseif (\$null -ne \$Installed) {
|
||||
Clear-Host
|
||||
Write-Host "Failed to update, try to uninstall existing installation while preserving userdata..."
|
||||
Remove-AppxPackage -PreserveApplicationData -Package \$Installed.PackageFullName
|
||||
Add-AppxPackage -ForceApplicationShutdown -ForceUpdateFromAnyVersion -Register .\AppxManifest.xml
|
||||
if (\$?) {
|
||||
Finish
|
||||
}
|
||||
}
|
||||
Write-Host "All Done\`r\`nPress any key to exit"
|
||||
\$null = \$Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
|
||||
EOF
|
||||
|
||||
echo "Generate info"
|
||||
if [[ "$ROOT_SOL" = "none" ]]; then
|
||||
name1=""
|
||||
elif [[ "$ROOT_SOL" = "" ]]; then
|
||||
name1="-with-magisk"
|
||||
else
|
||||
name1="-with-$ROOT_SOL"
|
||||
fi
|
||||
if [[ "$GAPPS_VARIANT" = "none" || "$GAPPS_VARIANT" = "" ]]; then
|
||||
name2="-NoGApps"
|
||||
else
|
||||
if [[ "$GAPPS_VARIANT" != "pico" ]]; then
|
||||
echo ":warning: Since OpenGapps doesn't officially support Android 12.1 yet, lock the variant to pico!"
|
||||
fi
|
||||
name2="-GApps-${GAPPS_VARIANT}"
|
||||
fi
|
||||
echo "WSA${name1}${name2}_${ARCH}"
|
||||
cat ../workdir/ENV
|
||||
rm -rf ../output
|
||||
mv ../workdir/wsa/$ARCH ../output
|
||||
rm -rf ../workdir
|
BIN
wine/makepri.exe
BIN
wine/makepri.exe
Binary file not shown.
Loading…
Reference in New Issue
Block a user