Home | History | Annotate | Download | only in batterytip
      1 /*
      2  * Copyright (C) 2018 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.settings.fuelgauge.batterytip;
     18 
     19 import android.app.AppOpsManager;
     20 import android.app.PendingIntent;
     21 import android.app.StatsManager;
     22 import android.content.Context;
     23 import android.content.Intent;
     24 import android.os.UserHandle;
     25 import android.os.UserManager;
     26 import android.support.annotation.NonNull;
     27 
     28 import com.android.internal.util.CollectionUtils;
     29 import com.android.settings.SettingsActivity;
     30 import com.android.settings.core.InstrumentedPreferenceFragment;
     31 import com.android.settings.fuelgauge.batterytip.actions.BatterySaverAction;
     32 import com.android.settings.fuelgauge.batterytip.actions.BatteryTipAction;
     33 import com.android.settings.fuelgauge.batterytip.actions.OpenBatterySaverAction;
     34 import com.android.settings.fuelgauge.batterytip.actions.OpenRestrictAppFragmentAction;
     35 import com.android.settings.fuelgauge.batterytip.actions.RestrictAppAction;
     36 import com.android.settings.fuelgauge.batterytip.actions.SmartBatteryAction;
     37 import com.android.settings.fuelgauge.batterytip.actions.UnrestrictAppAction;
     38 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
     39 import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip;
     40 import com.android.settings.fuelgauge.batterytip.tips.UnrestrictAppTip;
     41 
     42 import java.util.ArrayList;
     43 import java.util.List;
     44 
     45 /**
     46  * Utility class for {@link BatteryTip}
     47  */
     48 public class BatteryTipUtils {
     49     private static final int REQUEST_CODE = 0;
     50 
     51     /**
     52      * Get a list of restricted apps with {@link AppOpsManager#OP_RUN_ANY_IN_BACKGROUND}
     53      */
     54     @NonNull
     55     public static List<AppInfo> getRestrictedAppsList(AppOpsManager appOpsManager,
     56             UserManager userManager) {
     57         final List<UserHandle> userHandles = userManager.getUserProfiles();
     58         final List<AppOpsManager.PackageOps> packageOpsList = appOpsManager.getPackagesForOps(
     59                 new int[]{AppOpsManager.OP_RUN_ANY_IN_BACKGROUND});
     60         final List<AppInfo> appInfos = new ArrayList<>();
     61 
     62         for (int i = 0, size = CollectionUtils.size(packageOpsList); i < size; i++) {
     63             final AppOpsManager.PackageOps packageOps = packageOpsList.get(i);
     64             final List<AppOpsManager.OpEntry> entries = packageOps.getOps();
     65             for (int j = 0, entriesSize = entries.size(); j < entriesSize; j++) {
     66                 AppOpsManager.OpEntry entry = entries.get(j);
     67                 if (entry.getOp() != AppOpsManager.OP_RUN_ANY_IN_BACKGROUND) {
     68                     continue;
     69                 }
     70                 if (entry.getMode() != AppOpsManager.MODE_ALLOWED
     71                         && userHandles.contains(
     72                         new UserHandle(UserHandle.getUserId(packageOps.getUid())))) {
     73                     appInfos.add(new AppInfo.Builder()
     74                             .setPackageName(packageOps.getPackageName())
     75                             .setUid(packageOps.getUid())
     76                             .build());
     77                 }
     78             }
     79         }
     80 
     81         return appInfos;
     82     }
     83 
     84     /**
     85      * Get a corresponding action based on {@code batteryTip}
     86      * @param batteryTip used to detect which action to choose
     87      * @param settingsActivity used to populate {@link BatteryTipAction}
     88      * @param fragment used to populate {@link BatteryTipAction}
     89      * @return an action for {@code batteryTip}
     90      */
     91     public static BatteryTipAction getActionForBatteryTip(BatteryTip batteryTip,
     92             SettingsActivity settingsActivity, InstrumentedPreferenceFragment fragment) {
     93         switch (batteryTip.getType()) {
     94             case BatteryTip.TipType.SMART_BATTERY_MANAGER:
     95                 return new SmartBatteryAction(settingsActivity, fragment);
     96             case BatteryTip.TipType.BATTERY_SAVER:
     97             case BatteryTip.TipType.LOW_BATTERY:
     98                 if (batteryTip.getState() == BatteryTip.StateType.HANDLED) {
     99                     return new OpenBatterySaverAction(settingsActivity);
    100                 } else {
    101                     return new BatterySaverAction(settingsActivity);
    102                 }
    103             case BatteryTip.TipType.APP_RESTRICTION:
    104                 if (batteryTip.getState() == BatteryTip.StateType.HANDLED) {
    105                     return new OpenRestrictAppFragmentAction(fragment, (RestrictAppTip) batteryTip);
    106                 } else {
    107                     return new RestrictAppAction(settingsActivity, (RestrictAppTip) batteryTip);
    108                 }
    109             case BatteryTip.TipType.REMOVE_APP_RESTRICTION:
    110                 return new UnrestrictAppAction(settingsActivity, (UnrestrictAppTip) batteryTip);
    111             default:
    112                 return null;
    113         }
    114     }
    115 
    116     /**
    117      * Upload the {@link PendingIntent} to {@link StatsManager} for anomaly detection
    118      * @throws StatsManager.StatsUnavailableException if failed to communicate with stats service
    119      */
    120     public static void uploadAnomalyPendingIntent(Context context, StatsManager statsManager)
    121             throws StatsManager.StatsUnavailableException {
    122         final Intent extraIntent = new Intent(context, AnomalyDetectionReceiver.class);
    123         final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, REQUEST_CODE,
    124                 extraIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    125         statsManager.setBroadcastSubscriber(pendingIntent,
    126                 StatsManagerConfig.ANOMALY_CONFIG_KEY, StatsManagerConfig.SUBSCRIBER_ID);
    127     }
    128 }
    129