Unofficial GSI Android 13

https://sourceforge.net/projects/e-os/files/2.6-t-20241206-UNOFFICIAL-gsi_arm64/2.6-t-20241206-UNOFFICIAL-gsi_arm64.gz/download

3 Likes

Thanks for the GSI build.

I’ve just tested it on Samsung A31 and Samsung A21s.

It boots on both devices. All seems normal but internet connection doesn’t work. Even though it says connected to wifi and it recognizes LTE mobile network, browsers, apps and app stores couldn’t connect to the internet.

I turned off Advanaced Privacy and changed DNS in newtork settings but it didn’t help. Both mobile data and wifi can’t connect.

If anyone has any idea how to fix the internet connection, please share.

In the meantime, I will try this GSI on some other devices.

1 Like

rephone® (6/128 GB like Gigaset GS5 pro)
SoC: MediaTek Helio G85 - k69v1_64_k419
Stock Android 12 (A12) Kernel: 4.19.191
No custom recovery


2.6.3-t-UNOFFICIAL-gsi_arm64.img by @Colors

I’ve had the identical experience as @sethdot, which means no internet connection, although an active connection is shown in the settings.

@Colors, please stay tuned!

1 Like

A little update - after messing with settings, wifi is now fully working on Samsung A31. On Samsung A21s wifi still doesn’t work but I managed to get SIM card mobile date to work.

Unfortunately, I can’t provide feedback on what fixed it because I tried a lot of things and don’t know exactly what did it. I will write more detalis after recreating it again.

Supplement

I was also unable to establish a wired Internet connection with a NoName USB-C-to-RJ45 adapter, although it works perfectly with the GSI iode-5.8-20241214-arm64_ab_release.img by @iode.tech

1 Like

I will provide a 2.7 version the next days. My Samsung Tab A9+ wifi works properly… Android 14 may be more successful with the network stack.

1 Like

I found a solution for my device for the WiFi/Internet/Network problem described above:

a) Enable USB Debugging
b) Execute ADB Shell Command

adb shell settings put global restricted_networking_mode 0

c) Restart system

Now WLAN/Wi-Fi and also the wired LAN via NoName USB-C-to-RJ45 are working.

3 Likes

I can confirm that @Xxpsilon 's solution works. Thanks for sharing and for figuring it out so fast.

1 Like

Lenovo Tab M10 HD (TB-X505F)
SoC: Qualcomm Snapdragon 429
Stock Android 10 Kernel: 4.9.205
TWRP 3.7.0_11-0


:white_check_mark: works: lineage-20.0-20241118-UNOFFICIAL-arm64_bvN-vndklite by @AndyYan

:x: Does not boot: 2.6-t-20241206-UNOFFICIAL-gsi_arm64 by @Colors

The reboot first takes place in the Lenovo logo, then in the TWRP recovery, without the e-logo appearing once. A great pity. But today is not the end of the world, is it?

Hello, I have catalogued the changes needed for Android 14 here:

Before anything, the following additions to manifests are needed

  <project name="AndyCGYan/android_packages_apps_QcRilAm" path="packages/apps/QcRilAm" remote="github" revision="master" />
  <project name="TrebleDroid/vendor_hardware_overlay" path="vendor/hardware_overlay" remote="github" revision="pie" />
  <remove-project name="LineageOS/android_packages_apps_Camera2" />
  <remote name="gitlab" fetch="https://gitlab.com/" />
  <project name="TrebleDroid/vendor_interfaces" path="vendor/interfaces" remote="github" revision="android-14.0" />
  <project name="platform/prebuilts/vndk/v28" path="prebuilts/vndk/v28" remote="aosp" clone-depth="1" revision="204f1bad00aaf480ba33233f7b8c2ddaa03155dd" />
  <project name="phhusson/vendor_vndk-tests" path="vendor/vndk-tests" remote="github" revision="master" />

1: Duplicate sensor resolver

2: Applied GSI patches

3: GSI device files

4: Overlay for SystemUI elements
placed in vendor/hardware_overlay

5: Removed references to the following in hardware/lineage/compat/Android.bp:

prebuilt_libprotobuf-cpp-full-vendorcompat

prebuilt_libprotobuf-cpp-lite-vendorcompat

VNDK28 uses the prebuilt .so files.

6: In the vendor/hardware_overlay folder, delete Navbar and Trebleapp, they will cause breakage, Android has a default overlay manager that will handle it there is no need for Trebleapp

With this, your GSI should build and boot.

Successful repair of the WiFi/Internet/Network problem with:
adb shell settings put global restricted_networking_mode 0

Note: There is no search bar at the top of the settings

2 Likes

Hi @Colors /e/OS-T 2.7.x (A13) GSI would be very valuable because it can be used to degoogle older devices. A14 no longer runs on many older devices.

@Colors

For A14 you should use the following device configurations:

And use the following patches

If you do not use those trebledroid patches, It is not going to boot on MTK devices unless you’re planning on doing a dirty-port and not source building

The device configurations I linked you to will still work, but Phh’s device configurations allow for the GSI to be built for many different platforms and are more accurate

Specifically, the patch you need to use for MTK devices is:

From 0e3e58ee51ebf509fd662fe1146f723b185dd542 Mon Sep 17 00:00:00 2001
From: Pierre-Hugues Husson <phh@phh.me>
Date: Sat, 25 Nov 2023 08:15:28 -0500
Subject: [PATCH 09/14] Add MTK GED KPI support to fix broken Mediatek gpufreq

Mediatek GPU scheduler likes to have the timestamps of the frames to be
able to adjust DVFS.
Technically this isn't completely needed, because it looks like DVFS can
work once we started triggering /proc/ged. But now that the work is
done, let's do it completely.

In benchmarks on Poco X4 GT, before this patch result is 1500, after is
5700. If we disable the patch after enabling it without rebooting, it
goes to 5400. So looks like GED KPI thingy does try to do a bit more
than just standard DVFS.

Thanks @sarthakroy2002 for the help and support (other people helped as
well)
---
 libs/gui/Surface.cpp           | 202 +++++++++++++++++++++++++++++++++
 libs/gui/include/gui/Surface.h |   3 +
 2 files changed, 205 insertions(+)

diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 086544e48a..6e73c38a63 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -24,6 +24,9 @@
 #include <deque>
 #include <mutex>
 #include <thread>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
 
 #include <inttypes.h>
 
@@ -50,6 +53,9 @@
 #include <gui/LayerState.h>
 #include <private/gui/ComposerService.h>
 #include <private/gui/ComposerServiceAIDL.h>
+#include <android-base/properties.h>
+
+#include <binder/IPCThreadState.h>
 
 #include <com_android_graphics_libgui_flags.h>
 
@@ -76,6 +82,37 @@ bool isInterceptorRegistrationOp(int op) {
 }
 
 } // namespace
+  //
+#define GED_MAGIC 'g'
+#define GED_BRIDGE_COMMAND_GPU_TIMESTAMP      103
+#define GED_IOWR(INDEX)  _IOWR(GED_MAGIC, INDEX, GED_BRIDGE_PACKAGE)
+#define GED_BRIDGE_IO_GPU_TIMESTAMP \
+    GED_IOWR(GED_BRIDGE_COMMAND_GPU_TIMESTAMP)
+typedef struct _GED_BRIDGE_PACKAGE {
+    unsigned int ui32FunctionID;
+    int i32Size;
+    void *pvParamIn;
+    int i32InBufferSize;
+    void *pvParamOut;
+    int i32OutBufferSize;
+} GED_BRIDGE_PACKAGE;
+
+struct GED_BRIDGE_IN_GPU_TIMESTAMP {
+    int pid;
+    uint64_t ullWnd;
+    int32_t i32FrameID;
+    int fence_fd;
+    int QedBuffer_length;
+    int isSF;
+};
+
+struct GED_BRIDGE_OUT_GPU_TIMESTAMP {
+    int eError;
+    int is_ged_kpi_enabled;
+};
+
+static int doMtkGedKpi = -1;
+static int ged_fd = -1;
 
 Surface::Surface(const sp<IGraphicBufferProducer>& bufferProducer, bool controlledByApp,
                  const sp<IBinder>& surfaceControlHandle)
