Only initialize PermissionUsageHelper lazily or when requested

This fixes a memory leak caused by automatically registering a
PermissionUsageHelper on PermissionManager instantiation.

Bug: 204222680
Test: manual
Change-Id: I94c6da3dd89e8b158552e94c94e4d0fb3f5d6f0d
This commit is contained in:
Nate Myren
2021-10-29 12:39:52 -07:00
parent 88ba7c8f90
commit 338cafab6c
3 changed files with 35 additions and 7 deletions

View File

@@ -180,8 +180,6 @@ public final class PermissionManager {
mPermissionManager = IPermissionManager.Stub.asInterface(ServiceManager.getServiceOrThrow( mPermissionManager = IPermissionManager.Stub.asInterface(ServiceManager.getServiceOrThrow(
"permissionmgr")); "permissionmgr"));
mLegacyPermissionManager = context.getSystemService(LegacyPermissionManager.class); mLegacyPermissionManager = context.getSystemService(LegacyPermissionManager.class);
//TODO ntmyren: there should be a way to only enable the watcher when requested
mUsageHelper = new PermissionUsageHelper(context);
} }
/** /**
@@ -955,6 +953,29 @@ public final class PermissionManager {
return mSplitPermissionInfos; return mSplitPermissionInfos;
} }
/**
* Initialize the PermissionUsageHelper, which will register active app op listeners
*
* @hide
*/
public void initializeUsageHelper() {
if (mUsageHelper == null) {
mUsageHelper = new PermissionUsageHelper(mContext);
}
}
/**
* Teardown the PermissionUsageHelper, removing listeners
*
* @hide
*/
public void tearDownUsageHelper() {
if (mUsageHelper != null) {
mUsageHelper.tearDown();
mUsageHelper = null;
}
}
/** /**
* @return A list of permission groups currently or recently used by all apps by all users in * @return A list of permission groups currently or recently used by all apps by all users in
* the current profile group. * the current profile group.
@@ -965,7 +986,7 @@ public final class PermissionManager {
@NonNull @NonNull
@RequiresPermission(Manifest.permission.GET_APP_OPS_STATS) @RequiresPermission(Manifest.permission.GET_APP_OPS_STATS)
public List<PermGroupUsage> getIndicatorAppOpUsageData() { public List<PermGroupUsage> getIndicatorAppOpUsageData() {
return mUsageHelper.getOpUsageData(new AudioManager().isMicrophoneMute()); return getIndicatorAppOpUsageData(new AudioManager().isMicrophoneMute());
} }
/** /**
@@ -980,9 +1001,7 @@ public final class PermissionManager {
@RequiresPermission(Manifest.permission.GET_APP_OPS_STATS) @RequiresPermission(Manifest.permission.GET_APP_OPS_STATS)
public List<PermGroupUsage> getIndicatorAppOpUsageData(boolean micMuted) { public List<PermGroupUsage> getIndicatorAppOpUsageData(boolean micMuted) {
// Lazily initialize the usage helper // Lazily initialize the usage helper
if (mUsageHelper == null) { initializeUsageHelper();
mUsageHelper = new PermissionUsageHelper(mContext);
}
return mUsageHelper.getOpUsageData(micMuted); return mUsageHelper.getOpUsageData(micMuted);
} }

View File

@@ -176,6 +176,11 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis
return mUserContexts.get(user); return mUserContexts.get(user);
} }
public void tearDown() {
mAppOpsManager.stopWatchingActive(this);
mAppOpsManager.stopWatchingStarted(this);
}
@Override @Override
public void onOpActiveChanged(@NonNull String op, int uid, @NonNull String packageName, public void onOpActiveChanged(@NonNull String op, int uid, @NonNull String packageName,
boolean active) { boolean active) {

View File

@@ -442,7 +442,11 @@ public class FrameworkServicesModule {
@Provides @Provides
@Singleton @Singleton
static PermissionManager providePermissionManager(Context context) { static PermissionManager providePermissionManager(Context context) {
return context.getSystemService(PermissionManager.class); PermissionManager pm = context.getSystemService(PermissionManager.class);
if (pm != null) {
pm.initializeUsageHelper();
}
return pm;
} }
@Provides @Provides