Don't pass calling contexts into static services.
When initializing a service, StaticOuterContextServiceFetcher passes the calling context to it. This causes a leak if the service stores the context in a static variable. Instead, pass in the application context, which will never be freed for the life of the application, and correspondingly rename StaticOuterContextServiceFetcher to StaticApplicationContextServiceFetcher. Bug: 27147995 Change-Id: Ic67ebc32df7368184c2935f0327491fdc7d69836
This commit is contained in:
@@ -226,7 +226,7 @@ final class SystemServiceRegistry {
|
||||
SYSTEM_SERVICE_NAMES.put(android.text.ClipboardManager.class, Context.CLIPBOARD_SERVICE);
|
||||
|
||||
registerService(Context.CONNECTIVITY_SERVICE, ConnectivityManager.class,
|
||||
new StaticOuterContextServiceFetcher<ConnectivityManager>() {
|
||||
new StaticApplicationContextServiceFetcher<ConnectivityManager>() {
|
||||
@Override
|
||||
public ConnectivityManager createService(Context context) {
|
||||
IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
|
||||
@@ -840,22 +840,21 @@ final class SystemServiceRegistry {
|
||||
}
|
||||
|
||||
/**
|
||||
* Like StaticServiceFetcher, creates only one instance of the service per process, but when
|
||||
* creating the service for the first time, passes it the outer context of the creating
|
||||
* component.
|
||||
* Like StaticServiceFetcher, creates only one instance of the service per application, but when
|
||||
* creating the service for the first time, passes it the application context of the creating
|
||||
* application.
|
||||
*
|
||||
* TODO: Is this safe in the case where multiple applications share the same process?
|
||||
* TODO: Delete this once its only user (ConnectivityManager) is known to work well in the
|
||||
* case where multiple application components each have their own ConnectivityManager object.
|
||||
*/
|
||||
static abstract class StaticOuterContextServiceFetcher<T> implements ServiceFetcher<T> {
|
||||
static abstract class StaticApplicationContextServiceFetcher<T> implements ServiceFetcher<T> {
|
||||
private T mCachedInstance;
|
||||
|
||||
@Override
|
||||
public final T getService(ContextImpl ctx) {
|
||||
synchronized (StaticOuterContextServiceFetcher.this) {
|
||||
synchronized (StaticApplicationContextServiceFetcher.this) {
|
||||
if (mCachedInstance == null) {
|
||||
mCachedInstance = createService(ctx.getOuterContext());
|
||||
mCachedInstance = createService(ctx.getApplicationContext());
|
||||
}
|
||||
return mCachedInstance;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user