Only log the names of the app packages which are installed from Google Play Store in battery usage app optimization page

This is to meet the Guidelines for Logging Package Names: go/package-name-logging-guidance

Bug: 267430574
Fix: 267430574
Test: presubmit
Change-Id: Icf10000f5dcf87e45175d4005af8365191ad444d
This commit is contained in:
Zaiyue Xue
2023-02-01 18:46:05 +08:00
parent 51357872de
commit 65cfcbe486
3 changed files with 68 additions and 29 deletions

View File

@@ -25,7 +25,6 @@ import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Bundle; import android.os.Bundle;
import android.os.UserHandle; import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
@@ -56,6 +55,8 @@ import com.android.settingslib.widget.SelectorWithWidgetPreference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/** /**
* Power usage detail fragment for each app, this fragment contains * Power usage detail fragment for each app, this fragment contains
@@ -91,6 +92,8 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
private static final int REQUEST_UNINSTALL = 0; private static final int REQUEST_UNINSTALL = 0;
private static final int REQUEST_REMOVE_DEVICE_ADMIN = 1; private static final int REQUEST_REMOVE_DEVICE_ADMIN = 1;
private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
@VisibleForTesting @VisibleForTesting
LayoutPreference mHeaderPreference; LayoutPreference mHeaderPreference;
@VisibleForTesting @VisibleForTesting
@@ -98,8 +101,6 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
@VisibleForTesting @VisibleForTesting
ApplicationsState.AppEntry mAppEntry; ApplicationsState.AppEntry mAppEntry;
@VisibleForTesting @VisibleForTesting
BatteryUtils mBatteryUtils;
@VisibleForTesting
BatteryOptimizeUtils mBatteryOptimizeUtils; BatteryOptimizeUtils mBatteryOptimizeUtils;
@VisibleForTesting @VisibleForTesting
FooterPreference mFooterPreference; FooterPreference mFooterPreference;
@@ -244,7 +245,6 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
super.onAttach(activity); super.onAttach(activity);
mState = ApplicationsState.getInstance(getActivity().getApplication()); mState = ApplicationsState.getInstance(getActivity().getApplication());
mBatteryUtils = BatteryUtils.getInstance(getContext());
} }
@Override @Override
@@ -267,12 +267,15 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
initHeader(); initHeader();
mOptimizationMode = mBatteryOptimizeUtils.getAppOptimizationMode(); mOptimizationMode = mBatteryOptimizeUtils.getAppOptimizationMode();
initPreferenceForTriState(getContext()); initPreferenceForTriState(getContext());
final String packageName = mBatteryOptimizeUtils.getPackageName(); mExecutor.execute(() -> {
String packageName =
getLoggingPackageName(getContext(), mBatteryOptimizeUtils.getPackageName());
FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider() FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider()
.action( .action(
getContext(), getContext(),
SettingsEnums.OPEN_APP_BATTERY_USAGE, SettingsEnums.OPEN_APP_BATTERY_USAGE,
packageName); packageName);
});
mLogStringBuilder = new StringBuilder("onResume mode = ").append(mOptimizationMode); mLogStringBuilder = new StringBuilder("onResume mode = ").append(mOptimizationMode);
} }
@@ -444,17 +447,21 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
metricCategory = SettingsEnums.ACTION_APP_BATTERY_USAGE_RESTRICTED; metricCategory = SettingsEnums.ACTION_APP_BATTERY_USAGE_RESTRICTED;
break; break;
} }
if (metricCategory == 0) {
if (metricCategory != 0) { return;
final String packageName = mBatteryOptimizeUtils.getPackageName(); }
int finalMetricCategory = metricCategory;
mExecutor.execute(() -> {
String packageName =
getLoggingPackageName(getContext(), mBatteryOptimizeUtils.getPackageName());
FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider() FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider()
.action( .action(
/* attribution */ SettingsEnums.OPEN_APP_BATTERY_USAGE, /* attribution */ SettingsEnums.OPEN_APP_BATTERY_USAGE,
/* action */ metricCategory, /* action */ finalMetricCategory,
/* pageId */ SettingsEnums.OPEN_APP_BATTERY_USAGE, /* pageId */ SettingsEnums.OPEN_APP_BATTERY_USAGE,
TextUtils.isEmpty(packageName) ? PACKAGE_NAME_NONE : packageName, packageName,
getArguments().getInt(EXTRA_POWER_USAGE_AMOUNT)); getArguments().getInt(EXTRA_POWER_USAGE_AMOUNT));
} });
} }
private void onCreateForTriState(String packageName) { private void onCreateForTriState(String packageName) {
@@ -498,4 +505,9 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
return String.format("%s\n(%s)", usageSummary, slotSummary); return String.format("%s\n(%s)", usageSummary, slotSummary);
} }
} }
private static String getLoggingPackageName(Context context, String originalPackingName) {
return BatteryUtils.isAppInstalledFromGooglePlayStore(context, originalPackingName)
? originalPackingName : PACKAGE_NAME_NONE;
}
} }