@@ -128,6 +165,47 @@ Surface::Surface(const sp<IGraphicBufferProducer>& bufferProducer, bool controll
     mSwapIntervalZero = false;
     mMaxBufferCount = NUM_BUFFER_SLOTS;
     mSurfaceControlHandle = surfaceControlHandle;
+
+    if (doMtkGedKpi == -1) {
+        doMtkGedKpi = android::base::GetIntProperty("persist.sys.phh.mtk_ged_kpi", 0);
+    }
+
+    if (ged_fd == -1 && doMtkGedKpi == 1) {
+        ALOGE("Opening ged");
+        ged_fd = open("/proc/ged", O_RDONLY);
+        ALOGE("Opening ged ret = %d", ged_fd);
+        {
+        struct GED_BRIDGE_IN_GPU_TIMESTAMP in = {
+            .pid = 0,
+            //.ullWnd = (uint64_t)(intptr_t)this,
+                .ullWnd = 0,
+                .i32FrameID = 0,
+            .fence_fd = 0,
+            .isSF = 0,
+            .QedBuffer_length = 0,
+        };
+        struct GED_BRIDGE_OUT_GPU_TIMESTAMP out;
+        memset(&in, 0, sizeof(in));
+        GED_BRIDGE_PACKAGE package = {
+            .ui32FunctionID = GED_BRIDGE_IO_GPU_TIMESTAMP,
+            .i32Size = sizeof(GED_BRIDGE_PACKAGE),
+            .pvParamIn = &in,
+            .i32InBufferSize = sizeof(in),
+            .pvParamOut = &out,
+            .i32OutBufferSize = sizeof(out),
+        };
+        if (ged_fd >= 0) {
+            int ret = ioctl(ged_fd, GED_BRIDGE_IO_GPU_TIMESTAMP, &package);
+            ALOGE("First null timestamp ioctl returned %d %d %d", ret, out.eError, out.is_ged_kpi_enabled);
+            if (out.is_ged_kpi_enabled != 1) {
+                ALOGE("is_ged_kpi_enabled reported disabled");
+                doMtkGedKpi = 0;
+            }
+        } else {
+            ALOGE("No /proc/ged");
+        }
+        }
+    }
 }
 
 Surface::~Surface() {
@@ -668,6 +746,36 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
         }
     }
 
