Use a weak reference to the context in InputManager
It has been reported that a recent change to InputManager is
causing a memory leak. We were already planning to change it in a
way that this issue would no longer happen, but since it's a
refactor that will take some time, this is a temporary solution
that Prabir suggested; if we keep a weak reference to the context,
it will be freed when there is no other active references.
Bug: 267241786
Test: will ask for a test run of this change
Change-Id: I7e894ba1f014bba36f6ea2566b11426d17d84f68
(cherry picked from commit d87354712e)
Merged-In: I7e894ba1f014bba36f6ea2566b11426d17d84f68
This commit is contained in:
committed by
Cherrypicker Worker
parent
74efadf738
commit
71feb32d93
@@ -74,6 +74,7 @@ import com.android.internal.os.SomeArgs;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -99,13 +100,12 @@ public final class InputManager {
|
||||
private final IInputManager mIm;
|
||||
|
||||
/**
|
||||
* InputManager has historically used its own static getter {@link #getInstance()} that doesn't
|
||||
* provide a context. We provide a Context to the InputManager instance through the
|
||||
* {@link android.app.SystemServiceRegistry}. Methods that need a Context must use
|
||||
* {@link #getContext()} to obtain it.
|
||||
* We hold a weak reference to the context to avoid leaking it indefinitely,
|
||||
* since we currently store the input manager instance as a static variable that
|
||||
* will outlive any context.
|
||||
*/
|
||||
@Nullable
|
||||
private Context mLateInitContext;
|
||||
private WeakReference<Context> mWeakContext;
|
||||
|
||||
/**
|
||||
* Whether a PointerIcon is shown for stylus pointers.
|
||||
@@ -372,8 +372,8 @@ public final class InputManager {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
if (sInstance.mLateInitContext == null) {
|
||||
sInstance.mLateInitContext = context;
|
||||
if (sInstance.mWeakContext == null || sInstance.mWeakContext.get() == null) {
|
||||
sInstance.mWeakContext = new WeakReference(context);
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
@@ -381,9 +381,14 @@ public final class InputManager {
|
||||
|
||||
@NonNull
|
||||
private Context getContext() {
|
||||
return Objects.requireNonNull(mLateInitContext,
|
||||
WeakReference<Context> weakContext = Objects.requireNonNull(mWeakContext,
|
||||
"A context is required for InputManager. Get the InputManager instance using "
|
||||
+ "Context#getSystemService before calling this method.");
|
||||
// If we get at this point, an app calling this function could potentially expect a
|
||||
// Context that has disappeared due to garbage collection. Holding a weak reference
|
||||
// is a temporary solution that should be resolved before the release of a
|
||||
// production version. This is being tracked in b/267758905
|
||||
return Objects.requireNonNull(weakContext.get(), "missing Context");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user