From 2b845680b0d8d6778600d3c46a570d73dc83e2b5 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Sun, 24 Nov 2019 11:58:40 +0100 Subject: [PATCH] Initialize Application object to avoid NPE When an ApplicationInfo is set (commit 90293240cc622bb58cb1de741f86cbc0889c03e8), some devices (Nvidia Shield TV) attempt to access the Application object, causing a NullPointerException. As a workaround, initialize an Application object. Fixes --- .../java/com/genymobile/scrcpy/Workarounds.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/server/src/main/java/com/genymobile/scrcpy/Workarounds.java b/server/src/main/java/com/genymobile/scrcpy/Workarounds.java index ccfe5370..b1b81903 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Workarounds.java +++ b/server/src/main/java/com/genymobile/scrcpy/Workarounds.java @@ -1,11 +1,15 @@ package com.genymobile.scrcpy; import android.annotation.SuppressLint; +import android.app.Application; +import android.app.Instrumentation; +import android.content.Context; import android.content.pm.ApplicationInfo; import android.os.Looper; import java.lang.reflect.Constructor; import java.lang.reflect.Field; +import java.lang.reflect.Method; public final class Workarounds { private Workarounds() { @@ -56,6 +60,17 @@ public final class Workarounds { Field mBoundApplicationField = activityThreadClass.getDeclaredField("mBoundApplication"); mBoundApplicationField.setAccessible(true); mBoundApplicationField.set(activityThread, appBindData); + + // Context ctx = activityThread.getSystemContext(); + Method getSystemContextMethod = activityThreadClass.getDeclaredMethod("getSystemContext"); + Context ctx = (Context) getSystemContextMethod.invoke(activityThread); + + Application app = Instrumentation.newApplication(Application.class, ctx); + + // activityThread.mInitialApplication = app; + Field mInitialApplicationField = activityThreadClass.getDeclaredField("mInitialApplication"); + mInitialApplicationField.setAccessible(true); + mInitialApplicationField.set(activityThread, app); } catch (Throwable throwable) { // this is a workaround, so failing is not an error Ln.w("Could not fill app info: " + throwable.getMessage());