diff --git a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java index f3c64b78893..7fe180d0343 100644 --- a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java +++ b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java @@ -25,7 +25,6 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.os.Bundle; import android.os.UserHandle; -import android.text.TextUtils; import android.util.Log; import android.view.View; @@ -56,6 +55,8 @@ import com.android.settingslib.widget.SelectorWithWidgetPreference; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; /** * 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_REMOVE_DEVICE_ADMIN = 1; + private final ExecutorService mExecutor = Executors.newSingleThreadExecutor(); + @VisibleForTesting LayoutPreference mHeaderPreference; @VisibleForTesting @@ -98,8 +101,6 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements @VisibleForTesting ApplicationsState.AppEntry mAppEntry; @VisibleForTesting - BatteryUtils mBatteryUtils; - @VisibleForTesting BatteryOptimizeUtils mBatteryOptimizeUtils; @VisibleForTesting FooterPreference mFooterPreference; @@ -244,7 +245,6 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements super.onAttach(activity); mState = ApplicationsState.getInstance(getActivity().getApplication()); - mBatteryUtils = BatteryUtils.getInstance(getContext()); } @Override @@ -267,12 +267,15 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements initHeader(); mOptimizationMode = mBatteryOptimizeUtils.getAppOptimizationMode(); initPreferenceForTriState(getContext()); - final String packageName = mBatteryOptimizeUtils.getPackageName(); - FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider() - .action( - getContext(), - SettingsEnums.OPEN_APP_BATTERY_USAGE, - packageName); + mExecutor.execute(() -> { + String packageName = + getLoggingPackageName(getContext(), mBatteryOptimizeUtils.getPackageName()); + FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider() + .action( + getContext(), + SettingsEnums.OPEN_APP_BATTERY_USAGE, + packageName); + }); mLogStringBuilder = new StringBuilder("onResume mode = ").append(mOptimizationMode); } @@ -444,17 +447,21 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements metricCategory = SettingsEnums.ACTION_APP_BATTERY_USAGE_RESTRICTED; break; } - - if (metricCategory != 0) { - final String packageName = mBatteryOptimizeUtils.getPackageName(); + if (metricCategory == 0) { + return; + } + int finalMetricCategory = metricCategory; + mExecutor.execute(() -> { + String packageName = + getLoggingPackageName(getContext(), mBatteryOptimizeUtils.getPackageName()); FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider() .action( /* attribution */ SettingsEnums.OPEN_APP_BATTERY_USAGE, - /* action */ metricCategory, + /* action */ finalMetricCategory, /* pageId */ SettingsEnums.OPEN_APP_BATTERY_USAGE, - TextUtils.isEmpty(packageName) ? PACKAGE_NAME_NONE : packageName, + packageName, getArguments().getInt(EXTRA_POWER_USAGE_AMOUNT)); - } + }); } private void onCreateForTriState(String packageName) { @@ -498,4 +505,9 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements 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; + } } diff --git a/src/com/android/settings/fuelgauge/BatteryUtils.java b/src/com/android/settings/fuelgauge/BatteryUtils.java index 98defbd3ace..fe396bd6009 100644 --- a/src/com/android/settings/fuelgauge/BatteryUtils.java +++ b/src/com/android/settings/fuelgauge/BatteryUtils.java @@ -20,6 +20,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; +import android.content.pm.InstallSourceInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; @@ -34,6 +35,7 @@ import android.os.SystemClock; import android.os.UidBatteryConsumer; import android.os.UserHandle; import android.provider.Settings; +import android.text.TextUtils; import android.text.format.DateUtils; import android.util.Base64; import android.util.Log; @@ -83,6 +85,8 @@ public class BatteryUtils { 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) @IntDef({StatusType.SCREEN_USAGE, StatusType.FOREGROUND, @@ -597,6 +601,21 @@ public class BatteryUtils { 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. */ public static Intent getBatteryIntent(Context context) { return context.registerReceiver( diff --git a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java index 6363a8faa62..0278553b2a5 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java @@ -20,9 +20,8 @@ import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENT 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.anyLong; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; @@ -38,9 +37,9 @@ import android.app.settings.SettingsEnums; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; +import android.content.pm.InstallSourceInfo; import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; -import android.os.BatteryStats; import android.os.Bundle; import android.os.Process; import android.os.UserHandle; @@ -79,6 +78,8 @@ import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.util.ReflectionHelpers; +import java.util.concurrent.TimeUnit; + @RunWith(RobolectricTestRunner.class) @Config(shadows = {ShadowEntityHeaderController.class, ShadowActivityManager.class}) public class AdvancedPowerUsageDetailTest { @@ -116,12 +117,12 @@ public class AdvancedPowerUsageDetailTest { @Mock private PackageManager mPackageManager; @Mock + private InstallSourceInfo mInstallSourceInfo; + @Mock private AppOpsManager mAppOpsManager; @Mock private LoaderManager mLoaderManager; @Mock - private BatteryUtils mBatteryUtils; - @Mock private BatteryOptimizeUtils mBatteryOptimizeUtils; @Mock private BackupManager mBackupManager; @@ -179,7 +180,6 @@ public class AdvancedPowerUsageDetailTest { mFragment.mHeaderPreference = mHeaderPreference; mFragment.mState = mState; - mFragment.mBatteryUtils = new BatteryUtils(RuntimeEnvironment.application); mFragment.mBatteryOptimizeUtils = mBatteryOptimizeUtils; mFragment.mBackupManager = mBackupManager; mFragment.mLogStringBuilder = new StringBuilder(); @@ -190,10 +190,6 @@ public class AdvancedPowerUsageDetailTest { doReturn(mPackageManager).when(mActivity).getPackageManager(); 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 captor = ArgumentCaptor.forClass(Intent.class); Answer callable = invocation -> { @@ -757,34 +753,46 @@ public class AdvancedPowerUsageDetailTest { } @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; mFragment.mOptimizationMode = 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); mFragment.onRadioButtonClicked(mOptimizePreference); mFragment.onPause(); + TimeUnit.SECONDS.sleep(100); verify(mMetricsFeatureProvider) .action( SettingsEnums.OPEN_APP_BATTERY_USAGE, SettingsEnums.ACTION_APP_BATTERY_USAGE_OPTIMIZED, SettingsEnums.OPEN_APP_BATTERY_USAGE, - /* package name*/ "none", + packageName, /* consumed battery */ 0); } @Test - public void onPause_optimizationModeIsNotChanged_notInvokeLogging() { + public void onPause_optimizationModeIsNotChanged_notInvokeLogging() + throws PackageManager.NameNotFoundException, InterruptedException { final int mode = BatteryOptimizeUtils.MODE_OPTIMIZED; mFragment.mOptimizationMode = 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); mFragment.onRadioButtonClicked(mOptimizePreference); mFragment.onPause(); + TimeUnit.SECONDS.sleep(100); verifyNoInteractions(mMetricsFeatureProvider); }