diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 81068f159..c2d479537 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -240,6 +240,21 @@ jobs: tar --use-compress-program=unzstd -tf app/src/main/assets/pulseaudio.tzst | grep -c '\.so$' rm -rf pa-bundle sink-out + - name: Cache proot + id: proot + uses: actions/cache@v4 + with: + path: | + app/src/main/jniLibs/arm64-v8a/libproot.so + app/src/main/jniLibs/arm64-v8a/libproot-loader.so + key: proot-${{ env.NDK_VERSION }}-${{ hashFiles('tools/proot/**') }} + - name: Build proot + if: steps.proot.outputs.cache-hit != 'true' + run: | + set -euo pipefail + export NDK="${ANDROID_NDK_LATEST_HOME:-${ANDROID_NDK_HOME:-$ANDROID_NDK_ROOT}}" + tools/proot/build.sh app/src/main/jniLibs/arm64-v8a + - name: Check the preloads run: | set -euo pipefail diff --git a/.gitignore b/.gitignore index 1fa2e10c1..244bb5f33 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,8 @@ captures/ # Built in CI from tools/linuxfs and app/src/main/cpp/fakeinput.cpp, never committed, so the two # copies cannot drift. app/src/main/assets/linuxfs/ +app/src/main/jniLibs/arm64-v8a/libproot.so +app/src/main/jniLibs/arm64-v8a/libproot-loader.so # Kotlin compiler session files (build-tool state, never source). .kotlin/ diff --git a/app/src/main/cpp/framegen/VulkanRendererContext.h b/app/src/main/cpp/framegen/VulkanRendererContext.h index 5c8b8bfdd..cec4a4119 100644 --- a/app/src/main/cpp/framegen/VulkanRendererContext.h +++ b/app/src/main/cpp/framegen/VulkanRendererContext.h @@ -139,8 +139,6 @@ namespace winfg { class Engine; } static constexpr uint32_t MAX_FRAMES_IN_FLIGHT = 2; -struct WindowPushConstants { float ndcX0, ndcY0, ndcX1, ndcY1; int useTexAlpha; }; - // Push-constant layouts for the spatial-upscaler post passes. The leading vec4 // `ndc` matches upscale.vert; the remaining members are read only by the // fragment stage. std430 offsets line up with these C structs. @@ -164,11 +162,6 @@ struct RcasPushConstants { // 40 bytes uint32_t con[4]; // con.x = bit-packed sharpness float outW, outH; }; -struct DownscalePushConstants { // 32 bytes - float ndc[4]; - float srcW, srcH; // render (source) resolution - float dstW, dstH; // display (output) resolution -}; // Composable post effects (AMD CAS sharpen + fake-HDR). Both lead with vec4 ndc // (offset 0) like the upscaler PCs and stay well under the 88-byte PC range. struct CasPushConstants { // 32 bytes @@ -741,7 +734,6 @@ private: NisPushConstants nisPC{}; EasuPushConstants easuPC{}; RcasPushConstants rcasPC{}; - DownscalePushConstants dsPC{}; CasPushConstants casPC{}; HdrPushConstants hdrPC{}; FxaaPushConstants fxaaPC{}; diff --git a/app/src/main/cpp/shaders/downscale_frag.h b/app/src/main/cpp/shaders/downscale_frag.h deleted file mode 100644 index 8b29ace8a..000000000 --- a/app/src/main/cpp/shaders/downscale_frag.h +++ /dev/null @@ -1,133 +0,0 @@ - // 1116.2.0 - #pragma once -const uint32_t downscale_code[] = { - 0x07230203,0x00010000,0x0008000b,0x000000b5,0x00000000,0x00020011,0x00000001,0x00020011, - 0x00000032,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e, - 0x00000000,0x00000001,0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000046, - 0x000000ab,0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,0x000001c2,0x00040005, - 0x00000004,0x6e69616d,0x00000000,0x00060005,0x0000000a,0x636e616c,0x32736f7a,0x3b316628, - 0x00000000,0x00030005,0x00000009,0x00000078,0x00030005,0x0000001d,0x00007870,0x00040005, - 0x00000031,0x6c616373,0x00000065,0x00030005,0x00000033,0x00004350,0x00040006,0x00000033, - 0x00000000,0x0063646e,0x00050006,0x00000033,0x00000001,0x53637273,0x00657a69,0x00050006, - 0x00000033,0x00000002,0x53747364,0x00657a69,0x00030005,0x00000035,0x00006370,0x00050005, - 0x00000041,0x53766e69,0x656c6163,0x00000000,0x00030005,0x00000044,0x00000063,0x00060005, - 0x00000046,0x67617266,0x43786554,0x64726f6f,0x00000000,0x00040005,0x0000004d,0x65736162, - 0x00000000,0x00030005,0x00000051,0x00007a73,0x00030005,0x00000055,0x00637273,0x00030005, - 0x0000005c,0x00636361,0x00040005,0x0000005e,0x6d757377,0x00000000,0x00030005,0x00000060, - 0x00007964,0x00030005,0x0000006a,0x00007864,0x00030005,0x00000072,0x00000069,0x00030005, - 0x00000078,0x00000074,0x00030005,0x00000081,0x00000077,0x00040005,0x00000082,0x61726170, - 0x0000006d,0x00040005,0x00000088,0x61726170,0x0000006d,0x00030005,0x00000093,0x00006969, - 0x00050005,0x000000ab,0x4374756f,0x726f6c6f,0x00000000,0x00030047,0x00000033,0x00000002, - 0x00050048,0x00000033,0x00000000,0x00000023,0x00000000,0x00050048,0x00000033,0x00000001, - 0x00000023,0x00000010,0x00050048,0x00000033,0x00000002,0x00000023,0x00000018,0x00040047, - 0x00000046,0x0000001e,0x00000000,0x00040047,0x00000055,0x00000021,0x00000000,0x00040047, - 0x00000055,0x00000022,0x00000000,0x00040047,0x000000ab,0x0000001e,0x00000000,0x00020013, - 0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040020, - 0x00000007,0x00000007,0x00000006,0x00040021,0x00000008,0x00000006,0x00000007,0x0004002b, - 0x00000006,0x0000000f,0x3727c5ac,0x00020014,0x00000010,0x0004002b,0x00000006,0x00000014, - 0x3f800000,0x0004002b,0x00000006,0x00000017,0x40000000,0x0004002b,0x00000006,0x0000001b, - 0x00000000,0x0004002b,0x00000006,0x0000001e,0x40490fdb,0x0004002b,0x00000006,0x00000025, - 0x3f000000,0x00040017,0x0000002f,0x00000006,0x00000002,0x00040020,0x00000030,0x00000007, - 0x0000002f,0x00040017,0x00000032,0x00000006,0x00000004,0x0005001e,0x00000033,0x00000032, - 0x0000002f,0x0000002f,0x00040020,0x00000034,0x00000009,0x00000033,0x0004003b,0x00000034, - 0x00000035,0x00000009,0x00040015,0x00000036,0x00000020,0x00000001,0x0004002b,0x00000036, - 0x00000037,0x00000001,0x00040020,0x00000038,0x00000009,0x0000002f,0x0004002b,0x00000036, - 0x0000003b,0x00000002,0x0005002c,0x0000002f,0x0000003f,0x00000014,0x00000014,0x00040020, - 0x00000045,0x00000001,0x0000002f,0x0004003b,0x00000045,0x00000046,0x00000001,0x00040017, - 0x0000004b,0x00000036,0x00000002,0x00040020,0x0000004c,0x00000007,0x0000004b,0x00090019, - 0x00000052,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000, - 0x0003001b,0x00000053,0x00000052,0x00040020,0x00000054,0x00000000,0x00000053,0x0004003b, - 0x00000054,0x00000055,0x00000000,0x0004002b,0x00000036,0x00000057,0x00000000,0x00040017, - 0x0000005a,0x00000006,0x00000003,0x00040020,0x0000005b,0x00000007,0x0000005a,0x0006002c, - 0x0000005a,0x0000005d,0x0000001b,0x0000001b,0x0000001b,0x00040020,0x0000005f,0x00000007, - 0x00000036,0x0004002b,0x00000036,0x00000061,0xfffffffc,0x0004002b,0x00000036,0x00000068, - 0x00000004,0x0005002c,0x0000002f,0x0000007b,0x00000025,0x00000025,0x00040015,0x00000083, - 0x00000020,0x00000000,0x0004002b,0x00000083,0x00000084,0x00000000,0x0004002b,0x00000083, - 0x00000089,0x00000001,0x0005002c,0x0000004b,0x00000095,0x00000057,0x00000057,0x0005002c, - 0x0000004b,0x00000097,0x00000037,0x00000037,0x00040020,0x000000aa,0x00000003,0x00000032, - 0x0004003b,0x000000aa,0x000000ab,0x00000003,0x00050036,0x00000002,0x00000004,0x00000000, - 0x00000003,0x000200f8,0x00000005,0x0004003b,0x00000030,0x00000031,0x00000007,0x0004003b, - 0x00000030,0x00000041,0x00000007,0x0004003b,0x00000030,0x00000044,0x00000007,0x0004003b, - 0x0000004c,0x0000004d,0x00000007,0x0004003b,0x0000004c,0x00000051,0x00000007,0x0004003b, - 0x0000005b,0x0000005c,0x00000007,0x0004003b,0x00000007,0x0000005e,0x00000007,0x0004003b, - 0x0000005f,0x00000060,0x00000007,0x0004003b,0x0000005f,0x0000006a,0x00000007,0x0004003b, - 0x0000004c,0x00000072,0x00000007,0x0004003b,0x00000030,0x00000078,0x00000007,0x0004003b, - 0x00000007,0x00000081,0x00000007,0x0004003b,0x00000007,0x00000082,0x00000007,0x0004003b, - 0x00000007,0x00000088,0x00000007,0x0004003b,0x0000004c,0x00000093,0x00000007,0x00050041, - 0x00000038,0x00000039,0x00000035,0x00000037,0x0004003d,0x0000002f,0x0000003a,0x00000039, - 0x00050041,0x00000038,0x0000003c,0x00000035,0x0000003b,0x0004003d,0x0000002f,0x0000003d, - 0x0000003c,0x00050088,0x0000002f,0x0000003e,0x0000003a,0x0000003d,0x0007000c,0x0000002f, - 0x00000040,0x00000001,0x00000028,0x0000003e,0x0000003f,0x0003003e,0x00000031,0x00000040, - 0x0004003d,0x0000002f,0x00000042,0x00000031,0x00050088,0x0000002f,0x00000043,0x0000003f, - 0x00000042,0x0003003e,0x00000041,0x00000043,0x0004003d,0x0000002f,0x00000047,0x00000046, - 0x00050041,0x00000038,0x00000048,0x00000035,0x00000037,0x0004003d,0x0000002f,0x00000049, - 0x00000048,0x00050085,0x0000002f,0x0000004a,0x00000047,0x00000049,0x0003003e,0x00000044, - 0x0000004a,0x0004003d,0x0000002f,0x0000004e,0x00000044,0x0006000c,0x0000002f,0x0000004f, - 0x00000001,0x00000008,0x0000004e,0x0004006e,0x0000004b,0x00000050,0x0000004f,0x0003003e, - 0x0000004d,0x00000050,0x0004003d,0x00000053,0x00000056,0x00000055,0x00040064,0x00000052, - 0x00000058,0x00000056,0x00050067,0x0000004b,0x00000059,0x00000058,0x00000057,0x0003003e, - 0x00000051,0x00000059,0x0003003e,0x0000005c,0x0000005d,0x0003003e,0x0000005e,0x0000001b, - 0x0003003e,0x00000060,0x00000061,0x000200f9,0x00000062,0x000200f8,0x00000062,0x000400f6, - 0x00000064,0x00000065,0x00000000,0x000200f9,0x00000066,0x000200f8,0x00000066,0x0004003d, - 0x00000036,0x00000067,0x00000060,0x000500b3,0x00000010,0x00000069,0x00000067,0x00000068, - 0x000400fa,0x00000069,0x00000063,0x00000064,0x000200f8,0x00000063,0x0003003e,0x0000006a, - 0x00000061,0x000200f9,0x0000006b,0x000200f8,0x0000006b,0x000400f6,0x0000006d,0x0000006e, - 0x00000000,0x000200f9,0x0000006f,0x000200f8,0x0000006f,0x0004003d,0x00000036,0x00000070, - 0x0000006a,0x000500b3,0x00000010,0x00000071,0x00000070,0x00000068,0x000400fa,0x00000071, - 0x0000006c,0x0000006d,0x000200f8,0x0000006c,0x0004003d,0x0000004b,0x00000073,0x0000004d, - 0x0004003d,0x00000036,0x00000074,0x0000006a,0x0004003d,0x00000036,0x00000075,0x00000060, - 0x00050050,0x0000004b,0x00000076,0x00000074,0x00000075,0x00050080,0x0000004b,0x00000077, - 0x00000073,0x00000076,0x0003003e,0x00000072,0x00000077,0x0004003d,0x0000004b,0x00000079, - 0x00000072,0x0004006f,0x0000002f,0x0000007a,0x00000079,0x00050081,0x0000002f,0x0000007c, - 0x0000007a,0x0000007b,0x0004003d,0x0000002f,0x0000007d,0x00000044,0x00050083,0x0000002f, - 0x0000007e,0x0000007c,0x0000007d,0x0004003d,0x0000002f,0x0000007f,0x00000041,0x00050085, - 0x0000002f,0x00000080,0x0000007e,0x0000007f,0x0003003e,0x00000078,0x00000080,0x00050041, - 0x00000007,0x00000085,0x00000078,0x00000084,0x0004003d,0x00000006,0x00000086,0x00000085, - 0x0003003e,0x00000082,0x00000086,0x00050039,0x00000006,0x00000087,0x0000000a,0x00000082, - 0x00050041,0x00000007,0x0000008a,0x00000078,0x00000089,0x0004003d,0x00000006,0x0000008b, - 0x0000008a,0x0003003e,0x00000088,0x0000008b,0x00050039,0x00000006,0x0000008c,0x0000000a, - 0x00000088,0x00050085,0x00000006,0x0000008d,0x00000087,0x0000008c,0x0003003e,0x00000081, - 0x0000008d,0x0004003d,0x00000006,0x0000008e,0x00000081,0x000500b4,0x00000010,0x0000008f, - 0x0000008e,0x0000001b,0x000300f7,0x00000091,0x00000000,0x000400fa,0x0000008f,0x00000090, - 0x00000091,0x000200f8,0x00000090,0x000200f9,0x0000006e,0x000200f8,0x00000091,0x0004003d, - 0x0000004b,0x00000094,0x00000072,0x0004003d,0x0000004b,0x00000096,0x00000051,0x00050082, - 0x0000004b,0x00000098,0x00000096,0x00000097,0x0008000c,0x0000004b,0x00000099,0x00000001, - 0x0000002d,0x00000094,0x00000095,0x00000098,0x0003003e,0x00000093,0x00000099,0x0004003d, - 0x00000053,0x0000009a,0x00000055,0x0004003d,0x0000004b,0x0000009b,0x00000093,0x00040064, - 0x00000052,0x0000009c,0x0000009a,0x0007005f,0x00000032,0x0000009d,0x0000009c,0x0000009b, - 0x00000002,0x00000057,0x0008004f,0x0000005a,0x0000009e,0x0000009d,0x0000009d,0x00000000, - 0x00000001,0x00000002,0x0004003d,0x00000006,0x0000009f,0x00000081,0x0005008e,0x0000005a, - 0x000000a0,0x0000009e,0x0000009f,0x0004003d,0x0000005a,0x000000a1,0x0000005c,0x00050081, - 0x0000005a,0x000000a2,0x000000a1,0x000000a0,0x0003003e,0x0000005c,0x000000a2,0x0004003d, - 0x00000006,0x000000a3,0x00000081,0x0004003d,0x00000006,0x000000a4,0x0000005e,0x00050081, - 0x00000006,0x000000a5,0x000000a4,0x000000a3,0x0003003e,0x0000005e,0x000000a5,0x000200f9, - 0x0000006e,0x000200f8,0x0000006e,0x0004003d,0x00000036,0x000000a6,0x0000006a,0x00050080, - 0x00000036,0x000000a7,0x000000a6,0x00000037,0x0003003e,0x0000006a,0x000000a7,0x000200f9, - 0x0000006b,0x000200f8,0x0000006d,0x000200f9,0x00000065,0x000200f8,0x00000065,0x0004003d, - 0x00000036,0x000000a8,0x00000060,0x00050080,0x00000036,0x000000a9,0x000000a8,0x00000037, - 0x0003003e,0x00000060,0x000000a9,0x000200f9,0x00000062,0x000200f8,0x00000064,0x0004003d, - 0x0000005a,0x000000ac,0x0000005c,0x0004003d,0x00000006,0x000000ad,0x0000005e,0x0007000c, - 0x00000006,0x000000ae,0x00000001,0x00000028,0x000000ad,0x0000000f,0x00060050,0x0000005a, - 0x000000af,0x000000ae,0x000000ae,0x000000ae,0x00050088,0x0000005a,0x000000b0,0x000000ac, - 0x000000af,0x00050051,0x00000006,0x000000b1,0x000000b0,0x00000000,0x00050051,0x00000006, - 0x000000b2,0x000000b0,0x00000001,0x00050051,0x00000006,0x000000b3,0x000000b0,0x00000002, - 0x00070050,0x00000032,0x000000b4,0x000000b1,0x000000b2,0x000000b3,0x00000014,0x0003003e, - 0x000000ab,0x000000b4,0x000100fd,0x00010038,0x00050036,0x00000006,0x0000000a,0x00000000, - 0x00000008,0x00030037,0x00000007,0x00000009,0x000200f8,0x0000000b,0x0004003b,0x00000007, - 0x0000001d,0x00000007,0x0004003d,0x00000006,0x0000000c,0x00000009,0x0006000c,0x00000006, - 0x0000000d,0x00000001,0x00000004,0x0000000c,0x0003003e,0x00000009,0x0000000d,0x0004003d, - 0x00000006,0x0000000e,0x00000009,0x000500b8,0x00000010,0x00000011,0x0000000e,0x0000000f, - 0x000300f7,0x00000013,0x00000000,0x000400fa,0x00000011,0x00000012,0x00000013,0x000200f8, - 0x00000012,0x000200fe,0x00000014,0x000200f8,0x00000013,0x0004003d,0x00000006,0x00000016, - 0x00000009,0x000500be,0x00000010,0x00000018,0x00000016,0x00000017,0x000300f7,0x0000001a, - 0x00000000,0x000400fa,0x00000018,0x00000019,0x0000001a,0x000200f8,0x00000019,0x000200fe, - 0x0000001b,0x000200f8,0x0000001a,0x0004003d,0x00000006,0x0000001f,0x00000009,0x00050085, - 0x00000006,0x00000020,0x0000001e,0x0000001f,0x0003003e,0x0000001d,0x00000020,0x0004003d, - 0x00000006,0x00000021,0x0000001d,0x0006000c,0x00000006,0x00000022,0x00000001,0x0000000d, - 0x00000021,0x00050085,0x00000006,0x00000023,0x00000017,0x00000022,0x0004003d,0x00000006, - 0x00000024,0x0000001d,0x00050085,0x00000006,0x00000026,0x00000024,0x00000025,0x0006000c, - 0x00000006,0x00000027,0x00000001,0x0000000d,0x00000026,0x00050085,0x00000006,0x00000028, - 0x00000023,0x00000027,0x0004003d,0x00000006,0x00000029,0x0000001d,0x0004003d,0x00000006, - 0x0000002a,0x0000001d,0x00050085,0x00000006,0x0000002b,0x00000029,0x0000002a,0x00050088, - 0x00000006,0x0000002c,0x00000028,0x0000002b,0x000200fe,0x0000002c,0x00010038 -}; diff --git a/app/src/main/cpp/shaders/window_frag.h b/app/src/main/cpp/shaders/window_frag.h deleted file mode 100644 index 78d7e5848..000000000 --- a/app/src/main/cpp/shaders/window_frag.h +++ /dev/null @@ -1,49 +0,0 @@ - // 1116.3.0 - #pragma once -const uint32_t window_frag_code[] = { - 0x07230203,0x00010000,0x0008000b,0x00000033,0x00000000,0x00020011,0x00000001,0x0006000b, - 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, - 0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000011,0x00000015,0x00030010, - 0x00000004,0x00000007,0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d, - 0x00000000,0x00030005,0x00000009,0x00000063,0x00050005,0x0000000d,0x53786574,0x6c706d61, - 0x00007265,0x00060005,0x00000011,0x67617266,0x43786554,0x64726f6f,0x00000000,0x00050005, - 0x00000015,0x4374756f,0x726f6c6f,0x00000000,0x00030005,0x0000001a,0x00004350,0x00050006, - 0x0000001a,0x00000000,0x5863646e,0x00000030,0x00050006,0x0000001a,0x00000001,0x5963646e, - 0x00000030,0x00050006,0x0000001a,0x00000002,0x5863646e,0x00000031,0x00050006,0x0000001a, - 0x00000003,0x5963646e,0x00000031,0x00060006,0x0000001a,0x00000004,0x54657375,0x6c417865, - 0x00616870,0x00030005,0x0000001c,0x00006370,0x00040047,0x0000000d,0x00000021,0x00000000, - 0x00040047,0x0000000d,0x00000022,0x00000000,0x00040047,0x00000011,0x0000001e,0x00000000, - 0x00040047,0x00000015,0x0000001e,0x00000000,0x00030047,0x0000001a,0x00000002,0x00050048, - 0x0000001a,0x00000000,0x00000023,0x00000000,0x00050048,0x0000001a,0x00000001,0x00000023, - 0x00000004,0x00050048,0x0000001a,0x00000002,0x00000023,0x00000008,0x00050048,0x0000001a, - 0x00000003,0x00000023,0x0000000c,0x00050048,0x0000001a,0x00000004,0x00000023,0x00000010, - 0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020, - 0x00040017,0x00000007,0x00000006,0x00000004,0x00040020,0x00000008,0x00000007,0x00000007, - 0x00090019,0x0000000a,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001, - 0x00000000,0x0003001b,0x0000000b,0x0000000a,0x00040020,0x0000000c,0x00000000,0x0000000b, - 0x0004003b,0x0000000c,0x0000000d,0x00000000,0x00040017,0x0000000f,0x00000006,0x00000002, - 0x00040020,0x00000010,0x00000001,0x0000000f,0x0004003b,0x00000010,0x00000011,0x00000001, - 0x00040020,0x00000014,0x00000003,0x00000007,0x0004003b,0x00000014,0x00000015,0x00000003, - 0x00040017,0x00000016,0x00000006,0x00000003,0x00040015,0x00000019,0x00000020,0x00000001, - 0x0007001e,0x0000001a,0x00000006,0x00000006,0x00000006,0x00000006,0x00000019,0x00040020, - 0x0000001b,0x00000009,0x0000001a,0x0004003b,0x0000001b,0x0000001c,0x00000009,0x0004002b, - 0x00000019,0x0000001d,0x00000004,0x00040020,0x0000001e,0x00000009,0x00000019,0x0004002b, - 0x00000019,0x00000021,0x00000000,0x00020014,0x00000022,0x00040020,0x00000024,0x00000007, - 0x00000006,0x00040015,0x00000028,0x00000020,0x00000000,0x0004002b,0x00000028,0x00000029, - 0x00000003,0x0004002b,0x00000006,0x0000002d,0x3f800000,0x00050036,0x00000002,0x00000004, - 0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003b,0x00000008,0x00000009,0x00000007, - 0x0004003b,0x00000024,0x00000025,0x00000007,0x0004003d,0x0000000b,0x0000000e,0x0000000d, - 0x0004003d,0x0000000f,0x00000012,0x00000011,0x00050057,0x00000007,0x00000013,0x0000000e, - 0x00000012,0x0003003e,0x00000009,0x00000013,0x0004003d,0x00000007,0x00000017,0x00000009, - 0x0008004f,0x00000016,0x00000018,0x00000017,0x00000017,0x00000000,0x00000001,0x00000002, - 0x00050041,0x0000001e,0x0000001f,0x0000001c,0x0000001d,0x0004003d,0x00000019,0x00000020, - 0x0000001f,0x000500ab,0x00000022,0x00000023,0x00000020,0x00000021,0x000300f7,0x00000027, - 0x00000000,0x000400fa,0x00000023,0x00000026,0x0000002c,0x000200f8,0x00000026,0x00050041, - 0x00000024,0x0000002a,0x00000009,0x00000029,0x0004003d,0x00000006,0x0000002b,0x0000002a, - 0x0003003e,0x00000025,0x0000002b,0x000200f9,0x00000027,0x000200f8,0x0000002c,0x0003003e, - 0x00000025,0x0000002d,0x000200f9,0x00000027,0x000200f8,0x00000027,0x0004003d,0x00000006, - 0x0000002e,0x00000025,0x00050051,0x00000006,0x0000002f,0x00000018,0x00000000,0x00050051, - 0x00000006,0x00000030,0x00000018,0x00000001,0x00050051,0x00000006,0x00000031,0x00000018, - 0x00000002,0x00070050,0x00000007,0x00000032,0x0000002f,0x00000030,0x00000031,0x0000002e, - 0x0003003e,0x00000015,0x00000032,0x000100fd,0x00010038 -}; diff --git a/app/src/main/cpp/shaders/window_vert.h b/app/src/main/cpp/shaders/window_vert.h deleted file mode 100644 index 8c991104f..000000000 --- a/app/src/main/cpp/shaders/window_vert.h +++ /dev/null @@ -1,68 +0,0 @@ - // 1116.3.0 - #pragma once -const uint32_t window_vert_code[] = { - 0x07230203,0x00010000,0x0008000b,0x0000004a,0x00000000,0x00020011,0x00000001,0x0006000b, - 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, - 0x0008000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x0000000a,0x0000003a,0x00000044, - 0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005, - 0x00000008,0x00006978,0x00060005,0x0000000a,0x565f6c67,0x65747265,0x646e4978,0x00007865, - 0x00030005,0x0000000f,0x00006979,0x00030005,0x00000014,0x00000078,0x00030005,0x0000001b, - 0x00004350,0x00050006,0x0000001b,0x00000000,0x5863646e,0x00000030,0x00050006,0x0000001b, - 0x00000001,0x5963646e,0x00000030,0x00050006,0x0000001b,0x00000002,0x5863646e,0x00000031, - 0x00050006,0x0000001b,0x00000003,0x5963646e,0x00000031,0x00030005,0x0000001d,0x00006370, - 0x00030005,0x00000027,0x00000079,0x00060005,0x00000038,0x505f6c67,0x65567265,0x78657472, - 0x00000000,0x00060006,0x00000038,0x00000000,0x505f6c67,0x7469736f,0x006e6f69,0x00070006, - 0x00000038,0x00000001,0x505f6c67,0x746e696f,0x657a6953,0x00000000,0x00070006,0x00000038, - 0x00000002,0x435f6c67,0x4470696c,0x61747369,0x0065636e,0x00070006,0x00000038,0x00000003, - 0x435f6c67,0x446c6c75,0x61747369,0x0065636e,0x00030005,0x0000003a,0x00000000,0x00060005, - 0x00000044,0x67617266,0x43786554,0x64726f6f,0x00000000,0x00040047,0x0000000a,0x0000000b, - 0x0000002a,0x00030047,0x0000001b,0x00000002,0x00050048,0x0000001b,0x00000000,0x00000023, - 0x00000000,0x00050048,0x0000001b,0x00000001,0x00000023,0x00000004,0x00050048,0x0000001b, - 0x00000002,0x00000023,0x00000008,0x00050048,0x0000001b,0x00000003,0x00000023,0x0000000c, - 0x00030047,0x00000038,0x00000002,0x00050048,0x00000038,0x00000000,0x0000000b,0x00000000, - 0x00050048,0x00000038,0x00000001,0x0000000b,0x00000001,0x00050048,0x00000038,0x00000002, - 0x0000000b,0x00000003,0x00050048,0x00000038,0x00000003,0x0000000b,0x00000004,0x00040047, - 0x00000044,0x0000001e,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002, - 0x00040015,0x00000006,0x00000020,0x00000001,0x00040020,0x00000007,0x00000007,0x00000006, - 0x00040020,0x00000009,0x00000001,0x00000006,0x0004003b,0x00000009,0x0000000a,0x00000001, - 0x0004002b,0x00000006,0x0000000c,0x00000001,0x00030016,0x00000012,0x00000020,0x00040020, - 0x00000013,0x00000007,0x00000012,0x00020014,0x00000016,0x0006001e,0x0000001b,0x00000012, - 0x00000012,0x00000012,0x00000012,0x00040020,0x0000001c,0x00000009,0x0000001b,0x0004003b, - 0x0000001c,0x0000001d,0x00000009,0x0004002b,0x00000006,0x0000001e,0x00000002,0x00040020, - 0x0000001f,0x00000009,0x00000012,0x0004002b,0x00000006,0x00000023,0x00000000,0x0004002b, - 0x00000006,0x0000002d,0x00000003,0x00040017,0x00000034,0x00000012,0x00000004,0x00040015, - 0x00000035,0x00000020,0x00000000,0x0004002b,0x00000035,0x00000036,0x00000001,0x0004001c, - 0x00000037,0x00000012,0x00000036,0x0006001e,0x00000038,0x00000034,0x00000012,0x00000037, - 0x00000037,0x00040020,0x00000039,0x00000003,0x00000038,0x0004003b,0x00000039,0x0000003a, - 0x00000003,0x0004002b,0x00000012,0x0000003d,0x00000000,0x0004002b,0x00000012,0x0000003e, - 0x3f800000,0x00040020,0x00000040,0x00000003,0x00000034,0x00040017,0x00000042,0x00000012, - 0x00000002,0x00040020,0x00000043,0x00000003,0x00000042,0x0004003b,0x00000043,0x00000044, - 0x00000003,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005, - 0x0004003b,0x00000007,0x00000008,0x00000007,0x0004003b,0x00000007,0x0000000f,0x00000007, - 0x0004003b,0x00000013,0x00000014,0x00000007,0x0004003b,0x00000013,0x00000018,0x00000007, - 0x0004003b,0x00000013,0x00000027,0x00000007,0x0004003b,0x00000013,0x0000002a,0x00000007, - 0x0004003d,0x00000006,0x0000000b,0x0000000a,0x000500c3,0x00000006,0x0000000d,0x0000000b, - 0x0000000c,0x000500c7,0x00000006,0x0000000e,0x0000000d,0x0000000c,0x0003003e,0x00000008, - 0x0000000e,0x0004003d,0x00000006,0x00000010,0x0000000a,0x000500c7,0x00000006,0x00000011, - 0x00000010,0x0000000c,0x0003003e,0x0000000f,0x00000011,0x0004003d,0x00000006,0x00000015, - 0x00000008,0x000500aa,0x00000016,0x00000017,0x00000015,0x0000000c,0x000300f7,0x0000001a, - 0x00000000,0x000400fa,0x00000017,0x00000019,0x00000022,0x000200f8,0x00000019,0x00050041, - 0x0000001f,0x00000020,0x0000001d,0x0000001e,0x0004003d,0x00000012,0x00000021,0x00000020, - 0x0003003e,0x00000018,0x00000021,0x000200f9,0x0000001a,0x000200f8,0x00000022,0x00050041, - 0x0000001f,0x00000024,0x0000001d,0x00000023,0x0004003d,0x00000012,0x00000025,0x00000024, - 0x0003003e,0x00000018,0x00000025,0x000200f9,0x0000001a,0x000200f8,0x0000001a,0x0004003d, - 0x00000012,0x00000026,0x00000018,0x0003003e,0x00000014,0x00000026,0x0004003d,0x00000006, - 0x00000028,0x0000000f,0x000500aa,0x00000016,0x00000029,0x00000028,0x0000000c,0x000300f7, - 0x0000002c,0x00000000,0x000400fa,0x00000029,0x0000002b,0x00000030,0x000200f8,0x0000002b, - 0x00050041,0x0000001f,0x0000002e,0x0000001d,0x0000002d,0x0004003d,0x00000012,0x0000002f, - 0x0000002e,0x0003003e,0x0000002a,0x0000002f,0x000200f9,0x0000002c,0x000200f8,0x00000030, - 0x00050041,0x0000001f,0x00000031,0x0000001d,0x0000000c,0x0004003d,0x00000012,0x00000032, - 0x00000031,0x0003003e,0x0000002a,0x00000032,0x000200f9,0x0000002c,0x000200f8,0x0000002c, - 0x0004003d,0x00000012,0x00000033,0x0000002a,0x0003003e,0x00000027,0x00000033,0x0004003d, - 0x00000012,0x0000003b,0x00000014,0x0004003d,0x00000012,0x0000003c,0x00000027,0x00070050, - 0x00000034,0x0000003f,0x0000003b,0x0000003c,0x0000003d,0x0000003e,0x00050041,0x00000040, - 0x00000041,0x0000003a,0x00000023,0x0003003e,0x00000041,0x0000003f,0x0004003d,0x00000006, - 0x00000045,0x00000008,0x0004006f,0x00000012,0x00000046,0x00000045,0x0004003d,0x00000006, - 0x00000047,0x0000000f,0x0004006f,0x00000012,0x00000048,0x00000047,0x00050050,0x00000042, - 0x00000049,0x00000046,0x00000048,0x0003003e,0x00000044,0x00000049,0x000100fd,0x00010038 -}; diff --git a/app/src/main/cpp/waylandcomp/src/vk_import.c b/app/src/main/cpp/waylandcomp/src/vk_import.c deleted file mode 100644 index 08c1351a3..000000000 --- a/app/src/main/cpp/waylandcomp/src/vk_import.c +++ /dev/null @@ -1,167 +0,0 @@ -/* Compositor-side dmabuf import into Turnip (see vk_import.h). */ -#define _POSIX_C_SOURCE 200809L -#include "vk_import.h" -#include -#include -#include -#include -#include - -#define MOD_INVALID 0x00ffffffffffffffULL - -static int g_ready = -1; /* -1 = untried, 0 = ok, 1 = init failed */ -static VkInstance g_inst; -static VkPhysicalDevice g_pd; -static VkDevice g_dev; -static PFN_vkGetMemoryFdPropertiesKHR p_getMemFdProps; - -static int has_ext(VkExtensionProperties *e, uint32_t n, const char *name) { - for (uint32_t i = 0; i < n; i++) - if (!strcmp(e[i].extensionName, name)) return 1; - return 0; -} - -static int vk_init(void) { - if (g_ready >= 0) return g_ready == 0 ? 0 : -1; - - VkApplicationInfo app = {.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, - .pApplicationName = "spike-compositor-import", - .apiVersion = VK_API_VERSION_1_1}; - VkInstanceCreateInfo ici = {.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, - .pApplicationInfo = &app}; - if (vkCreateInstance(&ici, NULL, &g_inst) != VK_SUCCESS) { - fprintf(stderr, "[imp] vkCreateInstance failed\n"); - g_ready = 1; return -1; - } - uint32_t npd = 0; - vkEnumeratePhysicalDevices(g_inst, &npd, NULL); - if (!npd) { g_ready = 1; return -1; } - VkPhysicalDevice pds[8]; - if (npd > 8) npd = 8; - vkEnumeratePhysicalDevices(g_inst, &npd, pds); - g_pd = pds[0]; /* Turnip is forced via VK_ICD_FILENAMES */ - - const char *want[] = {"VK_KHR_external_memory_fd", - "VK_EXT_external_memory_dma_buf", - "VK_EXT_image_drm_format_modifier", - "VK_KHR_image_format_list"}; - uint32_t ne = 0; - vkEnumerateDeviceExtensionProperties(g_pd, NULL, &ne, NULL); - VkExtensionProperties *exts = calloc(ne, sizeof(*exts)); - vkEnumerateDeviceExtensionProperties(g_pd, NULL, &ne, exts); - for (unsigned i = 0; i < 4; i++) - if (!has_ext(exts, ne, want[i])) - fprintf(stderr, "[imp] WARNING device missing %s\n", want[i]); - free(exts); - - float prio = 1.0f; - VkDeviceQueueCreateInfo qci = {.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, - .queueFamilyIndex = 0, .queueCount = 1, - .pQueuePriorities = &prio}; - VkDeviceCreateInfo dci = {.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, - .queueCreateInfoCount = 1, .pQueueCreateInfos = &qci, - .enabledExtensionCount = 4, .ppEnabledExtensionNames = want}; - if (vkCreateDevice(g_pd, &dci, NULL, &g_dev) != VK_SUCCESS) { - fprintf(stderr, "[imp] vkCreateDevice failed\n"); - g_ready = 1; return -1; - } - p_getMemFdProps = (PFN_vkGetMemoryFdPropertiesKHR)vkGetDeviceProcAddr( - g_dev, "vkGetMemoryFdPropertiesKHR"); - g_ready = 0; - fprintf(stderr, "[imp] Vulkan import device ready (Turnip)\n"); - return 0; -} - -static VkFormat drm_to_vk(uint32_t drm) { - /* XR24/AR24 (XRGB/ARGB8888, little-endian bytes B,G,R,X) -> BGRA8. */ - return VK_FORMAT_B8G8R8A8_UNORM; -} - -int vk_import_dmabuf(int fd, uint32_t drm_format, uint64_t modifier, int w, int h, - uint32_t stride, uint32_t offset) { - if (modifier == MOD_INVALID) { - fprintf(stderr, "[imp] skip: INVALID modifier (needs implicit path)\n"); - return -1; - } - if (vk_init() != 0) return -1; - - VkSubresourceLayout plane = {.offset = offset, .rowPitch = stride}; - VkImageDrmFormatModifierExplicitCreateInfoEXT modInfo = { - .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT, - .drmFormatModifier = modifier, - .drmFormatModifierPlaneCount = 1, - .pPlaneLayouts = &plane}; - VkExternalMemoryImageCreateInfo extImg = { - .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO, - .pNext = &modInfo, - .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT}; - VkImageCreateInfo ici = { - .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, - .pNext = &extImg, - .imageType = VK_IMAGE_TYPE_2D, - .format = drm_to_vk(drm_format), - .extent = {w, h, 1}, - .mipLevels = 1, .arrayLayers = 1, .samples = VK_SAMPLE_COUNT_1_BIT, - .tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT, - .usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, - .sharingMode = VK_SHARING_MODE_EXCLUSIVE, - .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED}; - VkImage image; - VkResult r = vkCreateImage(g_dev, &ici, NULL, &image); - if (r != VK_SUCCESS) { - fprintf(stderr, "[imp] vkCreateImage(drm_modifier) -> %d\n", r); - return -1; - } - - int dupfd = dup(fd); - uint32_t allowed_types = 0xffffffff; - if (p_getMemFdProps) { - VkMemoryFdPropertiesKHR fp = {.sType = VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR}; - if (p_getMemFdProps(g_dev, VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, - dupfd, &fp) == VK_SUCCESS) - allowed_types = fp.memoryTypeBits; - } - VkMemoryRequirements req; - vkGetImageMemoryRequirements(g_dev, image, &req); - uint32_t bits = req.memoryTypeBits & allowed_types; - int type_idx = -1; - for (int i = 0; i < 32; i++) - if (bits & (1u << i)) { type_idx = i; break; } - if (type_idx < 0) { - fprintf(stderr, "[imp] no compatible memory type\n"); - vkDestroyImage(g_dev, image, NULL); close(dupfd); return -1; - } - - VkImportMemoryFdInfoKHR imp = { - .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR, - .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, - .fd = dupfd}; - VkMemoryDedicatedAllocateInfo ded = { - .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, - .pNext = &imp, .image = image}; - VkMemoryAllocateInfo mai = {.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, - .pNext = &ded, - .allocationSize = req.size, - .memoryTypeIndex = (uint32_t)type_idx}; - VkDeviceMemory mem; - r = vkAllocateMemory(g_dev, &mai, NULL, &mem); - if (r != VK_SUCCESS) { - fprintf(stderr, "[imp] vkAllocateMemory(import fd) -> %d\n", r); - vkDestroyImage(g_dev, image, NULL); close(dupfd); return -1; - } - r = vkBindImageMemory(g_dev, image, mem, 0); - if (r != VK_SUCCESS) { - fprintf(stderr, "[imp] vkBindImageMemory -> %d\n", r); - vkFreeMemory(g_dev, mem, NULL); vkDestroyImage(g_dev, image, NULL); - return -1; - } - - fprintf(stderr, - "[imp] *** IMPORTED dmabuf -> VkImage OK (memType %d, size %llu) " - "==> compositor can turn game frames into VkImages\n", - type_idx, (unsigned long long)req.size); - /* import took ownership of dupfd; free our objects */ - vkFreeMemory(g_dev, mem, NULL); - vkDestroyImage(g_dev, image, NULL); - return 0; -} diff --git a/app/src/main/cpp/waylandcomp/src/vk_import.h b/app/src/main/cpp/waylandcomp/src/vk_import.h deleted file mode 100644 index b333e6db9..000000000 --- a/app/src/main/cpp/waylandcomp/src/vk_import.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef VK_IMPORT_H -#define VK_IMPORT_H -#include -/* - * Import a received dmabuf into the compositor's own Vulkan (Turnip) device as a - * VkImage and bind its memory. This is the M4-import de-risk: if we can import + - * bind, sampling/blitting it to screen is standard Vulkan. Non-fatal: returns 0 - * on success, negative on failure, and logs details. Does NOT consume `fd` - * (dups internally). - */ -int vk_import_dmabuf(int fd, uint32_t drm_format, uint64_t modifier, - int w, int h, uint32_t stride, uint32_t offset); -#endif diff --git a/app/src/main/java/com/droiddeck/launcher/MainActivity.kt b/app/src/main/java/com/droiddeck/launcher/MainActivity.kt index 972e363a0..94f6ef1c9 100644 --- a/app/src/main/java/com/droiddeck/launcher/MainActivity.kt +++ b/app/src/main/java/com/droiddeck/launcher/MainActivity.kt @@ -86,7 +86,6 @@ class MainActivity : ComponentActivity() { private var glThread by mutableStateOf(true) private var noGlError by mutableStateOf(true) private var steamDeckMode by mutableStateOf(false) - private var showFrameGen by mutableStateOf(false) private var showCredits by mutableStateOf(false) private var showProtons by mutableStateOf(false) private var showMapping by mutableStateOf(false) @@ -590,9 +589,6 @@ class MainActivity : ComponentActivity() { }, "remove-pkg").start() } - /** Both driver lists as the dialog shows them, re-read from disk so an import or removal shows at once. */ - /** Everything the mode's cog shows, read fresh, then the dialog. */ - /** The Steam or Desktop settings page, in the front end's pane. */ @Composable private fun ModeSettingsHost(mode: String) { ModeSettingsPage( @@ -674,7 +670,6 @@ class MainActivity : ComponentActivity() { ) } - /** The Performance page, in the front end's pane. */ @Composable private fun PerformanceHost() { PerformancePage( diff --git a/app/src/main/java/com/droiddeck/launcher/files/FileManagerScreen.kt b/app/src/main/java/com/droiddeck/launcher/files/FileManagerScreen.kt index fda38ed8e..6442e656b 100644 --- a/app/src/main/java/com/droiddeck/launcher/files/FileManagerScreen.kt +++ b/app/src/main/java/com/droiddeck/launcher/files/FileManagerScreen.kt @@ -98,7 +98,6 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.asImageBitmap -import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.graphics.vector.rememberVectorPainter @@ -143,10 +142,6 @@ import java.util.Locale */ enum class ConflictChoice { OVERWRITE, MERGE, KEEP_BOTH, SKIP } -/** - * Ordering for the file list. Folders always lead regardless of direction - a descending sort that - * buries every folder under the files is never what someone means by "Z to A". - */ /** * Shortens a path from the LEFT, keeping whole segments. * @@ -164,6 +159,7 @@ private fun elidePathStart(path: String, max: Int): String { return if (out.isEmpty()) "…" + path.takeLast(max - 1) else "…$out" } +/** Folder-first ordering stays fixed across both sort directions. */ private fun comparatorFor(sortBy: String, desc: Boolean): Comparator { val inner: Comparator = when (sortBy) { "date" -> compareBy { it.lastModified() } @@ -176,17 +172,9 @@ private fun comparatorFor(sortBy: String, desc: Boolean): Comparator { return compareBy { if (it.isDirectory) 0 else 1 }.then(directed) } -private val FileTypeIcon: Map = mapOf( - "folder" to Icons.Filled.Folder, -) - // Image extensions that get a real thumbnail (via Coil) instead of the generic file icon. private val IMAGE_THUMB_EXTS = setOf("jpg", "jpeg", "png", "webp", "bmp", "gif") -// Color-only sweep: the former card-fill / card-stroke / divider / icon-blue / icon-white -// constants were rerouted onto MaterialTheme.colorScheme tokens (surface / outline / primary / -// onSurface) at their use sites so a theme preset/accent recolors them. - // True when [child] is [ancestor] itself or lives anywhere inside it. private fun isWithin(child: File, ancestor: File): Boolean { val c = runCatching { child.canonicalPath }.getOrDefault(child.absolutePath) @@ -937,8 +925,7 @@ fun FileManagerScreen( } if (!showFavorites) { - // New Folder moved off a bottom bar into the toolbar (next to the grid/list toggle), - // as a compact outlined button, so the file list reclaims that bottom strip. + // Keep New Folder in the toolbar so the file list uses the full height. if (!pickMode) { OutlinedButton( onClick = { showNewFolderDialog = true }, @@ -1425,7 +1412,6 @@ fun FileManagerScreen( } } // end content Box (beside the rail) } // end rail + content Row - // (New Folder moved into the top toolbar; the bottom bar was removed to reclaim its strip.) } } @@ -1447,7 +1433,6 @@ private fun FileContextMenuItems( onDismissMenu: () -> Unit, ) { val isDir = file.isDirectory - // Enter multi-select on this item (replaces the old long-press-only entry point). DropdownMenuItem( text = { Text("Select") }, leadingIcon = { Icon(Icons.Filled.Checklist, null, tint = MaterialTheme.colorScheme.primary) }, diff --git a/app/src/main/java/com/droiddeck/launcher/frontend/AddedGames.kt b/app/src/main/java/com/droiddeck/launcher/frontend/AddedGames.kt index 4f78634a4..bd5a75983 100644 --- a/app/src/main/java/com/droiddeck/launcher/frontend/AddedGames.kt +++ b/app/src/main/java/com/droiddeck/launcher/frontend/AddedGames.kt @@ -56,10 +56,10 @@ object AddedGames { "|.*installer.*|.*uninstall.*|.*updater?.*|.*config(ur.*)?|.*settings.*|.*editor.*|.*server.*|.*benchmark.*|.*helper.*|.*eac.*|.*easyanticheat.*|.*battleye.*)\\.exe$", ) - /** Where a host path appears inside the session, or null when the session cannot see it. */ /** Under here the chosen Games folders are bound inside the session, one each. */ const val GUEST_DIR = "/root/Games" + /** Where a host path appears inside the session, or null when the session cannot see it. */ fun guestPath(context: Context, host: File): String? { val path = host.absolutePath // The Games folders are bound on their own, so a folder anywhere - an SD card, a USB diff --git a/app/src/main/java/com/droiddeck/launcher/runtime/LinuxRuntime.java b/app/src/main/java/com/droiddeck/launcher/runtime/LinuxRuntime.java index 838c970b0..b0d9adb89 100644 --- a/app/src/main/java/com/droiddeck/launcher/runtime/LinuxRuntime.java +++ b/app/src/main/java/com/droiddeck/launcher/runtime/LinuxRuntime.java @@ -58,30 +58,22 @@ public final class LinuxRuntime { /** Where the runtime carries the host-side proot; see tools/linuxfs/prebuilt/proot/README.md. */ private static final String HOST_DIR = "opt/android-host"; - /** - * proot, preferred from the installed runtime and falling back to the copy in the apk. - * - *