View File

@@ -20,6 +20,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.InstallSourceInfo;
import android.content.pm.PackageInfo; 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;
@@ -34,6 +35,7 @@ import android.os.SystemClock;
import android.os.UidBatteryConsumer; import android.os.UidBatteryConsumer;
import android.os.UserHandle; import android.os.UserHandle;
import android.provider.Settings; import android.provider.Settings;
import android.text.TextUtils;
import android.text.format.DateUtils; import android.text.format.DateUtils;
import android.util.Base64; import android.util.Base64;
import android.util.Log; import android.util.Log;
@@ -83,6 +85,8 @@ public class BatteryUtils {
public static final String BYPASS_DOCK_DEFENDER_ACTION = "battery.dock.defender.bypass"; public static final String BYPASS_DOCK_DEFENDER_ACTION = "battery.dock.defender.bypass";
private static final String GOOGLE_PLAY_STORE_PACKAGE = "com.android.vending";
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@IntDef({StatusType.SCREEN_USAGE, @IntDef({StatusType.SCREEN_USAGE,
StatusType.FOREGROUND, StatusType.FOREGROUND,
@@ -597,6 +601,21 @@ public class BatteryUtils {
return -1L; return -1L;
} }
/** Whether the package is installed from Google Play Store or not */
public static boolean isAppInstalledFromGooglePlayStore(Context context, String packageName) {
if (TextUtils.isEmpty(packageName)) {
return false;
}
InstallSourceInfo installSourceInfo;
try {
installSourceInfo = context.getPackageManager().getInstallSourceInfo(packageName);
} catch (PackageManager.NameNotFoundException e) {
return false;
}
return installSourceInfo != null
&& GOOGLE_PLAY_STORE_PACKAGE.equals(installSourceInfo.getInitiatingPackageName());
}
/** Gets the latest sticky battery intent from the Android system. */ /** Gets the latest sticky battery intent from the Android system. */
public static Intent getBatteryIntent(Context context) { public static Intent getBatteryIntent(Context context) {
return context.registerReceiver( return context.registerReceiver(

View File

@@ -20,9 +20,8 @@ import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENT
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
@@ -38,9 +37,9 @@ import android.app.settings.SettingsEnums;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.InstallSourceInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.BatteryStats;
import android.os.Bundle; import android.os.Bundle;
import android.os.Process; import android.os.Process;
import android.os.UserHandle; import android.os.UserHandle;
@@ -79,6 +78,8 @@ import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers; import org.robolectric.util.ReflectionHelpers;
import java.util.concurrent.TimeUnit;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowEntityHeaderController.class, ShadowActivityManager.class}) @Config(shadows = {ShadowEntityHeaderController.class, ShadowActivityManager.class})
public class AdvancedPowerUsageDetailTest { public class AdvancedPowerUsageDetailTest {
@@ -116,12 +117,12 @@ public class AdvancedPowerUsageDetailTest {
@Mock @Mock
private PackageManager mPackageManager; private PackageManager mPackageManager;
@Mock @Mock
private InstallSourceInfo mInstallSourceInfo;
@Mock
private AppOpsManager mAppOpsManager; private AppOpsManager mAppOpsManager;
@Mock @Mock
private LoaderManager mLoaderManager; private LoaderManager mLoaderManager;
@Mock @Mock
private BatteryUtils mBatteryUtils;
@Mock
private BatteryOptimizeUtils mBatteryOptimizeUtils; private BatteryOptimizeUtils mBatteryOptimizeUtils;
@Mock @Mock
private BackupManager mBackupManager; private BackupManager mBackupManager;
@@ -179,7 +180,6 @@ public class AdvancedPowerUsageDetailTest {
mFragment.mHeaderPreference = mHeaderPreference; mFragment.mHeaderPreference = mHeaderPreference;
mFragment.mState = mState; mFragment.mState = mState;
mFragment.mBatteryUtils = new BatteryUtils(RuntimeEnvironment.application);
mFragment.mBatteryOptimizeUtils = mBatteryOptimizeUtils; mFragment.mBatteryOptimizeUtils = mBatteryOptimizeUtils;
mFragment.mBackupManager = mBackupManager; mFragment.mBackupManager = mBackupManager;
mFragment.mLogStringBuilder = new StringBuilder(); mFragment.mLogStringBuilder = new StringBuilder();
@@ -190,10 +190,6 @@ public class AdvancedPowerUsageDetailTest {
doReturn(mPackageManager).when(mActivity).getPackageManager(); doReturn(mPackageManager).when(mActivity).getPackageManager();
doReturn(mAppOpsManager).when(mTestActivity).getSystemService(Context.APP_OPS_SERVICE); doReturn(mAppOpsManager).when(mTestActivity).getSystemService(Context.APP_OPS_SERVICE);
mBatteryUtils = spy(new BatteryUtils(mContext));
doReturn(FOREGROUND_SERVICE_TIME_US).when(mBatteryUtils).getForegroundServiceTotalTimeUs(
any(BatteryStats.Uid.class), anyLong());
final ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); final ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
Answer<Void> callable = invocation -> { Answer<Void> callable = invocation -> {
@@ -757,34 +753,46 @@ public class AdvancedPowerUsageDetailTest {
} }
@Test @Test
public void onPause_optimizationModeChanged_logPreference() { public void onPause_optimizationModeChanged_logPreference()
throws PackageManager.NameNotFoundException, InterruptedException {
final String packageName = "testPackageName";
final int mode = BatteryOptimizeUtils.MODE_RESTRICTED; final int mode = BatteryOptimizeUtils.MODE_RESTRICTED;
mFragment.mOptimizationMode = mode; mFragment.mOptimizationMode = mode;
when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(mode); when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(mode);
when(mBatteryOptimizeUtils.getPackageName()).thenReturn(packageName);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
when(mPackageManager.getInstallSourceInfo(anyString())).thenReturn(mInstallSourceInfo);
when(mInstallSourceInfo.getInitiatingPackageName()).thenReturn("com.android.vending");
mOptimizePreference.setKey(KEY_PREF_OPTIMIZED); mOptimizePreference.setKey(KEY_PREF_OPTIMIZED);
mFragment.onRadioButtonClicked(mOptimizePreference); mFragment.onRadioButtonClicked(mOptimizePreference);
mFragment.onPause(); mFragment.onPause();
TimeUnit.SECONDS.sleep(100);
verify(mMetricsFeatureProvider) verify(mMetricsFeatureProvider)
.action( .action(
SettingsEnums.OPEN_APP_BATTERY_USAGE, SettingsEnums.OPEN_APP_BATTERY_USAGE,
SettingsEnums.ACTION_APP_BATTERY_USAGE_OPTIMIZED, SettingsEnums.ACTION_APP_BATTERY_USAGE_OPTIMIZED,
SettingsEnums.OPEN_APP_BATTERY_USAGE, SettingsEnums.OPEN_APP_BATTERY_USAGE,
/* package name*/ "none", packageName,
/* consumed battery */ 0); /* consumed battery */ 0);
} }
@Test @Test
public void onPause_optimizationModeIsNotChanged_notInvokeLogging() { public void onPause_optimizationModeIsNotChanged_notInvokeLogging()
throws PackageManager.NameNotFoundException, InterruptedException {
final int mode = BatteryOptimizeUtils.MODE_OPTIMIZED; final int mode = BatteryOptimizeUtils.MODE_OPTIMIZED;
mFragment.mOptimizationMode = mode; mFragment.mOptimizationMode = mode;
when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(mode); when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(mode);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
when(mPackageManager.getInstallSourceInfo(anyString())).thenReturn(mInstallSourceInfo);
when(mInstallSourceInfo.getInitiatingPackageName()).thenReturn("com.android.vending");
mOptimizePreference.setKey(KEY_PREF_OPTIMIZED); mOptimizePreference.setKey(KEY_PREF_OPTIMIZED);
mFragment.onRadioButtonClicked(mOptimizePreference); mFragment.onRadioButtonClicked(mOptimizePreference);
mFragment.onPause(); mFragment.onPause();
TimeUnit.SECONDS.sleep(100);
verifyNoInteractions(mMetricsFeatureProvider); verifyNoInteractions(mMetricsFeatureProvider);
} }