From c5767a01453f6ca4713b18c3bd860eefc361fbc3 Mon Sep 17 00:00:00 2001 From: Dmitry Muhomor Date: Wed, 5 Jun 2024 23:17:58 +0300 Subject: [PATCH] gmscompat: adjust to DynamiteLoader changes in GmsCore 24.22 APKs of Dynamite modules are now opened via ParcelFileDescriptor.open(). --- .../java/android/os/ParcelFileDescriptor.java | 10 +++++++ .../dynamite/GmsDynamiteClientHooks.java | 26 ++++++++++++++++--- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java index 93d508292c7f..7126c8d667f7 100644 --- a/core/java/android/os/ParcelFileDescriptor.java +++ b/core/java/android/os/ParcelFileDescriptor.java @@ -47,6 +47,8 @@ import android.util.Log; import android.util.Slog; +import com.android.internal.gmscompat.dynamite.GmsDynamiteClientHooks; + import dalvik.system.CloseGuard; import dalvik.system.VMRuntime; @@ -345,6 +347,14 @@ private static FileDescriptor openInternal(File file, int mode) throws FileNotFo if ((mode & MODE_WORLD_WRITEABLE) != 0) realMode |= S_IWOTH; final String path = file.getPath(); + + if (GmsDynamiteClientHooks.enabled()) { + FileDescriptor override = GmsDynamiteClientHooks.openFileDescriptor(path); + if (override != null) { + return override; + } + } + try { return Os.open(path, flags, realMode); } catch (ErrnoException e) { diff --git a/core/java/com/android/internal/gmscompat/dynamite/GmsDynamiteClientHooks.java b/core/java/com/android/internal/gmscompat/dynamite/GmsDynamiteClientHooks.java index 099adab2357e..d06dc4f166e2 100644 --- a/core/java/com/android/internal/gmscompat/dynamite/GmsDynamiteClientHooks.java +++ b/core/java/com/android/internal/gmscompat/dynamite/GmsDynamiteClientHooks.java @@ -17,13 +17,13 @@ package com.android.internal.gmscompat.dynamite; import android.app.compat.gms.GmsCompat; -import android.content.Context; import android.content.res.ApkAssets; import android.content.res.loader.AssetsProvider; import android.os.Environment; -import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.os.RemoteException; +import android.system.ErrnoException; +import android.system.Os; import android.util.ArrayMap; import android.util.Log; @@ -38,6 +38,8 @@ import dalvik.system.DelegateLastClassLoader; +import static android.system.OsConstants.F_DUPFD_CLOEXEC; + public final class GmsDynamiteClientHooks { static final String TAG = "GmsCompat/DynamiteClient"; private static final boolean DEBUG = false; @@ -127,6 +129,24 @@ public static long getFileLastModified(File file) { return 0L; } + public static FileDescriptor openFileDescriptor(String path) { + if (!path.startsWith(gmsCoreDataPrefix)) { + return null; + } + + FileDescriptor fd = modulePathToFd(path); + int dupFd; + try { + dupFd = Os.fcntlInt(fd, F_DUPFD_CLOEXEC, 0); + } catch (ErrnoException e) { + throw new RuntimeException(e); + } + + var dupJfd = new FileDescriptor(); + dupJfd.setInt$(dupFd); + return dupJfd; + } + // Replaces file paths of Dynamite modules with "/proc/self/fd" file descriptor references // DelegateLastClassLoader#maybeModifyClassLoaderPath(String, Boolean) public static String maybeModifyClassLoaderPath(String path, Boolean nativeLibsPathB) { @@ -175,7 +195,7 @@ public static String maybeModifyClassLoaderPath(String path, Boolean nativeLibsP // Returned file descriptor should never be closed, because it may be dup()-ed at any time by the native code private static FileDescriptor modulePathToFd(String path) { if (DEBUG) { - new Exception("path " + path).printStackTrace(); + Log.d(TAG, "path " + path, new Throwable()); } try { ArrayMap cache = pfdCache;