mirror of
https://github.com/topjohnwu/Magisk
synced 2025-11-05 19:22:29 +01:00
Compare commits
349 Commits
canary-281
...
v30.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f16e93c7db | ||
|
|
1b0ddec66e | ||
|
|
cd8820f563 | ||
|
|
b70192ca3e | ||
|
|
d42ec5da9a | ||
|
|
742913ebcb | ||
|
|
ed206c6480 | ||
|
|
f9a8052583 | ||
|
|
f4fdd516f9 | ||
|
|
5925a71f94 | ||
|
|
3cda9beb93 | ||
|
|
8b7d1ffcdd | ||
|
|
8d02d0632e | ||
|
|
dd743f6f7e | ||
|
|
cf483ad4d2 | ||
|
|
4aed644e08 | ||
|
|
0acc39cec0 | ||
|
|
8b3a44344f | ||
|
|
8b49eda85a | ||
|
|
7057d4c7f1 | ||
|
|
aab8344058 | ||
|
|
7cccf83b37 | ||
|
|
f10ad93c4e | ||
|
|
f143b5df15 | ||
|
|
71213cc6f4 | ||
|
|
e2a1774e5b | ||
|
|
0222527a1e | ||
|
|
312bfe1bab | ||
|
|
48c62a1dae | ||
|
|
cfc2bcb665 | ||
|
|
94b1ff674f | ||
|
|
111136733a | ||
|
|
c8caaa98f5 | ||
|
|
8d28f10a3f | ||
|
|
177a456d8b | ||
|
|
ef4e230258 | ||
|
|
17082af438 | ||
|
|
1df5b34175 | ||
|
|
ea5fe7525d | ||
|
|
a75c335261 | ||
|
|
3903f42cf6 | ||
|
|
fb0c4ea838 | ||
|
|
bc89c60977 | ||
|
|
bd657c354c | ||
|
|
675b5f9565 | ||
|
|
1b2c43268e | ||
|
|
653730d75e | ||
|
|
d472e9c36e | ||
|
|
484d53ef7e | ||
|
|
c4e2985677 | ||
|
|
42d9f87bc9 | ||
|
|
2e4fa6864c | ||
|
|
e2abb648ac | ||
|
|
3599dcedfb | ||
|
|
ea72666df8 | ||
|
|
bd2a47ba18 | ||
|
|
b861671391 | ||
|
|
e91fc75d86 | ||
|
|
78f5cd55c7 | ||
|
|
9787a69528 | ||
|
|
87b8fe374d | ||
|
|
7b706bb0cb | ||
|
|
c1491b8d2b | ||
|
|
5cbaf2ae11 | ||
|
|
8ebc6207b4 | ||
|
|
7848ee616b | ||
|
|
fd193c3cae | ||
|
|
36d33c7a85 | ||
|
|
5caf28d27c | ||
|
|
2c39d0234d | ||
|
|
c313812129 | ||
|
|
af51880a81 | ||
|
|
db8d832707 | ||
|
|
8dc23d0ead | ||
|
|
b4287700d5 | ||
|
|
8d10ab89f2 | ||
|
|
49fdc1addb | ||
|
|
1333d3b986 | ||
|
|
335146a6a2 | ||
|
|
eaf9527971 | ||
|
|
da937a88c8 | ||
|
|
9476e7282d | ||
|
|
251c3c3e0e | ||
|
|
cd0eca20b0 | ||
|
|
6839cb9ab2 | ||
|
|
d11a3397d8 | ||
|
|
975120d6a6 | ||
|
|
e489b3b6dd | ||
|
|
589a270b8d | ||
|
|
7961be5cfa | ||
|
|
959430e030 | ||
|
|
2923c8ccd1 | ||
|
|
7df4a9d74f | ||
|
|
bf4ed295da | ||
|
|
a5fca960dc | ||
|
|
f99912b9db | ||
|
|
a54bdb54e4 | ||
|
|
cd9851a1fe | ||
|
|
9ca469898c | ||
|
|
0665549473 | ||
|
|
9d7a14b335 | ||
|
|
62e29fee74 | ||
|
|
e472db552b | ||
|
|
466e4bd4e1 | ||
|
|
4cf525c588 | ||
|
|
c8aec2510d | ||
|
|
ccbfe0e66e | ||
|
|
23ea28de6f | ||
|
|
55c3ee3a6f | ||
|
|
2a42ca2b8f | ||
|
|
a897e82fa4 | ||
|
|
ffa15831d3 | ||
|
|
a344ebf28c | ||
|
|
78f7fa348e | ||
|
|
d8c448b99d | ||
|
|
d4b83b6a44 | ||
|
|
e5d36d1d24 | ||
|
|
ff18cb8e70 | ||
|
|
37a9724a54 | ||
|
|
d660401063 | ||
|
|
88541d6f49 | ||
|
|
ecd6129fe5 | ||
|
|
6dfe9df9e2 | ||
|
|
e81de7ec36 | ||
|
|
c78da1ce24 | ||
|
|
7b2d40987c | ||
|
|
3a37e8c9c5 | ||
|
|
58b405bce1 | ||
|
|
810174ef73 | ||
|
|
690a5ac033 | ||
|
|
89aad31f7e | ||
|
|
7124db98e3 | ||
|
|
0860e859f7 | ||
|
|
04008949b8 | ||
|
|
39f2940bd1 | ||
|
|
1460317ebd | ||
|
|
12340c9bd5 | ||
|
|
c4590fe2ba | ||
|
|
b36066bbcd | ||
|
|
65d1c5827c | ||
|
|
1d675c8b2e | ||
|
|
0b494ed7df | ||
|
|
48d9fc24eb | ||
|
|
83426f7f36 | ||
|
|
0e86d4dbcb | ||
|
|
5e050d7456 | ||
|
|
898580bf90 | ||
|
|
86621a4c46 | ||
|
|
a834e72b71 | ||
|
|
d8cf42af16 | ||
|
|
8c79d66b7b | ||
|
|
fada8b148a | ||
|
|
dc0acea47c | ||
|
|
78d1200608 | ||
|
|
527bbc0368 | ||
|
|
4c89c7e2b3 | ||
|
|
adbea7e313 | ||
|
|
76962f965e | ||
|
|
a4b8c5e46b | ||
|
|
83c707439c | ||
|
|
25dd6121f4 | ||
|
|
67f35ad027 | ||
|
|
0c4b8afbc5 | ||
|
|
34b30d7ce1 | ||
|
|
2215088973 | ||
|
|
8b7fb6cdde | ||
|
|
94c7dbedf2 | ||
|
|
b1dc47a047 | ||
|
|
62b1310d97 | ||
|
|
0a86916d3a | ||
|
|
9907ce57aa | ||
|
|
b92626cacc | ||
|
|
5a762f0a8e | ||
|
|
5dd7a7d804 | ||
|
|
7831f40691 | ||
|
|
4f4b1ff885 | ||
|
|
97901979dd | ||
|
|
287316842c | ||
|
|
608786e8f3 | ||
|
|
9684a35cab | ||
|
|
e3e4202954 | ||
|
|
23c2054d46 | ||
|
|
a20a2a8fa0 | ||
|
|
a2896be4a6 | ||
|
|
e9220a28d9 | ||
|
|
cf12087e21 | ||
|
|
00c1b36837 | ||
|
|
03e034795d | ||
|
|
79c0fafe43 | ||
|
|
d499819ba0 | ||
|
|
86da917174 | ||
|
|
30bd7d6555 | ||
|
|
e5a12f0f5f | ||
|
|
c85a8434c6 | ||
|
|
427a1ca4e5 | ||
|
|
22884e173a | ||
|
|
d1829308e9 | ||
|
|
73840f8721 | ||
|
|
c7d1af9805 | ||
|
|
4ad26d3dfb | ||
|
|
0c70b7670c | ||
|
|
f44d044095 | ||
|
|
5c1cb13472 | ||
|
|
3327fc668e | ||
|
|
610945ac54 | ||
|
|
ddf5474917 | ||
|
|
6ba1685ade | ||
|
|
e02b5f7868 | ||
|
|
ab2e5d1e7e | ||
|
|
f3fef7bfe4 | ||
|
|
c34c7838bb | ||
|
|
c8a16b0e0c | ||
|
|
14f9ed91a1 | ||
|
|
7a207d4ccf | ||
|
|
92a42d901f | ||
|
|
084d89fcce | ||
|
|
55b036c071 | ||
|
|
30e79310ab | ||
|
|
f063fa5054 | ||
|
|
7bd901273c | ||
|
|
c1e061603b | ||
|
|
cb08504fe5 | ||
|
|
c0a1fb77be | ||
|
|
4864c1112a | ||
|
|
9ddeab034b | ||
|
|
c4847ed288 | ||
|
|
b8f1523fb2 | ||
|
|
fb7fa8a6b3 | ||
|
|
9c7d359093 | ||
|
|
eb54bc1fd7 | ||
|
|
d4a0286e13 | ||
|
|
83e66767ff | ||
|
|
7dc010749b | ||
|
|
8e8d013b1b | ||
|
|
bba0373808 | ||
|
|
1fa318dc8c | ||
|
|
6edc5e2037 | ||
|
|
1523ed9f78 | ||
|
|
8e604d2ab8 | ||
|
|
2aba7247a9 | ||
|
|
e66fe8533e | ||
|
|
b03fbb3917 | ||
|
|
c2ece62e4c | ||
|
|
8c972dcf34 | ||
|
|
50af14f2a3 | ||
|
|
e0a356b319 | ||
|
|
c09a792958 | ||
|
|
0bbfe7f44d | ||
|
|
a396abf565 | ||
|
|
1e3edb8883 | ||
|
|
3b8b61bf35 | ||
|
|
6f90456036 | ||
|
|
f56fd4e215 | ||
|
|
aa35aac5d5 | ||
|
|
1f162b819d | ||
|
|
52ef1d1cb2 | ||
|
|
f14e3a89cc | ||
|
|
95d3eac2e0 | ||
|
|
8e73536e02 | ||
|
|
12a0870bc9 | ||
|
|
6ff82c4e86 | ||
|
|
c64de35375 | ||
|
|
ee5283f4e8 | ||
|
|
bd0e954fea | ||
|
|
675471a49e | ||
|
|
c90e73ccec | ||
|
|
a43c1267d8 | ||
|
|
e8958c6b5c | ||
|
|
e8a3bf82c6 | ||
|
|
27fd79176a | ||
|
|
28d86a3454 | ||
|
|
c6c1a17ae6 | ||
|
|
2b47d47215 | ||
|
|
0e82df9e10 | ||
|
|
893821ad88 | ||
|
|
6b80fbfa99 | ||
|
|
8c3c7d0194 | ||
|
|
b94a3d9f2f | ||
|
|
442d0b5ddc | ||
|
|
494615d9a0 | ||
|
|
afbfb81837 | ||
|
|
3ed4e258a3 | ||
|
|
dddd41c95b | ||
|
|
5f2ca81e86 | ||
|
|
c9eac0c438 | ||
|
|
b6b34f7612 | ||
|
|
e55c413261 | ||
|
|
0399cde50a | ||
|
|
019eb03823 | ||
|
|
363410e1c0 | ||
|
|
fc2ef21660 | ||
|
|
18cb659ff3 | ||
|
|
63231d97ce | ||
|
|
9ac81a8a25 | ||
|
|
79af2787ae | ||
|
|
f5f9b285c0 | ||
|
|
6c05f2ae85 | ||
|
|
29043e1684 | ||
|
|
b73d4a7022 | ||
|
|
ad95e8951b | ||
|
|
bf591fca12 | ||
|
|
dcf027884d | ||
|
|
584f3820fe | ||
|
|
3c7c46307a | ||
|
|
4d80361805 | ||
|
|
9a74e19117 | ||
|
|
b1e17706a4 | ||
|
|
caad129d69 | ||
|
|
da58571ce5 | ||
|
|
2aa7f1c094 | ||
|
|
823e31a91b | ||
|
|
fb926ae302 | ||
|
|
e0489eeffd | ||
|
|
dc9d5a4cac | ||
|
|
143743d0b0 | ||
|
|
563f0d5ad5 | ||
|
|
c99f4a591b | ||
|
|
449204e380 | ||
|
|
a85c4c6528 | ||
|
|
d203a6fff6 | ||
|
|
6c612d66d7 | ||
|
|
540253a55b | ||
|
|
15b7c4ccd1 | ||
|
|
442d5335ea | ||
|
|
8a80eea597 | ||
|
|
5e35703091 | ||
|
|
b7ca73f431 | ||
|
|
a14fc90f07 | ||
|
|
c913f7ec74 | ||
|
|
7f6c9e8411 | ||
|
|
bb02ea3a20 | ||
|
|
3981c9665e | ||
|
|
88628fdf3c | ||
|
|
0469817781 | ||
|
|
a786801141 | ||
|
|
ab86732c89 | ||
|
|
59622d1688 | ||
|
|
58a25a3e2b | ||
|
|
15dca29a87 | ||
|
|
46980819c0 | ||
|
|
4fb6a7268c | ||
|
|
c05e963f37 | ||
|
|
7f7f625864 | ||
|
|
b25aa8295a | ||
|
|
15a605765c | ||
|
|
b575c95710 | ||
|
|
a48a9c858a | ||
|
|
0d8d6290a3 | ||
|
|
4dcd733ddd |
6
.gitattributes
vendored
6
.gitattributes
vendored
@@ -12,13 +12,11 @@
|
|||||||
|
|
||||||
# Denote all files that are truly binary and should not be modified.
|
# Denote all files that are truly binary and should not be modified.
|
||||||
tools/** binary
|
tools/** binary
|
||||||
|
tools/rustup-wrapper/** -binary
|
||||||
|
tools/elf-cleaner/** -binary
|
||||||
*.jar binary
|
*.jar binary
|
||||||
*.exe binary
|
*.exe binary
|
||||||
*.apk binary
|
*.apk binary
|
||||||
*.png binary
|
*.png binary
|
||||||
*.jpg binary
|
*.jpg binary
|
||||||
*.ttf binary
|
*.ttf binary
|
||||||
|
|
||||||
# Help GitHub detect languages
|
|
||||||
native/jni/external/** linguist-vendored
|
|
||||||
native/jni/systemproperties/** linguist-language=C++
|
|
||||||
|
|||||||
27
.github/actions/setup/action.yml
vendored
27
.github/actions/setup/action.yml
vendored
@@ -26,6 +26,15 @@ runs:
|
|||||||
|
|
||||||
- name: Cache sccache
|
- name: Cache sccache
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
|
with:
|
||||||
|
path: .sccache
|
||||||
|
key: sccache-${{ runner.os }}-${{ github.sha }}
|
||||||
|
restore-keys: sccache-${{ runner.os }}-
|
||||||
|
|
||||||
|
- name: Restore sccache
|
||||||
|
uses: actions/cache/restore@v4
|
||||||
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
with:
|
with:
|
||||||
path: .sccache
|
path: .sccache
|
||||||
key: sccache-${{ runner.os }}-${{ github.sha }}
|
key: sccache-${{ runner.os }}-${{ github.sha }}
|
||||||
@@ -36,7 +45,7 @@ runs:
|
|||||||
env:
|
env:
|
||||||
SCCACHE_DIRECT: false
|
SCCACHE_DIRECT: false
|
||||||
SCCACHE_DIR: ${{ github.workspace }}/.sccache
|
SCCACHE_DIR: ${{ github.workspace }}/.sccache
|
||||||
SCCACHE_CACHE_SIZE: 2G
|
SCCACHE_CACHE_SIZE: ${{ inputs.is-asset-build == 'true' && '2G' || '300M' }}
|
||||||
SCCACHE_IDLE_TIMEOUT: 0
|
SCCACHE_IDLE_TIMEOUT: 0
|
||||||
run: |
|
run: |
|
||||||
bash $GITHUB_ACTION_PATH/sccache.sh
|
bash $GITHUB_ACTION_PATH/sccache.sh
|
||||||
@@ -55,18 +64,18 @@ runs:
|
|||||||
|
|
||||||
- name: Cache Gradle dependencies
|
- name: Cache Gradle dependencies
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
if: inputs.is-asset-build == 'true'
|
if: ${{ inputs.is-asset-build == 'true' && github.event_name != 'pull_request' }}
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
.gradle/caches
|
.gradle/caches
|
||||||
.gradle/wrapper
|
.gradle/wrapper
|
||||||
!.gradle/caches/build-cache-*
|
!.gradle/caches/build-cache-*
|
||||||
key: gradle-cache-${{ hashFiles('gradle/**') }}
|
key: gradle-cache-${{ hashFiles('app/gradle/**') }}
|
||||||
restore-keys: gradle-cache-
|
restore-keys: gradle-cache-
|
||||||
|
|
||||||
- name: Restore Gradle dependencies
|
- name: Restore Gradle dependencies
|
||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
if: inputs.is-asset-build == 'false'
|
if: ${{ inputs.is-asset-build == 'false' || github.event_name == 'pull_request' }}
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
.gradle/caches
|
.gradle/caches
|
||||||
@@ -78,19 +87,17 @@ runs:
|
|||||||
|
|
||||||
- name: Cache Gradle build cache
|
- name: Cache Gradle build cache
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
if: inputs.is-asset-build == 'true'
|
if: ${{ inputs.is-asset-build == 'true' && github.event_name != 'pull_request' }}
|
||||||
with:
|
with:
|
||||||
path: |
|
path: .gradle/caches/build-cache-*
|
||||||
.gradle/caches/build-cache-*
|
|
||||||
key: gradle-build-cache-${{ github.sha }}
|
key: gradle-build-cache-${{ github.sha }}
|
||||||
restore-keys: gradle-build-cache-
|
restore-keys: gradle-build-cache-
|
||||||
|
|
||||||
- name: Restore Gradle build cache
|
- name: Restore Gradle build cache
|
||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
if: inputs.is-asset-build == 'false'
|
if: ${{ inputs.is-asset-build == 'false' || github.event_name == 'pull_request' }}
|
||||||
with:
|
with:
|
||||||
path: |
|
path: .gradle/caches/build-cache-*
|
||||||
.gradle/caches/build-cache-*
|
|
||||||
key: gradle-build-cache-${{ github.sha }}
|
key: gradle-build-cache-${{ github.sha }}
|
||||||
restore-keys: gradle-build-cache-
|
restore-keys: gradle-build-cache-
|
||||||
enableCrossOsArchive: true
|
enableCrossOsArchive: true
|
||||||
|
|||||||
36
.github/workflows/build.yml
vendored
36
.github/workflows/build.yml
vendored
@@ -1,6 +1,13 @@
|
|||||||
name: Magisk Build
|
name: Magisk Build
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
push:
|
||||||
|
branches: [master]
|
||||||
|
paths:
|
||||||
|
- "app/**"
|
||||||
|
- "native/**"
|
||||||
|
- "build.py"
|
||||||
|
- ".github/workflows/build.yml"
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [master]
|
branches: [master]
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
@@ -29,7 +36,7 @@ jobs:
|
|||||||
run: ./build.py -v all
|
run: ./build.py -v all
|
||||||
|
|
||||||
- name: Stop gradle daemon
|
- name: Stop gradle daemon
|
||||||
run: ./gradlew --stop
|
run: ./app/gradlew --stop
|
||||||
|
|
||||||
- name: Upload build artifact
|
- name: Upload build artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
@@ -65,21 +72,20 @@ jobs:
|
|||||||
run: python build.py -v -c .github/ci.prop all
|
run: python build.py -v -c .github/ci.prop all
|
||||||
|
|
||||||
- name: Stop gradle daemon
|
- name: Stop gradle daemon
|
||||||
run: ./gradlew --stop
|
run: ./app/gradlew --stop
|
||||||
|
|
||||||
avd-test:
|
avd-test:
|
||||||
name: Test API ${{ matrix.version }} (x86_64)
|
name: Test API ${{ matrix.version }} (x86_64)
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
needs: build
|
needs: build
|
||||||
|
if: ${{ github.event_name != 'push' }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
version: [23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35]
|
version: [23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, "CANARY"]
|
||||||
type: [""]
|
type: [""]
|
||||||
include:
|
include:
|
||||||
- version: "Baklava"
|
- version: "CANARY"
|
||||||
type: "google_apis"
|
|
||||||
- version: "Baklava"
|
|
||||||
type: "google_apis_ps16k"
|
type: "google_apis_ps16k"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
@@ -99,10 +105,10 @@ jobs:
|
|||||||
sudo udevadm trigger --name-match=kvm
|
sudo udevadm trigger --name-match=kvm
|
||||||
|
|
||||||
- name: Run AVD test
|
- name: Run AVD test
|
||||||
timeout-minutes: 10
|
timeout-minutes: 15
|
||||||
env:
|
env:
|
||||||
AVD_TEST_LOG: 1
|
AVD_TEST_LOG: 1
|
||||||
run: scripts/avd_test.sh ${{ matrix.version }} ${{ matrix.type }}
|
run: scripts/avd.sh test ${{ matrix.version }} ${{ matrix.type }}
|
||||||
|
|
||||||
- name: Upload logs on error
|
- name: Upload logs on error
|
||||||
if: ${{ failure() }}
|
if: ${{ failure() }}
|
||||||
@@ -117,6 +123,7 @@ jobs:
|
|||||||
name: Test API ${{ matrix.version }} (x86)
|
name: Test API ${{ matrix.version }} (x86)
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
needs: build
|
needs: build
|
||||||
|
if: ${{ github.event_name != 'push' }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
@@ -139,11 +146,11 @@ jobs:
|
|||||||
sudo udevadm trigger --name-match=kvm
|
sudo udevadm trigger --name-match=kvm
|
||||||
|
|
||||||
- name: Run AVD test
|
- name: Run AVD test
|
||||||
timeout-minutes: 10
|
timeout-minutes: 15
|
||||||
env:
|
env:
|
||||||
FORCE_32_BIT: 1
|
FORCE_32_BIT: 1
|
||||||
AVD_TEST_LOG: 1
|
AVD_TEST_LOG: 1
|
||||||
run: scripts/avd_test.sh ${{ matrix.version }}
|
run: scripts/avd.sh test ${{ matrix.version }}
|
||||||
|
|
||||||
- name: Upload logs on error
|
- name: Upload logs on error
|
||||||
if: ${{ failure() }}
|
if: ${{ failure() }}
|
||||||
@@ -158,14 +165,15 @@ jobs:
|
|||||||
name: Test ${{ matrix.device }}
|
name: Test ${{ matrix.device }}
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
needs: build
|
needs: build
|
||||||
|
if: ${{ github.event_name != 'push' }}
|
||||||
env:
|
env:
|
||||||
CF_HOME: /home/runner/aosp_cf_phone
|
CF_HOME: /home/runner/aosp_cf_phone
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- branch: "aosp-main"
|
- branch: "aosp-android-latest-release"
|
||||||
device: "aosp_cf_x86_64_phone"
|
device: "aosp_cf_x86_64_only_phone"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check out
|
- name: Check out
|
||||||
@@ -183,8 +191,8 @@ jobs:
|
|||||||
scripts/cuttlefish.sh download ${{ matrix.branch }} ${{ matrix.device }}
|
scripts/cuttlefish.sh download ${{ matrix.branch }} ${{ matrix.device }}
|
||||||
|
|
||||||
- name: Run Cuttlefish test
|
- name: Run Cuttlefish test
|
||||||
timeout-minutes: 10
|
timeout-minutes: 15
|
||||||
run: su $USER -c 'scripts/cuttlefish.sh test'
|
run: sudo -E -u $USER scripts/cuttlefish.sh test
|
||||||
|
|
||||||
- name: Upload logs on error
|
- name: Upload logs on error
|
||||||
if: ${{ failure() }}
|
if: ${{ failure() }}
|
||||||
|
|||||||
10
.gitignore
vendored
10
.gitignore
vendored
@@ -2,19 +2,13 @@ out
|
|||||||
*.zip
|
*.zip
|
||||||
*.jks
|
*.jks
|
||||||
*.apk
|
*.apk
|
||||||
|
*.log
|
||||||
/config.prop
|
/config.prop
|
||||||
/notes.md
|
/notes.md
|
||||||
/update.sh
|
|
||||||
/app/dict.txt
|
|
||||||
|
|
||||||
# Built binaries
|
# Built binaries
|
||||||
native/out
|
native/out
|
||||||
|
|
||||||
# Android Studio / Gradle
|
# Android Studio
|
||||||
*.iml
|
*.iml
|
||||||
.gradle
|
|
||||||
.idea
|
.idea
|
||||||
.kotlin
|
|
||||||
/local.properties
|
|
||||||
/build
|
|
||||||
/captures
|
|
||||||
|
|||||||
15
.gitmodules
vendored
15
.gitmodules
vendored
@@ -4,21 +4,9 @@
|
|||||||
[submodule "lz4"]
|
[submodule "lz4"]
|
||||||
path = native/src/external/lz4
|
path = native/src/external/lz4
|
||||||
url = https://github.com/lz4/lz4.git
|
url = https://github.com/lz4/lz4.git
|
||||||
[submodule "bzip2"]
|
|
||||||
path = native/src/external/bzip2
|
|
||||||
url = https://github.com/nemequ/bzip2.git
|
|
||||||
[submodule "xz"]
|
|
||||||
path = native/src/external/xz
|
|
||||||
url = https://github.com/xz-mirror/xz.git
|
|
||||||
[submodule "libcxx"]
|
[submodule "libcxx"]
|
||||||
path = native/src/external/libcxx
|
path = native/src/external/libcxx
|
||||||
url = https://github.com/topjohnwu/libcxx.git
|
url = https://github.com/topjohnwu/libcxx.git
|
||||||
[submodule "zlib"]
|
|
||||||
path = native/src/external/zlib
|
|
||||||
url = https://android.googlesource.com/platform/external/zlib
|
|
||||||
[submodule "zopfli"]
|
|
||||||
path = native/src/external/zopfli
|
|
||||||
url = https://github.com/google/zopfli.git
|
|
||||||
[submodule "cxx-rs"]
|
[submodule "cxx-rs"]
|
||||||
path = native/src/external/cxx-rs
|
path = native/src/external/cxx-rs
|
||||||
url = https://github.com/topjohnwu/cxx.git
|
url = https://github.com/topjohnwu/cxx.git
|
||||||
@@ -31,6 +19,3 @@
|
|||||||
[submodule "crt0"]
|
[submodule "crt0"]
|
||||||
path = native/src/external/crt0
|
path = native/src/external/crt0
|
||||||
url = https://github.com/topjohnwu/crt0.git
|
url = https://github.com/topjohnwu/crt0.git
|
||||||
[submodule "termux-elf-cleaner"]
|
|
||||||
path = tools/termux-elf-cleaner
|
|
||||||
url = https://github.com/termux/termux-elf-cleaner.git
|
|
||||||
|
|||||||
@@ -16,13 +16,7 @@ Some highlight features:
|
|||||||
|
|
||||||
## Downloads
|
## Downloads
|
||||||
|
|
||||||
[Github](https://github.com/topjohnwu/Magisk/) is the only source where you can get official Magisk information and downloads.
|
[Github](https://github.com/topjohnwu/Magisk/releases) is the only source where you can get official Magisk information and downloads.
|
||||||
|
|
||||||
Click the icon below to download Magisk apk.
|
|
||||||
|
|
||||||
[](https://github.com/topjohnwu/Magisk/releases/tag/v28.1)
|
|
||||||
[](https://github.com/topjohnwu/Magisk/releases/tag/v28.1)
|
|
||||||
[](https://github.com/topjohnwu/Magisk/releases/tag/canary-28102)
|
|
||||||
|
|
||||||
## Useful Links
|
## Useful Links
|
||||||
|
|
||||||
|
|||||||
7
app/.gitignore
vendored
Normal file
7
app/.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/dict.txt
|
||||||
|
|
||||||
|
# Gradle
|
||||||
|
.gradle
|
||||||
|
.kotlin
|
||||||
|
/local.properties
|
||||||
|
/build
|
||||||
@@ -35,7 +35,7 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(project(":app:core"))
|
implementation(project(":core"))
|
||||||
coreLibraryDesugaring(libs.jdk.libs)
|
coreLibraryDesugaring(libs.jdk.libs)
|
||||||
|
|
||||||
implementation(libs.indeterminate.checkbox)
|
implementation(libs.indeterminate.checkbox)
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
package com.topjohnwu.magisk.arch
|
package com.topjohnwu.magisk.arch
|
||||||
|
|
||||||
|
import android.content.ContentResolver
|
||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import androidx.databinding.ViewDataBinding
|
import androidx.databinding.ViewDataBinding
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import androidx.navigation.NavDirections
|
import androidx.navigation.NavDirections
|
||||||
import androidx.navigation.fragment.NavHostFragment
|
import androidx.navigation.fragment.NavHostFragment
|
||||||
|
import androidx.navigation.navOptions
|
||||||
|
import com.topjohnwu.magisk.utils.AccessibilityUtils
|
||||||
|
|
||||||
abstract class NavigationActivity<Binding : ViewDataBinding> : UIActivity<Binding>() {
|
abstract class NavigationActivity<Binding : ViewDataBinding> : UIActivity<Binding>() {
|
||||||
|
|
||||||
@@ -31,7 +34,17 @@ abstract class NavigationActivity<Binding : ViewDataBinding> : UIActivity<Bindin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun navigate(directions: NavDirections, navigation: NavController, cr: ContentResolver) {
|
||||||
|
if (AccessibilityUtils.isAnimationEnabled(cr)) {
|
||||||
|
navigation.navigate(directions)
|
||||||
|
} else {
|
||||||
|
navigation.navigate(directions, navOptions {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun NavDirections.navigate() {
|
fun NavDirections.navigate() {
|
||||||
navigation.navigate(this)
|
navigate(this, navigation, contentResolver)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import androidx.core.widget.ImageViewCompat
|
|||||||
import androidx.databinding.BindingAdapter
|
import androidx.databinding.BindingAdapter
|
||||||
import androidx.databinding.InverseBindingAdapter
|
import androidx.databinding.InverseBindingAdapter
|
||||||
import androidx.databinding.InverseBindingListener
|
import androidx.databinding.InverseBindingListener
|
||||||
|
import androidx.databinding.InverseMethod
|
||||||
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
|
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
|
||||||
import androidx.recyclerview.widget.DividerItemDecoration
|
import androidx.recyclerview.widget.DividerItemDecoration
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
@@ -33,9 +34,11 @@ import androidx.recyclerview.widget.StaggeredGridLayoutManager
|
|||||||
import com.google.android.material.button.MaterialButton
|
import com.google.android.material.button.MaterialButton
|
||||||
import com.google.android.material.card.MaterialCardView
|
import com.google.android.material.card.MaterialCardView
|
||||||
import com.google.android.material.chip.Chip
|
import com.google.android.material.chip.Chip
|
||||||
|
import com.google.android.material.slider.Slider
|
||||||
import com.google.android.material.textfield.TextInputLayout
|
import com.google.android.material.textfield.TextInputLayout
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.core.di.ServiceLocator
|
import com.topjohnwu.magisk.core.di.ServiceLocator
|
||||||
|
import com.topjohnwu.magisk.core.model.su.SuPolicy
|
||||||
import com.topjohnwu.magisk.utils.TextHolder
|
import com.topjohnwu.magisk.utils.TextHolder
|
||||||
import com.topjohnwu.superuser.internal.UiThreadHandler
|
import com.topjohnwu.superuser.internal.UiThreadHandler
|
||||||
import com.topjohnwu.widget.IndeterminateCheckBox
|
import com.topjohnwu.widget.IndeterminateCheckBox
|
||||||
@@ -306,3 +309,38 @@ fun TextView.setText(text: TextHolder) {
|
|||||||
fun Spinner.setAdapter(items: Array<Any>, layoutRes: Int) {
|
fun Spinner.setAdapter(items: Array<Any>, layoutRes: Int) {
|
||||||
adapter = ArrayAdapter(context, layoutRes, items)
|
adapter = ArrayAdapter(context, layoutRes, items)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@BindingAdapter("labelFormatter")
|
||||||
|
fun Slider.setLabelFormatter(formatter: (Float) -> Int) {
|
||||||
|
setLabelFormatter { value -> resources.getString(formatter(value)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@InverseBindingAdapter(attribute = "android:value")
|
||||||
|
fun Slider.getValueBinding() = value
|
||||||
|
|
||||||
|
@BindingAdapter("android:valueAttrChanged")
|
||||||
|
fun Slider.setListener(attrChange: InverseBindingListener) {
|
||||||
|
addOnSliderTouchListener(object : Slider.OnSliderTouchListener {
|
||||||
|
override fun onStartTrackingTouch(slider: Slider) = Unit
|
||||||
|
override fun onStopTrackingTouch(slider: Slider) = attrChange.onChange()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
@InverseMethod("sliderValueToPolicy")
|
||||||
|
fun policyToSliderValue(policy: Int): Float {
|
||||||
|
return when (policy) {
|
||||||
|
SuPolicy.DENY -> 1f
|
||||||
|
SuPolicy.RESTRICT -> 2f
|
||||||
|
SuPolicy.ALLOW -> 3f
|
||||||
|
else -> 1f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun sliderValueToPolicy(value: Float): Int {
|
||||||
|
return when (value) {
|
||||||
|
1f -> SuPolicy.DENY
|
||||||
|
2f -> SuPolicy.RESTRICT
|
||||||
|
3f -> SuPolicy.ALLOW
|
||||||
|
else -> SuPolicy.DENY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package com.topjohnwu.magisk.dialog
|
|||||||
import com.topjohnwu.magisk.core.AppContext
|
import com.topjohnwu.magisk.core.AppContext
|
||||||
import com.topjohnwu.magisk.core.Info
|
import com.topjohnwu.magisk.core.Info
|
||||||
import com.topjohnwu.magisk.core.R
|
import com.topjohnwu.magisk.core.R
|
||||||
import com.topjohnwu.magisk.core.di.ServiceLocator
|
|
||||||
import com.topjohnwu.magisk.core.download.DownloadEngine
|
import com.topjohnwu.magisk.core.download.DownloadEngine
|
||||||
import com.topjohnwu.magisk.core.download.Subject
|
import com.topjohnwu.magisk.core.download.Subject
|
||||||
import com.topjohnwu.magisk.view.MagiskDialog
|
import com.topjohnwu.magisk.view.MagiskDialog
|
||||||
@@ -11,15 +10,10 @@ import java.io.File
|
|||||||
|
|
||||||
class ManagerInstallDialog : MarkDownDialog() {
|
class ManagerInstallDialog : MarkDownDialog() {
|
||||||
|
|
||||||
private val svc get() = ServiceLocator.networkService
|
|
||||||
|
|
||||||
override suspend fun getMarkdownText(): String {
|
override suspend fun getMarkdownText(): String {
|
||||||
val text = svc.fetchString(Info.remote.magisk.note)
|
val text = Info.update.note
|
||||||
// Cache the changelog
|
// Cache the changelog
|
||||||
AppContext.cacheDir.listFiles { _, name -> name.endsWith(".md") }.orEmpty().forEach {
|
File(AppContext.cacheDir, "${Info.update.versionCode}.md").writeText(text)
|
||||||
it.delete()
|
|
||||||
}
|
|
||||||
File(AppContext.cacheDir, "${Info.remote.magisk.versionCode}.md").writeText(text)
|
|
||||||
return text
|
return text
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ import com.topjohnwu.magisk.core.Info
|
|||||||
import com.topjohnwu.magisk.core.download.DownloadEngine
|
import com.topjohnwu.magisk.core.download.DownloadEngine
|
||||||
import com.topjohnwu.magisk.databinding.FragmentHomeMd2Binding
|
import com.topjohnwu.magisk.databinding.FragmentHomeMd2Binding
|
||||||
import com.topjohnwu.magisk.core.R as CoreR
|
import com.topjohnwu.magisk.core.R as CoreR
|
||||||
|
import androidx.navigation.findNavController
|
||||||
|
import com.topjohnwu.magisk.arch.NavigationActivity
|
||||||
|
|
||||||
class HomeFragment : BaseFragment<FragmentHomeMd2Binding>(), MenuProvider {
|
class HomeFragment : BaseFragment<FragmentHomeMd2Binding>(), MenuProvider {
|
||||||
|
|
||||||
@@ -68,7 +70,13 @@ class HomeFragment : BaseFragment<FragmentHomeMd2Binding>(), MenuProvider {
|
|||||||
override fun onMenuItemSelected(item: MenuItem): Boolean {
|
override fun onMenuItemSelected(item: MenuItem): Boolean {
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.action_settings ->
|
R.id.action_settings ->
|
||||||
HomeFragmentDirections.actionHomeFragmentToSettingsFragment().navigate()
|
activity?.let {
|
||||||
|
NavigationActivity.navigate(
|
||||||
|
HomeFragmentDirections.actionHomeFragmentToSettingsFragment(),
|
||||||
|
it.findNavController(R.id.main_nav_host),
|
||||||
|
it.contentResolver,
|
||||||
|
)
|
||||||
|
}
|
||||||
R.id.action_reboot -> activity?.let { RebootMenu.inflate(it).show() }
|
R.id.action_reboot -> activity?.let { RebootMenu.inflate(it).show() }
|
||||||
else -> return super.onOptionsItemSelected(item)
|
else -> return super.onOptionsItemSelected(item)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,16 +91,15 @@ class HomeViewModel(
|
|||||||
|
|
||||||
override suspend fun doLoadWork() {
|
override suspend fun doLoadWork() {
|
||||||
appState = State.LOADING
|
appState = State.LOADING
|
||||||
Info.getRemote(svc)?.apply {
|
Info.fetchUpdate(svc)?.apply {
|
||||||
appState = when {
|
appState = when {
|
||||||
BuildConfig.APP_VERSION_CODE < magisk.versionCode -> State.OUTDATED
|
BuildConfig.APP_VERSION_CODE < versionCode -> State.OUTDATED
|
||||||
else -> State.UP_TO_DATE
|
else -> State.UP_TO_DATE
|
||||||
}
|
}
|
||||||
|
|
||||||
val isDebug = Config.updateChannel == Config.Value.DEBUG_CHANNEL
|
val isDebug = Config.updateChannel == Config.Value.DEBUG_CHANNEL
|
||||||
managerRemoteVersion =
|
managerRemoteVersion =
|
||||||
("${magisk.version} (${magisk.versionCode})" +
|
("$version (${versionCode})" + if (isDebug) " (D)" else "").asText()
|
||||||
if (isDebug) " (D)" else "").asText()
|
|
||||||
} ?: run {
|
} ?: run {
|
||||||
appState = State.INVALID
|
appState = State.INVALID
|
||||||
managerRemoteVersion = CoreR.string.not_available.asText()
|
managerRemoteVersion = CoreR.string.not_available.asText()
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ object RebootMenu {
|
|||||||
activity.getSystemService<PowerManager>()?.isRebootingUserspaceSupported == true) {
|
activity.getSystemService<PowerManager>()?.isRebootingUserspaceSupported == true) {
|
||||||
menu.menu.findItem(R.id.action_reboot_userspace).isVisible = true
|
menu.menu.findItem(R.id.action_reboot_userspace).isVisible = true
|
||||||
}
|
}
|
||||||
if (Const.Version.isCanary()) {
|
if (Const.Version.atLeast_28_0()) {
|
||||||
menu.menu.findItem(R.id.action_reboot_safe_mode).isChecked = Config.bootloop >= 2
|
menu.menu.findItem(R.id.action_reboot_safe_mode).isChecked = Config.bootloop >= 2
|
||||||
} else {
|
} else {
|
||||||
menu.menu.findItem(R.id.action_reboot_safe_mode).isVisible = false
|
menu.menu.findItem(R.id.action_reboot_safe_mode).isVisible = false
|
||||||
|
|||||||
@@ -14,9 +14,8 @@ import com.topjohnwu.magisk.BR
|
|||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.arch.BaseViewModel
|
import com.topjohnwu.magisk.arch.BaseViewModel
|
||||||
import com.topjohnwu.magisk.core.AppContext
|
import com.topjohnwu.magisk.core.AppContext
|
||||||
import com.topjohnwu.magisk.core.BuildConfig
|
import com.topjohnwu.magisk.core.BuildConfig.APP_VERSION_CODE
|
||||||
import com.topjohnwu.magisk.core.Config
|
import com.topjohnwu.magisk.core.Config
|
||||||
import com.topjohnwu.magisk.core.Const
|
|
||||||
import com.topjohnwu.magisk.core.Info
|
import com.topjohnwu.magisk.core.Info
|
||||||
import com.topjohnwu.magisk.core.base.ContentResultCallback
|
import com.topjohnwu.magisk.core.base.ContentResultCallback
|
||||||
import com.topjohnwu.magisk.core.ktx.toast
|
import com.topjohnwu.magisk.core.ktx.toast
|
||||||
@@ -70,17 +69,16 @@ class InstallViewModel(svc: NetworkService, markwon: Markwon) : BaseViewModel()
|
|||||||
init {
|
init {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
val file = File(AppContext.cacheDir, "${BuildConfig.APP_VERSION_CODE}.md")
|
val noteFile = File(AppContext.cacheDir, "${APP_VERSION_CODE}.md")
|
||||||
val text = when {
|
val noteText = when {
|
||||||
file.exists() -> file.readText()
|
noteFile.exists() -> noteFile.readText()
|
||||||
Const.Url.CHANGELOG_URL.isEmpty() -> ""
|
|
||||||
else -> {
|
else -> {
|
||||||
val str = svc.fetchString(Const.Url.CHANGELOG_URL)
|
val note = svc.fetchUpdate(APP_VERSION_CODE).note
|
||||||
file.writeText(str)
|
noteFile.writeText(note)
|
||||||
str
|
note
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val spanned = markwon.toMarkdown(text)
|
val spanned = markwon.toMarkdown(noteText)
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
notes = spanned
|
notes = spanned
|
||||||
}
|
}
|
||||||
@@ -100,13 +98,15 @@ class InstallViewModel(svc: NetworkService, markwon: Markwon) : BaseViewModel()
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onSaveState(state: Bundle) {
|
override fun onSaveState(state: Bundle) {
|
||||||
state.putParcelable(INSTALL_STATE_KEY, InstallState(
|
state.putParcelable(
|
||||||
|
INSTALL_STATE_KEY, InstallState(
|
||||||
methodId,
|
methodId,
|
||||||
step,
|
step,
|
||||||
Config.keepVerity,
|
Config.keepVerity,
|
||||||
Config.keepEnc,
|
Config.keepEnc,
|
||||||
Config.recovery
|
Config.recovery
|
||||||
))
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onRestoreState(state: Bundle) {
|
override fun onRestoreState(state: Bundle) {
|
||||||
@@ -124,6 +124,7 @@ class InstallViewModel(svc: NetworkService, markwon: Markwon) : BaseViewModel()
|
|||||||
override fun onActivityLaunch() {
|
override fun onActivityLaunch() {
|
||||||
AppContext.toast(CoreR.string.patch_file_msg, Toast.LENGTH_LONG)
|
AppContext.toast(CoreR.string.patch_file_msg, Toast.LENGTH_LONG)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onActivityResult(result: Uri) {
|
override fun onActivityResult(result: Uri) {
|
||||||
uri.value = result
|
uri.value = result
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import android.view.Menu
|
|||||||
import android.view.MenuInflater
|
import android.view.MenuInflater
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.widget.HorizontalScrollView
|
||||||
import androidx.core.view.MenuProvider
|
import androidx.core.view.MenuProvider
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
@@ -12,6 +13,7 @@ import com.topjohnwu.magisk.arch.BaseFragment
|
|||||||
import com.topjohnwu.magisk.arch.viewModel
|
import com.topjohnwu.magisk.arch.viewModel
|
||||||
import com.topjohnwu.magisk.databinding.FragmentLogMd2Binding
|
import com.topjohnwu.magisk.databinding.FragmentLogMd2Binding
|
||||||
import com.topjohnwu.magisk.ui.MainActivity
|
import com.topjohnwu.magisk.ui.MainActivity
|
||||||
|
import com.topjohnwu.magisk.utils.AccessibilityUtils
|
||||||
import com.topjohnwu.magisk.utils.MotionRevealHelper
|
import com.topjohnwu.magisk.utils.MotionRevealHelper
|
||||||
import rikka.recyclerview.addEdgeSpacing
|
import rikka.recyclerview.addEdgeSpacing
|
||||||
import rikka.recyclerview.addItemSpacing
|
import rikka.recyclerview.addItemSpacing
|
||||||
@@ -56,6 +58,11 @@ class LogFragment : BaseFragment<FragmentLogMd2Binding>(), MenuProvider {
|
|||||||
addItemSpacing(R.dimen.l1, R.dimen.l_50, R.dimen.l1)
|
addItemSpacing(R.dimen.l1, R.dimen.l_50, R.dimen.l1)
|
||||||
fixEdgeEffect()
|
fixEdgeEffect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!AccessibilityUtils.isAnimationEnabled(requireContext().contentResolver)) {
|
||||||
|
val scrollView = view.findViewById<HorizontalScrollView>(R.id.log_scroll_magisk)
|
||||||
|
scrollView.setOverScrollMode(View.OVER_SCROLL_NEVER)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -147,19 +147,11 @@ object UpdateChannel : BaseSettingsItem.Selector() {
|
|||||||
get() = Config.updateChannel
|
get() = Config.updateChannel
|
||||||
set(value) {
|
set(value) {
|
||||||
Config.updateChannel = value
|
Config.updateChannel = value
|
||||||
Info.remote = Info.EMPTY_REMOTE
|
Info.resetUpdate()
|
||||||
}
|
}
|
||||||
|
|
||||||
override val title = CoreR.string.settings_update_channel_title.asText()
|
override val title = CoreR.string.settings_update_channel_title.asText()
|
||||||
|
|
||||||
override val entryRes = CoreR.array.update_channel
|
override val entryRes = CoreR.array.update_channel
|
||||||
override fun entries(res: Resources): Array<String> {
|
|
||||||
return super.entries(res).let {
|
|
||||||
if (!Const.APP_IS_CANARY && !BuildConfig.DEBUG)
|
|
||||||
it.copyOfRange(0, Config.Value.CANARY_CHANNEL)
|
|
||||||
else it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object UpdateChannelUrl : BaseSettingsItem.Input() {
|
object UpdateChannelUrl : BaseSettingsItem.Input() {
|
||||||
@@ -169,7 +161,7 @@ object UpdateChannelUrl : BaseSettingsItem.Input() {
|
|||||||
get() = Config.customChannelUrl
|
get() = Config.customChannelUrl
|
||||||
set(value) {
|
set(value) {
|
||||||
Config.customChannelUrl = value
|
Config.customChannelUrl = value
|
||||||
Info.remote = Info.EMPTY_REMOTE
|
Info.resetUpdate()
|
||||||
notifyPropertyChanged(BR.description)
|
notifyPropertyChanged(BR.description)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,6 +322,12 @@ object Reauthenticate : BaseSettingsItem.Toggle() {
|
|||||||
override var value by Config::suReAuth
|
override var value by Config::suReAuth
|
||||||
|
|
||||||
override fun refresh() {
|
override fun refresh() {
|
||||||
isEnabled = Build.VERSION.SDK_INT < Build.VERSION_CODES.O && Info.showSuperUser
|
isEnabled = Build.VERSION.SDK_INT < Build.VERSION_CODES.O
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object Restrict : BaseSettingsItem.Toggle() {
|
||||||
|
override val title = CoreR.string.settings_su_restrict_title.asText()
|
||||||
|
override val description = CoreR.string.settings_su_restrict_summary.asText()
|
||||||
|
override var value by Config::suRestrict
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,11 +22,11 @@ import com.topjohnwu.magisk.core.ktx.activity
|
|||||||
import com.topjohnwu.magisk.core.ktx.toast
|
import com.topjohnwu.magisk.core.ktx.toast
|
||||||
import com.topjohnwu.magisk.core.tasks.AppMigration
|
import com.topjohnwu.magisk.core.tasks.AppMigration
|
||||||
import com.topjohnwu.magisk.core.utils.LocaleSetting
|
import com.topjohnwu.magisk.core.utils.LocaleSetting
|
||||||
|
import com.topjohnwu.magisk.core.utils.RootUtils
|
||||||
import com.topjohnwu.magisk.databinding.bindExtra
|
import com.topjohnwu.magisk.databinding.bindExtra
|
||||||
import com.topjohnwu.magisk.events.AddHomeIconEvent
|
import com.topjohnwu.magisk.events.AddHomeIconEvent
|
||||||
import com.topjohnwu.magisk.events.AuthEvent
|
import com.topjohnwu.magisk.events.AuthEvent
|
||||||
import com.topjohnwu.magisk.events.SnackbarEvent
|
import com.topjohnwu.magisk.events.SnackbarEvent
|
||||||
import com.topjohnwu.superuser.Shell
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler {
|
class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler {
|
||||||
@@ -83,6 +83,9 @@ class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler {
|
|||||||
// Can hide overlay windows on 12.0+
|
// Can hide overlay windows on 12.0+
|
||||||
list.remove(Tapjack)
|
list.remove(Tapjack)
|
||||||
}
|
}
|
||||||
|
if (Const.Version.atLeast_30_1()) {
|
||||||
|
list.add(Restrict)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return list
|
return list
|
||||||
@@ -127,7 +130,8 @@ class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createHosts() {
|
private fun createHosts() {
|
||||||
Shell.cmd("add_hosts_module").submit {
|
viewModelScope.launch {
|
||||||
|
RootUtils.addSystemlessHosts()
|
||||||
AppContext.toast(R.string.settings_hosts_toast, Toast.LENGTH_SHORT)
|
AppContext.toast(R.string.settings_hosts_toast, Toast.LENGTH_SHORT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,13 @@ import android.graphics.drawable.Drawable
|
|||||||
import androidx.databinding.Bindable
|
import androidx.databinding.Bindable
|
||||||
import com.topjohnwu.magisk.BR
|
import com.topjohnwu.magisk.BR
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
|
import com.topjohnwu.magisk.core.Config
|
||||||
import com.topjohnwu.magisk.core.model.su.SuPolicy
|
import com.topjohnwu.magisk.core.model.su.SuPolicy
|
||||||
import com.topjohnwu.magisk.databinding.DiffItem
|
import com.topjohnwu.magisk.databinding.DiffItem
|
||||||
import com.topjohnwu.magisk.databinding.ItemWrapper
|
import com.topjohnwu.magisk.databinding.ItemWrapper
|
||||||
import com.topjohnwu.magisk.databinding.ObservableRvItem
|
import com.topjohnwu.magisk.databinding.ObservableRvItem
|
||||||
import com.topjohnwu.magisk.databinding.set
|
import com.topjohnwu.magisk.databinding.set
|
||||||
|
import com.topjohnwu.magisk.core.R as CoreR
|
||||||
|
|
||||||
class PolicyRvItem(
|
class PolicyRvItem(
|
||||||
private val viewModel: SuperuserViewModel,
|
private val viewModel: SuperuserViewModel,
|
||||||
@@ -33,12 +35,32 @@ class PolicyRvItem(
|
|||||||
var isExpanded = false
|
var isExpanded = false
|
||||||
set(value) = set(value, field, { field = it }, BR.expanded)
|
set(value) = set(value, field, { field = it }, BR.expanded)
|
||||||
|
|
||||||
|
val showSlider = Config.suRestrict || item.policy == SuPolicy.RESTRICT
|
||||||
|
|
||||||
@get:Bindable
|
@get:Bindable
|
||||||
var isEnabled
|
var isEnabled
|
||||||
get() = item.policy == SuPolicy.ALLOW
|
get() = item.policy >= SuPolicy.ALLOW
|
||||||
set(value) = setImpl(value, isEnabled) {
|
set(value) = setImpl(value, isEnabled) {
|
||||||
notifyPropertyChanged(BR.enabled)
|
notifyPropertyChanged(BR.enabled)
|
||||||
viewModel.togglePolicy(this, value)
|
viewModel.updatePolicy(this, if (it) SuPolicy.ALLOW else SuPolicy.DENY)
|
||||||
|
}
|
||||||
|
|
||||||
|
@get:Bindable
|
||||||
|
var sliderValue
|
||||||
|
get() = item.policy
|
||||||
|
set(value) = setImpl(value, sliderValue) {
|
||||||
|
notifyPropertyChanged(BR.sliderValue)
|
||||||
|
notifyPropertyChanged(BR.enabled)
|
||||||
|
viewModel.updatePolicy(this, it)
|
||||||
|
}
|
||||||
|
|
||||||
|
val sliderValueToPolicyString: (Float) -> Int = { value ->
|
||||||
|
when (value.toInt()) {
|
||||||
|
1 -> CoreR.string.deny
|
||||||
|
2 -> CoreR.string.restrict
|
||||||
|
3 -> CoreR.string.grant
|
||||||
|
else -> CoreR.string.deny
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@get:Bindable
|
@get:Bindable
|
||||||
|
|||||||
@@ -156,15 +156,16 @@ class SuperuserViewModel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun togglePolicy(item: PolicyRvItem, enable: Boolean) {
|
fun updatePolicy(item: PolicyRvItem, policy: Int) {
|
||||||
val items = itemsPolicies.filter { it.item.uid == item.item.uid }
|
val items = itemsPolicies.filter { it.item.uid == item.item.uid }
|
||||||
fun updateState() {
|
fun updateState() {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
val res = if (enable) R.string.su_snack_grant else R.string.su_snack_deny
|
val res = if (policy >= SuPolicy.ALLOW) R.string.su_snack_grant else R.string.su_snack_deny
|
||||||
item.item.policy = if (enable) SuPolicy.ALLOW else SuPolicy.DENY
|
item.item.policy = policy
|
||||||
db.update(item.item)
|
db.update(item.item)
|
||||||
items.forEach {
|
items.forEach {
|
||||||
it.notifyPropertyChanged(BR.enabled)
|
it.notifyPropertyChanged(BR.enabled)
|
||||||
|
it.notifyPropertyChanged(BR.sliderValue)
|
||||||
}
|
}
|
||||||
SnackbarEvent(res.asText(item.appName)).publish()
|
SnackbarEvent(res.asText(item.appName)).publish()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,10 +43,6 @@ enum class Theme(
|
|||||||
|
|
||||||
val isSelected get() = Config.themeOrdinal == ordinal
|
val isSelected get() = Config.themeOrdinal == ordinal
|
||||||
|
|
||||||
fun select() {
|
|
||||||
Config.themeOrdinal = ordinal
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val selected get() = values().getOrNull(Config.themeOrdinal) ?: Piplup
|
val selected get() = values().getOrNull(Config.themeOrdinal) ?: Piplup
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.topjohnwu.magisk.utils
|
||||||
|
|
||||||
|
import android.content.ContentResolver
|
||||||
|
import android.provider.Settings
|
||||||
|
|
||||||
|
class AccessibilityUtils {
|
||||||
|
companion object {
|
||||||
|
fun isAnimationEnabled(cr: ContentResolver): Boolean {
|
||||||
|
return !(Settings.Global.getFloat(cr, Settings.Global.ANIMATOR_DURATION_SCALE, 1.0f) == 0.0f
|
||||||
|
&& Settings.Global.getFloat(cr, Settings.Global.TRANSITION_ANIMATION_SCALE, 1.0f) == 0.0f
|
||||||
|
&& Settings.Global.getFloat(cr, Settings.Global.WINDOW_ANIMATION_SCALE, 1.0f) == 0.0f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<HorizontalScrollView
|
<HorizontalScrollView
|
||||||
|
android:id="@+id/log_scroll_magisk"
|
||||||
gone="@{viewModel.loading}"
|
gone="@{viewModel.loading}"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
<include
|
<include
|
||||||
android:id="@+id/log_track_container"
|
android:id="@+id/log_track_container"
|
||||||
bullet="@{item.log.action == 2 ? R.drawable.ic_check_md2 : R.drawable.ic_close_md2}"
|
bullet="@{item.log.action >= 2 ? R.drawable.ic_check_md2 : R.drawable.ic_close_md2}"
|
||||||
isBottom="@{item.isBottom}"
|
isBottom="@{item.isBottom}"
|
||||||
isSelected="@{item.log.action != 2}"
|
isSelected="@{item.log.action != 2}"
|
||||||
isTop="@{item.isTop}"
|
isTop="@{item.isTop}"
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
<data>
|
<data>
|
||||||
|
|
||||||
|
<import type="com.topjohnwu.magisk.databinding.DataBindingAdaptersKt" />
|
||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="item"
|
name="item"
|
||||||
type="com.topjohnwu.magisk.ui.superuser.PolicyRvItem" />
|
type="com.topjohnwu.magisk.ui.superuser.PolicyRvItem" />
|
||||||
@@ -85,16 +87,32 @@
|
|||||||
app:layout_constraintVertical_bias="0"
|
app:layout_constraintVertical_bias="0"
|
||||||
tools:text="com.topjohnwu.magisk" />
|
tools:text="com.topjohnwu.magisk" />
|
||||||
|
|
||||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
<FrameLayout
|
||||||
android:id="@+id/policy_indicator"
|
android:id="@+id/policy_indicator"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="@dimen/l1"
|
android:layout_marginEnd="@dimen/l1"
|
||||||
android:checked="@={item.enabled}"
|
|
||||||
android:nextFocusLeft="@id/policy"
|
android:nextFocusLeft="@id/policy"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||||
|
gone="@{item.showSlider}"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:checked="@={item.enabled}" />
|
||||||
|
|
||||||
|
<com.google.android.material.slider.Slider
|
||||||
|
goneUnless="@{item.showSlider}"
|
||||||
|
labelFormatter="@{item.sliderValueToPolicyString}"
|
||||||
|
android:layout_width="96dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:stepSize="1"
|
||||||
|
android:value="@={DataBindingAdaptersKt.policyToSliderValue(item.sliderValue)}"
|
||||||
|
android:valueFrom="1"
|
||||||
|
android:valueTo="3" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
tasks.register("clean") {
|
plugins {
|
||||||
|
id("MagiskPlugin")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.register("clean", Delete::class) {
|
||||||
|
delete(rootProject.layout.buildDirectory)
|
||||||
|
|
||||||
subprojects.forEach {
|
subprojects.forEach {
|
||||||
dependsOn(":app:${it.name}:clean")
|
dependsOn(":${it.name}:clean")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,17 +18,12 @@ gradlePlugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
|
||||||
compilerOptions {
|
|
||||||
languageVersion = KotlinVersion.KOTLIN_2_0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(kotlin("gradle-plugin", libs.versions.kotlin.get()))
|
implementation(kotlin("gradle-plugin", libs.versions.kotlin.get()))
|
||||||
implementation(libs.android.gradle.plugin)
|
implementation(libs.android.gradle.plugin)
|
||||||
implementation(libs.ksp.plugin)
|
implementation(libs.ksp.plugin)
|
||||||
implementation(libs.navigation.safe.args.plugin)
|
implementation(libs.navigation.safe.args.plugin)
|
||||||
implementation(libs.lsparanoid.plugin)
|
implementation(libs.lsparanoid.plugin)
|
||||||
|
implementation(libs.moshi.plugin)
|
||||||
implementation(libs.jgit)
|
implementation(libs.jgit)
|
||||||
}
|
}
|
||||||
77
app/buildSrc/src/main/java/AddCommentTask.kt
Normal file
77
app/buildSrc/src/main/java/AddCommentTask.kt
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
import com.android.build.api.artifact.ArtifactTransformationRequest
|
||||||
|
import com.android.build.api.dsl.ApkSigningConfig
|
||||||
|
import com.android.builder.internal.packaging.IncrementalPackager
|
||||||
|
import com.android.tools.build.apkzlib.sign.SigningExtension
|
||||||
|
import com.android.tools.build.apkzlib.sign.SigningOptions
|
||||||
|
import com.android.tools.build.apkzlib.zfile.ZFiles
|
||||||
|
import com.android.tools.build.apkzlib.zip.ZFileOptions
|
||||||
|
import org.gradle.api.DefaultTask
|
||||||
|
import org.gradle.api.file.DirectoryProperty
|
||||||
|
import org.gradle.api.provider.Property
|
||||||
|
import org.gradle.api.tasks.Input
|
||||||
|
import org.gradle.api.tasks.InputFiles
|
||||||
|
import org.gradle.api.tasks.Internal
|
||||||
|
import org.gradle.api.tasks.OutputDirectory
|
||||||
|
import org.gradle.api.tasks.TaskAction
|
||||||
|
import java.io.File
|
||||||
|
import java.security.KeyStore
|
||||||
|
import java.security.cert.X509Certificate
|
||||||
|
import java.util.jar.JarFile
|
||||||
|
|
||||||
|
abstract class AddCommentTask: DefaultTask() {
|
||||||
|
@get:Input
|
||||||
|
abstract val comment: Property<String>
|
||||||
|
|
||||||
|
@get:Input
|
||||||
|
abstract val signingConfig: Property<ApkSigningConfig>
|
||||||
|
|
||||||
|
@get:InputFiles
|
||||||
|
abstract val apkFolder: DirectoryProperty
|
||||||
|
|
||||||
|
@get:OutputDirectory
|
||||||
|
abstract val outFolder: DirectoryProperty
|
||||||
|
|
||||||
|
@get:Internal
|
||||||
|
abstract val transformationRequest: Property<ArtifactTransformationRequest<AddCommentTask>>
|
||||||
|
|
||||||
|
@TaskAction
|
||||||
|
fun taskAction() = transformationRequest.get().submit(this) { artifact ->
|
||||||
|
val inFile = File(artifact.outputFile)
|
||||||
|
val outFile = outFolder.file(inFile.name).get().asFile
|
||||||
|
|
||||||
|
val privateKey = signingConfig.get().getPrivateKey()
|
||||||
|
val signingOptions = SigningOptions.builder()
|
||||||
|
.setMinSdkVersion(0)
|
||||||
|
.setV1SigningEnabled(true)
|
||||||
|
.setV2SigningEnabled(true)
|
||||||
|
.setKey(privateKey.privateKey)
|
||||||
|
.setCertificates(privateKey.certificate as X509Certificate)
|
||||||
|
.setValidation(SigningOptions.Validation.ASSUME_INVALID)
|
||||||
|
.build()
|
||||||
|
val options = ZFileOptions().apply {
|
||||||
|
noTimestamps = true
|
||||||
|
autoSortFiles = true
|
||||||
|
}
|
||||||
|
outFile.parentFile?.mkdirs()
|
||||||
|
inFile.copyTo(outFile, overwrite = true)
|
||||||
|
ZFiles.apk(outFile, options).use {
|
||||||
|
SigningExtension(signingOptions).register(it)
|
||||||
|
it.eocdComment = comment.get().toByteArray()
|
||||||
|
it.get(IncrementalPackager.APP_METADATA_ENTRY_PATH)?.delete()
|
||||||
|
it.get(IncrementalPackager.VERSION_CONTROL_INFO_ENTRY_PATH)?.delete()
|
||||||
|
it.get(JarFile.MANIFEST_NAME)?.delete()
|
||||||
|
}
|
||||||
|
|
||||||
|
outFile
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ApkSigningConfig.getPrivateKey(): KeyStore.PrivateKeyEntry {
|
||||||
|
val keyStore = KeyStore.getInstance(storeType ?: KeyStore.getDefaultType())
|
||||||
|
storeFile!!.inputStream().use {
|
||||||
|
keyStore.load(it, storePassword!!.toCharArray())
|
||||||
|
}
|
||||||
|
val keyPwdArray = keyPassword!!.toCharArray()
|
||||||
|
val entry = keyStore.getEntry(keyAlias!!, KeyStore.PasswordProtection(keyPwdArray))
|
||||||
|
return entry as KeyStore.PrivateKeyEntry
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,12 @@ import org.gradle.api.Project
|
|||||||
import org.gradle.kotlin.dsl.provideDelegate
|
import org.gradle.kotlin.dsl.provideDelegate
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.Properties
|
import java.util.Properties
|
||||||
|
import java.util.Random
|
||||||
|
|
||||||
|
// Set non-zero value here to fix the random seed for reproducible builds
|
||||||
|
// CI builds are always reproducible
|
||||||
|
val RAND_SEED = if (System.getenv("CI") != null) 42 else 0
|
||||||
|
lateinit var RANDOM: Random
|
||||||
|
|
||||||
private val props = Properties()
|
private val props = Properties()
|
||||||
private var commitHash = ""
|
private var commitHash = ""
|
||||||
@@ -14,7 +20,7 @@ private val defaultAbis = setOf("armeabi-v7a", "x86", "arm64-v8a", "x86_64")
|
|||||||
object Config {
|
object Config {
|
||||||
operator fun get(key: String): String? {
|
operator fun get(key: String): String? {
|
||||||
val v = props[key] as? String ?: return null
|
val v = props[key] as? String ?: return null
|
||||||
return if (v.isBlank()) null else v
|
return v.ifBlank { null }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun contains(key: String) = get(key) != null
|
fun contains(key: String) = get(key) != null
|
||||||
@@ -28,19 +34,25 @@ object Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Project.rootFile(path: String): File {
|
||||||
|
val file = File(path)
|
||||||
|
return if (file.isAbsolute) file
|
||||||
|
else File(rootProject.file(".."), path)
|
||||||
|
}
|
||||||
|
|
||||||
class MagiskPlugin : Plugin<Project> {
|
class MagiskPlugin : Plugin<Project> {
|
||||||
override fun apply(project: Project) = project.applyPlugin()
|
override fun apply(project: Project) = project.applyPlugin()
|
||||||
|
|
||||||
private fun Project.applyPlugin() {
|
private fun Project.applyPlugin() {
|
||||||
initRandom(rootProject.file("app/dict.txt"))
|
initRandom(rootProject.file("dict.txt"))
|
||||||
props.clear()
|
props.clear()
|
||||||
rootProject.file("gradle.properties").inputStream().use { props.load(it) }
|
rootProject.file("gradle.properties").inputStream().use { props.load(it) }
|
||||||
val configPath: String? by this
|
val configPath: String? by this
|
||||||
val config = configPath?.let { File(it) } ?: rootProject.file("config.prop")
|
val config = rootFile(configPath ?: "config.prop")
|
||||||
if (config.exists())
|
if (config.exists())
|
||||||
config.inputStream().use { props.load(it) }
|
config.inputStream().use { props.load(it) }
|
||||||
|
|
||||||
val repo = FileRepository(rootProject.file(".git"))
|
val repo = FileRepository(rootFile(".git"))
|
||||||
val refId = repo.refDatabase.exactRef("HEAD").objectId
|
val refId = repo.refDatabase.exactRef("HEAD").objectId
|
||||||
commitHash = repo.newObjectReader().abbreviate(refId, 8).name()
|
commitHash = repo.newObjectReader().abbreviate(refId, 8).name()
|
||||||
}
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user