It is an Android binary rather than part of the rootfs - it is what creates the rootfs - - * but it travels in the runtime tarball so that reinstalling the app cannot replace the one - * binary everything else depends on, and so a device with no working packaged proot can still - * run the runtime. - */ public static File prootBinary(Context context) { - File shipped = new File(rootDir(context), HOST_DIR + "/proot"); - if (shipped.isFile()) return shipped; - return new File(context.getApplicationInfo().nativeLibraryDir, "libproot.so"); + File packaged = new File(context.getApplicationInfo().nativeLibraryDir, "libproot.so"); + if (packaged.isFile()) return packaged; + return new File(rootDir(context), HOST_DIR + "/proot"); } public static File prootLoader(Context context) { - File shipped = new File(rootDir(context), HOST_DIR + "/loader"); - if (shipped.isFile()) return shipped; - return new File(context.getApplicationInfo().nativeLibraryDir, "libproot-loader.so"); + File packaged = new File(context.getApplicationInfo().nativeLibraryDir, "libproot-loader.so"); + if (packaged.isFile()) return packaged; + return new File(rootDir(context), HOST_DIR + "/loader"); } /** proot links against libtalloc, which sits beside it; empty when the apk copy is in use. */ public static String prootLibraryPath(Context context) { File dir = new File(rootDir(context), HOST_DIR); - return new File(dir, "proot").isFile() ? dir.getPath() : ""; + return dir.equals(prootBinary(context).getParentFile()) ? dir.getPath() : ""; } /** The rootfs is present with gamescope and the session script the launcher hands control to. */ diff --git a/app/src/main/java/com/droiddeck/launcher/session/SessionPaths.kt b/app/src/main/java/com/droiddeck/launcher/session/SessionPaths.kt index 0ae1ffb98..68570c848 100644 --- a/app/src/main/java/com/droiddeck/launcher/session/SessionPaths.kt +++ b/app/src/main/java/com/droiddeck/launcher/session/SessionPaths.kt @@ -48,7 +48,6 @@ object SessionPaths { return made } - /** The current session's folder, or null between sessions. */ fun current(): File? = dir /** @@ -63,7 +62,6 @@ object SessionPaths { return ended } - /** A file in the current session's folder, or null between sessions. */ fun file(name: String): File? = dir?.let { File(it, name) } /** Let the next session claim a new folder. Called when a session ends. */ diff --git a/app/src/main/java/com/droiddeck/launcher/session/SessionService.kt b/app/src/main/java/com/droiddeck/launcher/session/SessionService.kt index ec15c5c2c..5fa6f3c5d 100644 --- a/app/src/main/java/com/droiddeck/launcher/session/SessionService.kt +++ b/app/src/main/java/com/droiddeck/launcher/session/SessionService.kt @@ -982,7 +982,7 @@ class SessionService : Service() { private const val EXTRA_AUXILIARY_PID = "auxiliaryPid" /** Command lines that can only belong to a session of ours. */ private val STRAGGLERS = listOf("bannerlator-session", "gamescope", "Xwayland", "steamrtarm64", - "steamwebhelper", "linuxfs/opt/android-host/proot", "pulseaudio/libpulseaudio.so") + "steamwebhelper", "linuxfs/opt/android-host/proot", "/libproot.so", "pulseaudio/libpulseaudio.so") /** How long proot gets to run its own cleanup before it is killed outright. */ private const val GRACE_MS = 1200L private const val NO_PAD_SWITCH = "Download/droiddeck-no-pad" diff --git a/app/src/main/java/com/droiddeck/launcher/ui/ModeSettingsDialog.kt b/app/src/main/java/com/droiddeck/launcher/ui/ModeSettingsDialog.kt index 6eb2cc913..9c964a0f5 100644 --- a/app/src/main/java/com/droiddeck/launcher/ui/ModeSettingsDialog.kt +++ b/app/src/main/java/com/droiddeck/launcher/ui/ModeSettingsDialog.kt @@ -59,8 +59,7 @@ class ModeSettings( val forceFullscreen: Boolean? = null, /** Steam only: the client branch forced on the command line. */ val steamChannel: String? = null, - /** Steam only: the user's own games folder and what was found in it. */ - /** The chosen Games folders (null = not a Steam page). */ + /** Steam only: the user's chosen Games folders; null outside Steam. */ val addedGamesDirs: List? = null, val addedGames: List = emptyList(), val addedGamesArt: Boolean = true, diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml deleted file mode 100644 index 8ae0e2961..000000000 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/app/src/main/res/values-w600dp/dimens.xml b/app/src/main/res/values-w600dp/dimens.xml deleted file mode 100644 index a00eee9b6..000000000 --- a/app/src/main/res/values-w600dp/dimens.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - 96dp - 80dp - diff --git a/app/src/main/res/values-w960dp/dimens.xml b/app/src/main/res/values-w960dp/dimens.xml deleted file mode 100644 index 6f48fecf8..000000000 --- a/app/src/main/res/values-w960dp/dimens.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - 240dp - 88dp - diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml deleted file mode 100644 index a338b9468..000000000 --- a/app/src/main/res/values/dimens.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - 24dp - 72dp - diff --git a/gradle.properties b/gradle.properties index 58de70a52..68abc99e0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,8 +1,5 @@ org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8 -# CI is the only thing that builds this repo and its minutes are billed, so every cache Gradle -# offers is on: task outputs are reused across runs from the cache the CI action restores, the -# configuration phase is skipped when nothing about the build scripts changed, and independent -# tasks run together. +# Reuse task outputs, skip unchanged configuration, and run independent tasks in parallel. org.gradle.caching=true org.gradle.configuration-cache=true org.gradle.parallel=true diff --git a/tools/build_local.sh b/tools/build_local.sh index cd831a8df..3df403703 100755 --- a/tools/build_local.sh +++ b/tools/build_local.sh @@ -135,6 +135,7 @@ fi export NDK="${sdk_dir}/ndk/${ndk_version}" sink_output="${staging_dir}/sink-out" "${repo_root}/tools/aaudio-sink/build.sh" "${pa_source}" "${sink_output}" +"${repo_root}/tools/proot/build.sh" "${repo_root}/app/src/main/jniLibs/arm64-v8a" cp -p "${bundle_asset}" "${bundle_backup}" bundle_dir="${staging_dir}/pulseaudio-bundle" diff --git a/tools/proot/PATCHES.md b/tools/proot/PATCHES.md new file mode 100644 index 000000000..64b5857dc --- /dev/null +++ b/tools/proot/PATCHES.md @@ -0,0 +1,21 @@ +# proot patches carried by the app + +Built by `tools/proot/build.sh` with the NDK on top of termux/proot `4dba3afb` (Termux's +5.1.107-70 package, the proot the Linux runtime ships at `opt/android-host/proot`; every +`file.c:line` site in that binary matches this commit). talloc is linked in statically from +Samba's release tarball, so the apk carries one self-contained `libproot.so` plus +`libproot-loader.so`, and `LinuxRuntime` prefers them over the runtime's copy. + +Ported from WinNative (`feature/proot-enhancements`, e7af0f24): + +- `0001-tracee-lookup-by-pid.patch` - tracees are hashed by pid, so each ptrace stop finds its + tracee without walking one list entry per thread, and terminated tracees are swept only after a + termination. +- `0002-canon-resolve-parent-at-once.patch` - a clean absolute guest path at least three + directories deep under the rootfs binding alone has its parent opened once with `O_PATH` and + taken as canonical when `/proc/self/fd` names the path proot would build, replacing an `lstat` + per component. The final component of a call that does not follow it is no longer `lstat`ed. + Extensions still see the parent's host path, and the fast path stays off while the f2fs + workaround is active. +- `0003-clone3-flags-read-guard.patch` - a thread created with `clone3` keeps the flags it + inherited when `struct clone_args` cannot be read, instead of being tracked as a fork. diff --git a/tools/proot/build.sh b/tools/proot/build.sh new file mode 100755 index 000000000..897e2e017 --- /dev/null +++ b/tools/proot/build.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +set -euo pipefail +OUTDIR=$(mkdir -p "$1" && cd "$1" && pwd) +: "${NDK:?set NDK to the Android NDK root}" +API=26 +HERE=$(cd "$(dirname "$0")" && pwd) +. "$HERE/source.env" +case "$(uname -s):$(uname -m)" in + Darwin:*) NDK_HOST=darwin-x86_64 ;; + Linux:x86_64) NDK_HOST=linux-x86_64 ;; + Linux:aarch64|Linux:arm64) NDK_HOST=linux-aarch64 ;; + *) echo "Unsupported build host: $(uname -s) $(uname -m)" >&2; exit 1 ;; +esac +TOOLCHAIN="$NDK/toolchains/llvm/prebuilt/$NDK_HOST/bin" +if [[ ! -d "$TOOLCHAIN" && -d "$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin" ]]; then + TOOLCHAIN="$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin" +fi +CC="$TOOLCHAIN/aarch64-linux-android${API}-clang" +if [[ ! -x "$CC" ]]; then + echo "Android NDK toolchain not found at $TOOLCHAIN" >&2 + exit 1 +fi +WORK=$(mktemp -d) +trap 'rm -rf "$WORK"' EXIT +fetch() { + curl -fsSL --retry 3 -o "$WORK/$1" "$2" + echo "$3 $WORK/$1" | shasum -a 256 -c - + mkdir -p "$WORK/${1%%.*}" + tar -xzf "$WORK/$1" -C "$WORK/${1%%.*}" --strip-components=1 +} +fetch proot.tar.gz "https://github.com/termux/proot/archive/${PROOT_COMMIT}.tar.gz" "$PROOT_SHA256" +fetch talloc.tar.gz "https://www.samba.org/ftp/talloc/talloc-${TALLOC_VERSION}.tar.gz" "$TALLOC_SHA256" +for patch in "$HERE"/patches/*.patch; do + patch -d "$WORK/proot" -p1 --forward --quiet < "$patch" +done +mkdir -p "$WORK/talloc/config" +cp "$HERE/talloc-config.h" "$WORK/talloc/config/config.h" +"$CC" -c -O2 -fPIC -ffile-prefix-map="$WORK"=. -D__STDC_WANT_LIB_EXT1__=1 -DHAVE_CONFIG_H \ + -I"$WORK/talloc/config" -I"$WORK/talloc" -I"$WORK/talloc/lib/replace" \ + -o "$WORK/talloc.o" "$WORK/talloc/talloc.c" +"$TOOLCHAIN/llvm-ar" rcs "$WORK/libtalloc.a" "$WORK/talloc.o" +mkdir -p "$WORK/bin" +ln -s "$TOOLCHAIN/llvm-readelf" "$WORK/bin/readelf" +PATH="$WORK/bin:$PATH" make -C "$WORK/proot/src" -j"$(getconf _NPROCESSORS_ONLN)" \ + CC="$CC" STRIP="$TOOLCHAIN/llvm-strip" OBJCOPY="$TOOLCHAIN/llvm-objcopy" OBJDUMP="$TOOLCHAIN/llvm-objdump" \ + CPPFLAGS="-D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -I. -I$WORK/talloc -DARG_MAX=131072 -Wno-error=implicit-function-declaration" \ + LDFLAGS="$WORK/libtalloc.a -Wl,-z,noexecstack" \ + PROOT_UNBUNDLE_LOADER=/nonexistent proot loader +install -m755 "$WORK/proot/src/proot" "$OUTDIR/libproot.so" +install -m755 "$WORK/proot/src/loader/loader" "$OUTDIR/libproot-loader.so" +"$TOOLCHAIN/llvm-strip" --strip-unneeded "$OUTDIR/libproot.so" +grep -q '^#define HAVE_SECCOMP_FILTER' "$WORK/proot/src/build.h" || { echo "ERROR: proot was built without seccomp acceleration"; exit 1; } +grep -q '^#define HAVE_PROCESS_VM' "$WORK/proot/src/build.h" || { echo "ERROR: proot was built without process_vm"; exit 1; } +NEEDED=$("$TOOLCHAIN/llvm-readelf" -d "$OUTDIR/libproot.so" | sed -n 's/.*NEEDED.*\[\(.*\)\]/\1/p' | tr '\n' ' ') +echo "libproot.so NEEDED: $NEEDED" +for lib in $NEEDED; do + case $lib in libc.so|libdl.so|libm.so) ;; + *) echo "ERROR: unexpected dependency $lib"; exit 1 ;; + esac +done +ls -l "$OUTDIR/libproot.so" "$OUTDIR/libproot-loader.so" diff --git a/tools/proot/patches/0001-tracee-lookup-by-pid.patch b/tools/proot/patches/0001-tracee-lookup-by-pid.patch new file mode 100644 index 000000000..3b181ced6 --- /dev/null +++ b/tools/proot/patches/0001-tracee-lookup-by-pid.patch @@ -0,0 +1,137 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: maxjivi05 +Date: Wed, 23 Sep 2026 21:44:45 -0400 +Subject: [PATCH] tracee: find tracees by pid, and sweep only after a + termination + +--- + src/cli/cli.c | 2 +- + src/tracee/event.c | 2 +- + src/tracee/tracee.c | 26 +++++++++++++++++++++++++- + src/tracee/tracee.h | 2 ++ + 4 files changed, 29 insertions(+), 3 deletions(-) + +diff --git a/src/cli/cli.c b/src/cli/cli.c +index bbc6400..ec50712 100644 +--- a/src/cli/cli.c ++++ b/src/cli/cli.c +@@ -465,7 +465,7 @@ int main(int argc, char *const argv[]) + tracee = get_tracee(NULL, 0, true); + if (tracee == NULL) + goto error; +- tracee->pid = getpid(); ++ set_tracee_pid(tracee, getpid()); + + /* Set verboseness from env variable, may be overriden by option */ + { +diff --git a/src/tracee/event.c b/src/tracee/event.c +index 756aa7e..ec79ef3 100644 +--- a/src/tracee/event.c ++++ b/src/tracee/event.c +@@ -106,7 +106,7 @@ int launch_process(Tracee *tracee, char *const argv[]) + + default: /* parent */ + /* We know the pid of the first tracee now. */ +- tracee->pid = pid; ++ set_tracee_pid(tracee, pid); + return 0; + } + +diff --git a/src/tracee/tracee.c b/src/tracee/tracee.c +index a97757d..90894a0 100644 +--- a/src/tracee/tracee.c ++++ b/src/tracee/tracee.c +@@ -48,6 +48,16 @@ + + static Tracees tracees; + ++#define TRACEE_BUCKETS 1024 ++static Tracees buckets[TRACEE_BUCKETS]; ++ ++static bool terminations_pending = false; ++ ++static Tracees *bucket_of(pid_t pid) ++{ ++ return &buckets[(unsigned int) pid % TRACEE_BUCKETS]; ++} ++ + + /** + * Remove @zombie from its parent's list of zombies. Note: this is a +@@ -89,6 +99,7 @@ static int remove_tracee(Tracee *tracee) + int event; + + LIST_REMOVE(tracee, link); ++ LIST_REMOVE(tracee, bucket_link); + + /* Clean objects that are linked to this tracee's life + * span. */ +@@ -226,6 +237,7 @@ static Tracee *new_tracee(pid_t pid) + tracee->vpid = next_vpid++; + + LIST_INSERT_HEAD(&tracees, tracee, link); ++ LIST_INSERT_HEAD(bucket_of(pid), tracee, bucket_link); + + tracee->life_context = talloc_new(tracee); + +@@ -327,7 +339,7 @@ Tracee *get_tracee(const Tracee *current_tracee, pid_t pid, bool create) + if (current_tracee != NULL && current_tracee->pid == pid) + return (Tracee *)current_tracee; + +- LIST_FOREACH(tracee, &tracees, link) { ++ LIST_FOREACH(tracee, bucket_of(pid), bucket_link) { + if (tracee->pid == pid) { + /* Flush then allocate a new memory collector. */ + TALLOC_FREE(tracee->ctx); +@@ -340,12 +352,20 @@ Tracee *get_tracee(const Tracee *current_tracee, pid_t pid, bool create) + return (create ? new_tracee(pid) : NULL); + } + ++void set_tracee_pid(Tracee *tracee, pid_t pid) ++{ ++ tracee->pid = pid; ++ LIST_REMOVE(tracee, bucket_link); ++ LIST_INSERT_HEAD(bucket_of(pid), tracee, bucket_link); ++} ++ + /** + * Mark tracee as terminated and optionally take action. + */ + void terminate_tracee(Tracee *tracee) + { + tracee->terminated = true; ++ terminations_pending = true; + + /* Case where the terminated tracee is marked + to kill all tracees on exit. +@@ -363,6 +383,10 @@ void free_terminated_tracees() + { + Tracee *next; + ++ if (!terminations_pending) ++ return; ++ terminations_pending = false; ++ + /* Items can't be deleted when using LIST_FOREACH. */ + next = tracees.lh_first; + while (next != NULL) { +diff --git a/src/tracee/tracee.h b/src/tracee/tracee.h +index 3dcbc7b..e4be3ff 100644 +--- a/src/tracee/tracee.h ++++ b/src/tracee/tracee.h +@@ -79,6 +79,7 @@ typedef struct tracee { + + /* Link for the list of all tracees. */ + LIST_ENTRY(tracee) link; ++ LIST_ENTRY(tracee) bucket_link; + + /* Process identifier. */ + pid_t pid; +@@ -300,6 +301,7 @@ typedef struct tracee { + #define TRACEE(a) talloc_get_type_abort(talloc_parent(talloc_parent(a)), Tracee) + + extern Tracee *get_tracee(const Tracee *tracee, pid_t pid, bool create); ++extern void set_tracee_pid(Tracee *tracee, pid_t pid); + extern Tracee *get_stopped_ptracee(const Tracee *ptracer, pid_t pid, + bool only_with_pevent, word_t wait_options); + extern bool has_ptracees(const Tracee *ptracer, pid_t pid, word_t wait_options); diff --git a/tools/proot/patches/0002-canon-resolve-parent-at-once.patch b/tools/proot/patches/0002-canon-resolve-parent-at-once.patch new file mode 100644 index 000000000..8965ba61f --- /dev/null +++ b/tools/proot/patches/0002-canon-resolve-parent-at-once.patch @@ -0,0 +1,198 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: maxjivi05 +Date: Wed, 23 Sep 2026 21:44:45 -0400 +Subject: [PATCH] canon: resolve a deep parent directory at once, and skip the + lstat of a final component that is not followed + +--- + src/path/canon.c | 94 +++++++++++++++++++++++++++++++++++++++++++-- + src/path/f2fs-bug.c | 7 +++- + src/path/f2fs-bug.h | 1 + + 3 files changed, 97 insertions(+), 5 deletions(-) + +diff --git a/src/path/canon.c b/src/path/canon.c +index 6c5d4c0..cabd0c0 100644 +--- a/src/path/canon.c ++++ b/src/path/canon.c +@@ -24,6 +24,7 @@ + #include /* PATH_MAX, */ + #include /* MAXSYMLINKS, */ + #include /* E*, */ ++#include + #include /* lstat(2), S_ISREG(), */ + #include /* access(2), lstat(2), */ + #include /* string(3), */ +@@ -133,7 +134,8 @@ static inline Finality next_component(char component[NAME_MAX], const char **cur + * (returned value is 1), otherwise it returns -errno (-ENOENT or + * -ENOTDIR). + */ +-static inline int substitute_binding_stat(Tracee *tracee, Finality finality, unsigned int recursion_level, ++static inline int substitute_binding_stat(Tracee *tracee, Finality finality, bool deref_final, ++ unsigned int recursion_level, + const char guest_path[PATH_MAX], char host_path[PATH_MAX]) + { + struct stat statl; +@@ -152,6 +154,9 @@ static inline int substitute_binding_stat(Tracee *tracee, Finality finality, uns + return status; + } + ++ if (finality == FINAL_NORMAL && !deref_final && tracee->glue_type == 0) ++ return 0; ++ + statl.st_mode = 0; + if (should_skip_file_access_due_to_f2fs_bug(tracee, host_path)) { + status = -ENOENT; +@@ -186,6 +191,87 @@ static inline int substitute_binding_stat(Tracee *tracee, Finality finality, uns + return (S_ISLNK(statl.st_mode) ? 1 : 0); + } + ++#define RESOLVE_AT_ONCE_MIN_DEPTH 3 ++ ++static size_t resolve_parent_at_once(Tracee *tracee, const char *user_path, ++ char guest_path[PATH_MAX]) ++{ ++ char parent[PATH_MAX]; ++ char expected[PATH_MAX]; ++ char resolved[PATH_MAX]; ++ char link[32]; ++ const Binding *binding; ++ const char *last; ++ const char *cursor; ++ size_t parent_length; ++ size_t prefix_length; ++ size_t expected_length; ++ ssize_t length; ++ int depth; ++ int fd; ++ ++ if (tracee->glue_type != 0 || f2fs_bug_workaround_active(tracee)) ++ return 0; ++ ++ last = strrchr(user_path, '/'); ++ if (last == NULL || last == user_path || last[1] == '\0' ++ || strcmp(last + 1, ".") == 0 || strcmp(last + 1, "..") == 0) ++ return 0; ++ ++ parent_length = last - user_path; ++ if (parent_length >= PATH_MAX) ++ return 0; ++ ++ depth = 0; ++ for (cursor = user_path; cursor < last; ) { ++ const char *end; ++ ++ end = memchr(cursor + 1, '/', last - cursor); ++ if (end == NULL) ++ end = last; ++ if (end == cursor + 1 ++ || (end == cursor + 2 && cursor[1] == '.') ++ || (end == cursor + 3 && cursor[1] == '.' && cursor[2] == '.')) ++ return 0; ++ depth++; ++ cursor = end; ++ } ++ if (depth < RESOLVE_AT_ONCE_MIN_DEPTH) ++ return 0; ++ ++ memcpy(parent, user_path, parent_length); ++ parent[parent_length] = '\0'; ++ ++ binding = get_binding(tracee, GUEST, parent); ++ if (binding == NULL || binding->guest.length != 1) ++ return 0; ++ ++ prefix_length = (binding->host.length == 1 ? 0 : binding->host.length); ++ expected_length = prefix_length + parent_length; ++ if (expected_length >= PATH_MAX) ++ return 0; ++ memcpy(expected, binding->host.path, prefix_length); ++ strcpy(expected + prefix_length, parent); ++ ++ fd = open(expected, O_PATH | O_DIRECTORY | O_CLOEXEC); ++ if (fd < 0) ++ return 0; ++ ++ snprintf(link, sizeof(link), "/proc/self/fd/%d", fd); ++ length = readlink(link, resolved, sizeof(resolved)); ++ close(fd); ++ ++ if (length < 0 || (size_t) length != expected_length ++ || memcmp(resolved, expected, expected_length) != 0) ++ return 0; ++ ++ if (notify_extensions(tracee, HOST_PATH, (intptr_t) expected, false) < 0) ++ return 0; ++ ++ strcpy(guest_path, parent); ++ return last + 1 - user_path; ++} ++ + /** + * Copy in @guest_path the canonicalization (see `man 3 realpath`) of + * @user_path regarding to @tracee->root. The path to canonicalize +@@ -227,6 +313,8 @@ int canonicalize(Tracee *tracee, const char *user_path, bool deref_final, + + /* Canonicalize recursely 'user_path' into 'guest_path'. */ + cursor = user_path; ++ if (user_path[0] == '/') ++ cursor += resolve_parent_at_once(tracee, user_path, guest_path); + finality = NOT_FINAL; + while (!IS_FINAL(finality)) { + Comparison comparison; +@@ -260,7 +348,7 @@ int canonicalize(Tracee *tracee, const char *user_path, bool deref_final, + * symlink. For this latter case, we check that the + * symlink points to a directory once it is + * canonicalized, at the end of this loop. */ +- status = substitute_binding_stat(tracee, finality, recursion_level, scratch_path, host_path); ++ status = substitute_binding_stat(tracee, finality, deref_final, recursion_level, scratch_path, host_path); + if (status < 0) + return status; + +@@ -338,7 +426,7 @@ int canonicalize(Tracee *tracee, const char *user_path, bool deref_final, + + /* Check that a non-final canonicalized/dereferenced + * symlink exists and is a directory. */ +- status = substitute_binding_stat(tracee, finality, recursion_level, guest_path, host_path); ++ status = substitute_binding_stat(tracee, finality, deref_final, recursion_level, guest_path, host_path); + if (status < 0) + return status; + +diff --git a/src/path/f2fs-bug.c b/src/path/f2fs-bug.c +index 4a5ee45..e4bddb9 100644 +--- a/src/path/f2fs-bug.c ++++ b/src/path/f2fs-bug.c +@@ -113,7 +113,7 @@ end: + return result; + } + +-bool should_skip_file_access_due_to_f2fs_bug(const Tracee *tracee, const char *path) { ++bool f2fs_bug_workaround_active(const Tracee *tracee) { + /* On first call check if workaround should be enabled */ + static bool f2fs_bug_probed; + static bool f2fs_bug_detected; +@@ -130,9 +130,12 @@ bool should_skip_file_access_due_to_f2fs_bug(const Tracee *tracee, const char *p + } + f2fs_bug_probed = true; + } ++ return f2fs_bug_detected; ++} + ++bool should_skip_file_access_due_to_f2fs_bug(const Tracee *tracee, const char *path) { + /* If workaround is not active don't skip access to file */ +- if (!f2fs_bug_detected) { ++ if (!f2fs_bug_workaround_active(tracee)) { + return false; + } + +diff --git a/src/path/f2fs-bug.h b/src/path/f2fs-bug.h +index b8eabdf..360f149 100644 +--- a/src/path/f2fs-bug.h ++++ b/src/path/f2fs-bug.h +@@ -4,6 +4,7 @@ + #include /* bool, true, false, */ + #include "tracee/tracee.h" /* Tracee, */ + ++bool f2fs_bug_workaround_active(const Tracee *tracee); + bool should_skip_file_access_due_to_f2fs_bug(const Tracee *tracee, const char *path); + + #endif /* F2FS_BUG_H */ diff --git a/tools/proot/patches/0003-clone3-flags-read-guard.patch b/tools/proot/patches/0003-clone3-flags-read-guard.patch new file mode 100644 index 000000000..773297951 --- /dev/null +++ b/tools/proot/patches/0003-clone3-flags-read-guard.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: maxjivi05 +Date: Wed, 23 Sep 2026 21:44:45 -0400 +Subject: [PATCH] tracee: keep a thread's inherited clone flags when clone3's + arguments cannot be read + +--- + src/tracee/tracee.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/src/tracee/tracee.c b/src/tracee/tracee.c +index 90894a0..7c0c50c 100644 +--- a/src/tracee/tracee.c ++++ b/src/tracee/tracee.c +@@ -423,10 +423,11 @@ int new_child(Tracee *parent, word_t clone_flags) + status = fetch_regs(parent); + if (status >= 0 && get_sysnum(parent, CURRENT) == PR_clone) + clone_flags = peek_reg(parent, CURRENT, SYSARG_1); +- else if (status >= 0 && get_sysnum(parent, CURRENT) == PR_clone3) +- // Look at the first word of the clone_args structure, which +- // contains the usual clone flags. +- clone_flags = peek_word(parent, peek_reg(parent, CURRENT, SYSARG_1)); ++ else if (status >= 0 && get_sysnum(parent, CURRENT) == PR_clone3) { ++ word_t flags = peek_word(parent, peek_reg(parent, CURRENT, SYSARG_1)); ++ if (errno == 0) ++ clone_flags = flags; ++ } + + /* Get the pid of the parent's new child. */ + status = ptrace(PTRACE_GETEVENTMSG, parent->pid, NULL, &pid); diff --git a/tools/proot/source.env b/tools/proot/source.env new file mode 100644 index 000000000..1d705b893 --- /dev/null +++ b/tools/proot/source.env @@ -0,0 +1,4 @@ +PROOT_COMMIT=4dba3afbf3a63af89b4d9c1a59bf2bda10f4d10f +PROOT_SHA256=de94f648547d1b62431073b82dc99d56ef0ddcef6da022e0dfffe2bf661cc34e +TALLOC_VERSION=2.4.3 +TALLOC_SHA256=dc46c40b9f46bb34dd97fe41f548b0e8b247b77a918576733c528e83abd854dd diff --git a/tools/proot/talloc-config.h b/tools/proot/talloc-config.h new file mode 100644 index 000000000..ef7a805f1 --- /dev/null +++ b/tools/proot/talloc-config.h @@ -0,0 +1,34 @@ +#define TALLOC_BUILD_VERSION_MAJOR 2 +#define TALLOC_BUILD_VERSION_MINOR 4 +#define TALLOC_BUILD_VERSION_RELEASE 3 +#define HAVE_STDBOOL_H 1 +#define HAVE_BOOL 1 +#define HAVE_STDINT_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_STRING_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_UNISTD_H 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_DLFCN_H 1 +#define HAVE_STRNLEN 1 +#define HAVE_STRNDUP 1 +#define HAVE_STRLCPY 1 +#define HAVE_STRLCAT 1 +#define HAVE_USLEEP 1 +#define HAVE_VA_COPY 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_SNPRINTF 1 +#define HAVE_C99_VSNPRINTF 1 +#define HAVE_INTPTR_T 1 +#define HAVE_UINTPTR_T 1 +#define HAVE_PTRDIFF_T 1 +#define HAVE_SIG_ATOMIC_T_TYPE 1 +#define HAVE_ERRNO_DECL 1 +#define HAVE_MEMMOVE 1 +#define HAVE_CONSTRUCTOR_ATTRIBUTE 1 +#define HAVE_DESTRUCTOR_ATTRIBUTE 1 +#define HAVE_VISIBILITY_ATTR 1 +#define HAVE_FALLTHROUGH_ATTRIBUTE 1 +#define HAVE_SYS_AUXV_H 1 +#define HAVE_GETAUXVAL 1 diff --git a/tools/release/axml_rename.py b/tools/release/axml_rename.py index ec553a12c..92da2753a 100644 --- a/tools/release/axml_rename.py +++ b/tools/release/axml_rename.py @@ -20,7 +20,7 @@ def enc_len16(n): return struct.pack('> 16), n & 0xffff) def rewrite(axml, repl): - ftype, fhs, fsize = struct.unpack_from('