+    if (mGraphicBufferProducer != nullptr && ged_fd >= 0) {
+        uint64_t uniqueId;
+        mGraphicBufferProducer->getUniqueId(&uniqueId);
+
+        const int32_t dupFenceFd = fence->isValid() ? fence->dup() : -1;
+
+        struct GED_BRIDGE_IN_GPU_TIMESTAMP in = {
+            .pid = mPid,
+            .ullWnd = uniqueId,
+            .i32FrameID = static_cast<int32_t>(reinterpret_cast<intptr_t>(gbuf->handle)) & 0x3fffffff,
+            .fence_fd = dupFenceFd,
+            .isSF = mIsSurfaceFlinger ? 1 : 0,
+            .QedBuffer_length = -2,
+        };
+        struct GED_BRIDGE_OUT_GPU_TIMESTAMP out;
+        memset(&out, 0, sizeof(out));
+        GED_BRIDGE_PACKAGE package = {
+            .ui32FunctionID = GED_BRIDGE_IO_GPU_TIMESTAMP,
+            .i32Size = sizeof(GED_BRIDGE_PACKAGE),
+            .pvParamIn = &in,
+            .i32InBufferSize = sizeof(in),
+            .pvParamOut = &out,
+            .i32OutBufferSize = sizeof(out),
+        };
+
+        int ret = ioctl(ged_fd, GED_BRIDGE_IO_GPU_TIMESTAMP, &package);
+        ALOGV("GPU timestamp ioctl returned %d %d %d %d", ret, out.eError, out.is_ged_kpi_enabled, in.i32FrameID);
+
+        close(dupFenceFd);
+    }
     if (fence->isValid()) {
         *fenceFd = fence->dup();
         if (*fenceFd == -1) {
@@ -1111,6 +1219,60 @@ void Surface::onBufferQueuedLocked(int slot, sp<Fence> fence,
     }
 
     mQueueBufferCondition.broadcast();
+    if (mGraphicBufferProducer != nullptr && ged_fd >= 0) {
+        sp<GraphicBuffer>& gbuf(mSlots[slot].buffer);
+        uint64_t uniqueId;
+        mGraphicBufferProducer->getUniqueId(&uniqueId);
+
+        const int32_t dupFenceFd = fence->isValid() ? fence->dup() : -1;
+        // onQueue
+        {
+            struct GED_BRIDGE_IN_GPU_TIMESTAMP in = {
+                .pid = mPid,
+                .ullWnd = uniqueId,
+                .i32FrameID = static_cast<int32_t>(reinterpret_cast<intptr_t>(gbuf->handle)) & 0x3fffffff,
+                .fence_fd = dupFenceFd,
+                .isSF = mIsSurfaceFlinger ? 1 : 0,
+                .QedBuffer_length = static_cast<int>(output.numPendingBuffers),
+            };
+            struct GED_BRIDGE_OUT_GPU_TIMESTAMP out;
+            memset(&out, 0, sizeof(out));
+            GED_BRIDGE_PACKAGE package = {
+                .ui32FunctionID = GED_BRIDGE_IO_GPU_TIMESTAMP,
+                .i32Size = sizeof(GED_BRIDGE_PACKAGE),
+                .pvParamIn = &in,
+                .i32InBufferSize = sizeof(in),
+                .pvParamOut = &out,
+                .i32OutBufferSize = sizeof(out),
+            };
+            int ret = ioctl(ged_fd, GED_BRIDGE_IO_GPU_TIMESTAMP, &package);
+            ALOGV("GPU timestamp ioctl returned %d %d %d", ret, out.eError, in.i32FrameID);
+        }
+        // acquire
+        {
+            struct GED_BRIDGE_IN_GPU_TIMESTAMP in = {
+                .pid = mPid,
+                .isSF = mIsSurfaceFlinger ? 1 : 0,
+                .ullWnd = uniqueId,
+                .i32FrameID = static_cast<int32_t>(reinterpret_cast<intptr_t>(gbuf->handle)) & 0x3fffffff,
+                .fence_fd = dupFenceFd,
+                .QedBuffer_length = -1,
+            };
+            struct GED_BRIDGE_OUT_GPU_TIMESTAMP out;
+            memset(&out, 0, sizeof(out));
+            GED_BRIDGE_PACKAGE package = {
+                .ui32FunctionID = GED_BRIDGE_IO_GPU_TIMESTAMP,
+                .i32Size = sizeof(GED_BRIDGE_PACKAGE),
+                .pvParamIn = &in,
+                .i32InBufferSize = sizeof(in),
+                .pvParamOut = &in,
+                .i32OutBufferSize = sizeof(out),
+            };
+            int ret = ioctl(ged_fd, GED_BRIDGE_IO_GPU_TIMESTAMP, &package);
+            ALOGV("GPU timestamp ioctl returned %d %d %d", ret, out.eError, in.i32FrameID);
+        }
+        close(dupFenceFd);
+    }
 
     if (CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))) {
         static gui::FenceMonitor gpuCompletionThread("GPU completion");
@@ -1878,6 +2040,46 @@ int Surface::connect(
 
         mConsumerRunningBehind = (output.numPendingBuffers >= 2);
     }
+
+    // For MTK GED KPI, we need to grab the Surface owner's PID
+    // and also know whether that owner is surfaceflinger
+    if (api == NATIVE_WINDOW_API_EGL && ged_fd >= 0) {
+        IPCThreadState *ipc = IPCThreadState::selfOrNull();
+        const sp<IBinder>& token = listener->asBinder(listener);
+        mPid =  (token != NULL && NULL != token->localBinder())
+            ? getpid()
+            : (ipc != nullptr)?ipc->getCallingPid():-1;
+
+        // We've got caller PID. Now checking whether it is surfaceflinger
+        char cmdline[128];
+        char path[128];
+        snprintf(path, sizeof(path)-1, "/proc/%d/cmdline", mPid);
+        int fd = open(path, O_RDONLY);
+        read(fd, cmdline, sizeof(cmdline)-1);
+        // Normally cmdline is already \0-separated, but well
+        for(unsigned i=0; i<sizeof(cmdline); i++)
+            if(cmdline[i] == '\n')
+                cmdline[i] = 0;
+        cmdline[sizeof(cmdline)-1] = 0;
+
+        close(fd);
+
+        // Truncate to last / (also called basename)
+        const char *c = strrchr(cmdline, '/');
+        if (c != nullptr) {
+            c = c+1;
+        } else {
+            c = cmdline;
+        }
+        if(strcmp(c, "surfaceflinger") == 0) {
+            ALOGE("is surfaceflinger = 1");
+            mIsSurfaceFlinger = true;
+        } else {
+            ALOGE("is surfaceflinger = 0");
+            mIsSurfaceFlinger = false;
+        }
+    }
+
     if (!err && api == NATIVE_WINDOW_API_CPU) {
         mConnectedToCpu = true;
         // Clear the dirty region in case we're switching from a non-CPU API
diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h
index 39a59e42aa..ff595dd188 100644
--- a/libs/gui/include/gui/Surface.h
+++ b/libs/gui/include/gui/Surface.h
@@ -638,6 +638,9 @@ protected:
 
     // Buffers that are successfully dequeued/attached and handed to clients
     std::unordered_set<int> mDequeuedSlots;
+
+    pid_t mPid;
+    bool mIsSurfaceFlinger;
 };
 
 } // namespace android
