Fix memory leaks in Settings

Bug: 80507279
Test: inspected hprof before and after fix
Change-Id: I6ea2925695deb6261263649e858484e1667ec522
This commit is contained in:
Fan Zhang
2018-06-07 11:33:48 -07:00
parent 7bc2f98188
commit 838f6c7812
4 changed files with 40 additions and 31 deletions

View File

@@ -24,18 +24,12 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.os.BatteryStats; import android.os.BatteryStats;
import android.os.Bundle;
import android.os.Build; import android.os.Build;
import android.os.Bundle;
import android.os.Process; import android.os.Process;
import android.os.SystemClock; import android.os.SystemClock;
import android.os.UserHandle; import android.os.UserHandle;
import android.os.UserManager; import android.os.UserManager;
import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.annotation.VisibleForTesting;
import androidx.annotation.WorkerThread;
import android.text.TextUtils;
import android.text.format.DateUtils; import android.text.format.DateUtils;
import android.util.Log; import android.util.Log;
import android.util.SparseLongArray; import android.util.SparseLongArray;
@@ -48,7 +42,6 @@ import com.android.settings.fuelgauge.anomaly.Anomaly;
import com.android.settings.fuelgauge.batterytip.AnomalyInfo; import com.android.settings.fuelgauge.batterytip.AnomalyInfo;
import com.android.settings.fuelgauge.batterytip.StatsManagerConfig; import com.android.settings.fuelgauge.batterytip.StatsManagerConfig;
import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.fuelgauge.PowerWhitelistBackend; import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
import com.android.settingslib.utils.PowerUtil; import com.android.settingslib.utils.PowerUtil;
@@ -58,6 +51,12 @@ import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.annotation.VisibleForTesting;
import androidx.annotation.WorkerThread;
/** /**
* Utils for battery operation * Utils for battery operation
*/ */
@@ -93,14 +92,14 @@ public class BatteryUtils {
public static BatteryUtils getInstance(Context context) { public static BatteryUtils getInstance(Context context) {
if (sInstance == null || sInstance.isDataCorrupted()) { if (sInstance == null || sInstance.isDataCorrupted()) {
sInstance = new BatteryUtils(context); sInstance = new BatteryUtils(context.getApplicationContext());
} }
return sInstance; return sInstance;
} }
@VisibleForTesting @VisibleForTesting
BatteryUtils(Context context) { BatteryUtils(Context context) {
mContext = context.getApplicationContext(); mContext = context;
mPackageManager = context.getPackageManager(); mPackageManager = context.getPackageManager();
mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
mPowerUsageFeatureProvider = FeatureFactory.getFactory( mPowerUsageFeatureProvider = FeatureFactory.getFactory(

View File

@@ -21,7 +21,6 @@ import android.app.admin.DevicePolicyManager;
import android.content.Context; import android.content.Context;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.os.UserManager; import android.os.UserManager;
import androidx.annotation.Keep;
import com.android.settings.accounts.AccountFeatureProvider; import com.android.settings.accounts.AccountFeatureProvider;
import com.android.settings.accounts.AccountFeatureProviderImpl; import com.android.settings.accounts.AccountFeatureProviderImpl;
@@ -54,6 +53,8 @@ import com.android.settings.users.UserFeatureProvider;
import com.android.settings.users.UserFeatureProviderImpl; import com.android.settings.users.UserFeatureProviderImpl;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import androidx.annotation.Keep;
/** /**
* {@link FeatureFactory} implementation for AOSP Settings. * {@link FeatureFactory} implementation for AOSP Settings.
*/ */
@@ -93,7 +94,8 @@ public class FeatureFactoryImpl extends FeatureFactory {
@Override @Override
public PowerUsageFeatureProvider getPowerUsageFeatureProvider(Context context) { public PowerUsageFeatureProvider getPowerUsageFeatureProvider(Context context) {
if (mPowerUsageFeatureProvider == null) { if (mPowerUsageFeatureProvider == null) {
mPowerUsageFeatureProvider = new PowerUsageFeatureProviderImpl(context); mPowerUsageFeatureProvider = new PowerUsageFeatureProviderImpl(
context.getApplicationContext());
} }
return mPowerUsageFeatureProvider; return mPowerUsageFeatureProvider;
} }
@@ -101,7 +103,8 @@ public class FeatureFactoryImpl extends FeatureFactory {
@Override @Override
public DashboardFeatureProvider getDashboardFeatureProvider(Context context) { public DashboardFeatureProvider getDashboardFeatureProvider(Context context) {
if (mDashboardFeatureProvider == null) { if (mDashboardFeatureProvider == null) {
mDashboardFeatureProvider = new DashboardFeatureProviderImpl(context); mDashboardFeatureProvider = new DashboardFeatureProviderImpl(
context.getApplicationContext());
} }
return mDashboardFeatureProvider; return mDashboardFeatureProvider;
} }
@@ -117,10 +120,11 @@ public class FeatureFactoryImpl extends FeatureFactory {
@Override @Override
public ApplicationFeatureProvider getApplicationFeatureProvider(Context context) { public ApplicationFeatureProvider getApplicationFeatureProvider(Context context) {
if (mApplicationFeatureProvider == null) { if (mApplicationFeatureProvider == null) {
mApplicationFeatureProvider = new ApplicationFeatureProviderImpl(context, final Context appContext = context.getApplicationContext();
context.getPackageManager(), mApplicationFeatureProvider = new ApplicationFeatureProviderImpl(appContext,
appContext.getPackageManager(),
AppGlobals.getPackageManager(), AppGlobals.getPackageManager(),
(DevicePolicyManager) context (DevicePolicyManager) appContext
.getSystemService(Context.DEVICE_POLICY_SERVICE)); .getSystemService(Context.DEVICE_POLICY_SERVICE));
} }
return mApplicationFeatureProvider; return mApplicationFeatureProvider;
@@ -137,12 +141,14 @@ public class FeatureFactoryImpl extends FeatureFactory {
@Override @Override
public EnterprisePrivacyFeatureProvider getEnterprisePrivacyFeatureProvider(Context context) { public EnterprisePrivacyFeatureProvider getEnterprisePrivacyFeatureProvider(Context context) {
if (mEnterprisePrivacyFeatureProvider == null) { if (mEnterprisePrivacyFeatureProvider == null) {
mEnterprisePrivacyFeatureProvider = new EnterprisePrivacyFeatureProviderImpl(context, final Context appContext = context.getApplicationContext();
(DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE), mEnterprisePrivacyFeatureProvider = new EnterprisePrivacyFeatureProviderImpl(appContext,
context.getPackageManager(), (DevicePolicyManager) appContext.getSystemService(
UserManager.get(context), Context.DEVICE_POLICY_SERVICE),
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE), appContext.getPackageManager(),
context.getResources()); UserManager.get(appContext),
(ConnectivityManager) appContext.getSystemService(Context.CONNECTIVITY_SERVICE),
appContext.getResources());
} }
return mEnterprisePrivacyFeatureProvider; return mEnterprisePrivacyFeatureProvider;
} }
@@ -171,7 +177,8 @@ public class FeatureFactoryImpl extends FeatureFactory {
@Override @Override
public SuggestionFeatureProvider getSuggestionFeatureProvider(Context context) { public SuggestionFeatureProvider getSuggestionFeatureProvider(Context context) {
if (mSuggestionFeatureProvider == null) { if (mSuggestionFeatureProvider == null) {
mSuggestionFeatureProvider = new SuggestionFeatureProviderImpl(context); mSuggestionFeatureProvider = new SuggestionFeatureProviderImpl(
context.getApplicationContext());
} }
return mSuggestionFeatureProvider; return mSuggestionFeatureProvider;
} }
@@ -179,7 +186,7 @@ public class FeatureFactoryImpl extends FeatureFactory {
@Override @Override
public UserFeatureProvider getUserFeatureProvider(Context context) { public UserFeatureProvider getUserFeatureProvider(Context context) {
if (mUserFeatureProvider == null) { if (mUserFeatureProvider == null) {
mUserFeatureProvider = new UserFeatureProviderImpl(context); mUserFeatureProvider = new UserFeatureProviderImpl(context.getApplicationContext());
} }
return mUserFeatureProvider; return mUserFeatureProvider;
} }

View File

@@ -37,9 +37,6 @@ import android.media.MediaRouter;
import android.media.MediaRouter.Callback; import android.media.MediaRouter.Callback;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.FeatureFlagUtils; import android.util.FeatureFlagUtils;
import android.util.Log; import android.util.Log;
@@ -64,6 +61,10 @@ import java.util.List;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask; import java.util.concurrent.FutureTask;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
/** /**
* Abstract class for audio switcher controller to notify subclass * Abstract class for audio switcher controller to notify subclass
* updating the current status of switcher entry. Subclasses must overwrite * updating the current status of switcher entry. Subclasses must overwrite
@@ -74,7 +75,7 @@ public abstract class AudioSwitchPreferenceController extends BasePreferenceCont
implements Preference.OnPreferenceChangeListener, BluetoothCallback, implements Preference.OnPreferenceChangeListener, BluetoothCallback,
LifecycleObserver, OnStart, OnStop { LifecycleObserver, OnStart, OnStop {
private static final String TAG = "AudioSwitchPreferenceController"; private static final String TAG = "AudioSwitchPrefCtrl";
private static final int INVALID_INDEX = -1; private static final int INVALID_INDEX = -1;
protected final List<BluetoothDevice> mConnectedDevices; protected final List<BluetoothDevice> mConnectedDevices;

View File

@@ -32,7 +32,6 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Build; import android.os.Build;
import android.os.UserManager; import android.os.UserManager;
import androidx.preference.Preference;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.FakeFeatureFactory;
@@ -50,6 +49,8 @@ import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment; import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
import androidx.preference.Preference;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
@Config(shadows = {SettingsShadowResources.SettingsShadowTheme.class, ShadowFragment.class}) @Config(shadows = {SettingsShadowResources.SettingsShadowTheme.class, ShadowFragment.class})
public class BackgroundActivityPreferenceControllerTest { public class BackgroundActivityPreferenceControllerTest {
@@ -89,6 +90,7 @@ public class BackgroundActivityPreferenceControllerTest {
mShadowContext = RuntimeEnvironment.application; mShadowContext = RuntimeEnvironment.application;
FakeFeatureFactory.setupForTest(); FakeFeatureFactory.setupForTest();
when(mContext.getApplicationContext()).thenReturn(mContext);
when(mContext.getPackageManager()).thenReturn(mPackageManager); when(mContext.getPackageManager()).thenReturn(mPackageManager);
when(mContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager); when(mContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager);
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager); when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
@@ -118,7 +120,7 @@ public class BackgroundActivityPreferenceControllerTest {
@Test @Test
public void testHandlePreferenceTreeClick_restrictApp_showDialog() { public void testHandlePreferenceTreeClick_restrictApp_showDialog() {
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager) doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
.checkOpNoThrow(anyInt(), anyInt(), anyString()); .checkOpNoThrow(anyInt(), anyInt(), anyString());
mController.handlePreferenceTreeClick(mPreference); mController.handlePreferenceTreeClick(mPreference);
@@ -128,7 +130,7 @@ public class BackgroundActivityPreferenceControllerTest {
@Test @Test
public void testHandlePreferenceTreeClick_unRestrictApp_showDialog() { public void testHandlePreferenceTreeClick_unRestrictApp_showDialog() {
doReturn(AppOpsManager.MODE_IGNORED).when(mAppOpsManager) doReturn(AppOpsManager.MODE_IGNORED).when(mAppOpsManager)
.checkOpNoThrow(anyInt(), anyInt(), anyString()); .checkOpNoThrow(anyInt(), anyInt(), anyString());
mController.handlePreferenceTreeClick(mPreference); mController.handlePreferenceTreeClick(mPreference);