-- 
2.34.1

Lenovo Smart Tab M10 HD TB-X306F
SoC: Mediatek MT6762 Helio P22T
Stock Android 11 (A11) Kernel: 4.19.127
No custom recovery


:white_check_mark: working ~ 2.6.3-t-UNOFFICIAL-gsi_arm64 by @colors

Successful repair of the WiFi/Internet/Network problem with:
adb shell settings put global restricted_networking_mode 0

2.7 gsi android 13… Thanks to Null for the hint (app button)! I will build on the existing source tree as a reference for 2.7- U version build from Null.
Today… in the evening. Thank you Xxpsilon for the special effort made to complete this gsi build. Thank you Null and everyone involved. My contribution is just meteoric as a personal necessity.
Next week i will rewamp the source tree to have more treble conformity.

3 Likes

Let me give you a new source tree, this has support for MTK devices built in:

This can also build for all other devices in the architecture as well, just make sure to add to each device file template the following:

Namespace fix:

# Soong namespaces
PRODUCT_SOONG_NAMESPACES += $(DEVICE_PATH)

To use it invoke

breakfast treble_arm64_bvN

This targets A/B devices, but any of the other make files can be modified in this way for their respective architecture, Phh did a really good job.

This is what I’m presently building with, it is a little more complete than the previous device tree.

Thank you for doing the treble bring-up @colors you’re a fantastic developer

GSI 2.7-t version

https://sourceforge.net/projects/e-os/files/GSI/2.7-t-UNOFFICIAL-gsi_arm64.img.xz/download

Thanks to Null the Switch App button has regained functionality.

3 Likes

It takes me back to developing MIUI in the past when you had to straight up decompile apks in order to export system functionality into forked firmware and I don’t mean that in a good way, hoping that the developers of /e/OS don’t do this in Android 15 or later revisions of the operating system because it sets a bad precedent

I do not know exactly where to look for the search bar in Settings. Can be packages/apps/SettingsIntelligence/res/values…

I’ll check for you, I didn’t have a problem with the search bar in Android 14 bring up; I feel that in 13 it is in framework-res.apk though; when I get going for the day I will look through it to see where it is stored in Android 13

The eOS developers seem to be exporting all the app related values to framework