Merge "Fix issue #21813831: Need API for asking to be added to power whitelist" into mnc-dev
diff --git a/api/current.txt b/api/current.txt
index 72b5ca4..4b30051 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -23419,6 +23419,7 @@
 
   public final class PowerManager {
     method public boolean isDeviceIdleMode();
+    method public boolean isIgnoringBatteryOptimizations(java.lang.String);
     method public boolean isInteractive();
     method public boolean isPowerSaveMode();
     method public deprecated boolean isScreenOn();
diff --git a/api/system-current.txt b/api/system-current.txt
index 6ef78d0..582e146 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -25341,6 +25341,7 @@
 
   public final class PowerManager {
     method public boolean isDeviceIdleMode();
+    method public boolean isIgnoringBatteryOptimizations(java.lang.String);
     method public boolean isInteractive();
     method public boolean isPowerSaveMode();
     method public boolean isScreenBrightnessBoosted();
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 970623a..83ce087 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2248,6 +2248,7 @@
             //@hide: VOICE_INTERACTION_MANAGER_SERVICE,
             //@hide: BACKUP_SERVICE,
             DROPBOX_SERVICE,
+            //@hide: DEVICE_IDLE_CONTROLLER,
             DEVICE_POLICY_SERVICE,
             UI_MODE_SERVICE,
             DOWNLOAD_SERVICE,
@@ -2874,6 +2875,13 @@
     public static final String DROPBOX_SERVICE = "dropbox";
 
     /**
+     * System service name for the DeviceIdleController.  There is no Java API for this.
+     * @see #getSystemService
+     * @hide
+     */
+    public static final String DEVICE_IDLE_CONTROLLER = "deviceidle";
+
+    /**
      * Use with {@link #getSystemService} to retrieve a
      * {@link android.app.admin.DevicePolicyManager} for working with global
      * device policy management.
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 7a1aa1e..6ef1cd0 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -392,6 +392,8 @@
     final IPowerManager mService;
     final Handler mHandler;
 
+    IDeviceIdleController mIDeviceIdleController;
+
     /**
      * {@hide}
      */
@@ -892,6 +894,25 @@
     }
 
     /**
+     * Return whether the given application package name is on the device's power whitelist.
+     * Apps can be placed on the whitelist through the settings UI invoked by
+     * {@link android.provider.Settings#ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS}.
+     */
+    public boolean isIgnoringBatteryOptimizations(String packageName) {
+        synchronized (this) {
+            if (mIDeviceIdleController == null) {
+                mIDeviceIdleController = IDeviceIdleController.Stub.asInterface(
+                        ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
+            }
+        }
+        try {
+            return mIDeviceIdleController.isPowerSaveWhitelistApp(packageName);
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
+    /**
      * Turn off the device.
      *
      * @param confirm If true, shows a shutdown confirmation dialog.
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index e335f6d..dfd72c2 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -579,13 +579,14 @@
     /**
      * Activity Action: Show screen for controlling which apps can ignore battery optimizations.
      * <p>
-     * In some cases, a matching Activity may not exist, so ensure you
-     * safeguard against this.
-     * <p>
-     * Input: The Intent's data URI specifies the application package name
+     * Input: Optionally, the Intent's data URI specifies the application package name
      * to be shown, with the "package" scheme.  That is "package:com.my.app".
      * <p>
      * Output: Nothing.
+     * <p>
+     * You can use {@link android.os.PowerManager#isIgnoringBatteryOptimizations
+     * PowerManager.isIgnoringBatteryOptimizations()} to determine if an application is
+     * already ignoring optimizations.
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS =
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index ad34b37..6eba3f6 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -95,8 +95,6 @@
 
     private static final boolean COMPRESS_TIME = false;
 
-    public static final String SERVICE_NAME = "deviceidle";
-
     private static final String ACTION_STEP_IDLE_STATE =
             "com.android.server.device_idle.STEP_IDLE_STATE";
 
@@ -636,7 +634,7 @@
             mInactiveTimeout = mConstants.INACTIVE_TIMEOUT;
         }
 
-        publishBinderService(SERVICE_NAME, new BinderService());
+        publishBinderService(Context.DEVICE_IDLE_CONTROLLER, new BinderService());
     }
 
     @Override
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 81ef4d5..e009455 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -338,7 +338,7 @@
         mNetworkStats = checkNotNull(networkStats, "missing networkStats");
         mNetworkManager = checkNotNull(networkManagement, "missing networkManagement");
         mDeviceIdleController = IDeviceIdleController.Stub.asInterface(ServiceManager.getService(
-                DeviceIdleController.SERVICE_NAME));
+                Context.DEVICE_IDLE_CONTROLLER));
         mTime = checkNotNull(time, "missing TrustedTime");
         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
 
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 837570b..75b8278 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -196,7 +196,7 @@
 
             mAppWidgetManager = getContext().getSystemService(AppWidgetManager.class);
             mDeviceIdleController = IDeviceIdleController.Stub.asInterface(
-                    ServiceManager.getService(DeviceIdleController.SERVICE_NAME));
+                    ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
             mBatteryStats = IBatteryStats.Stub.asInterface(
                     ServiceManager.getService(BatteryStats.SERVICE_NAME));
             mDisplayManager = (DisplayManager) getContext().getSystemService(
diff --git a/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java b/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
index 94cbabf..2f0bf39 100644
--- a/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
+++ b/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
@@ -32,15 +32,18 @@
 import android.content.Intent;
 import android.content.ServiceConnection;
 import android.graphics.BitmapFactory;
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
+import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.graphics.Bitmap;
+import android.provider.Settings;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
@@ -60,6 +63,7 @@
     static final String KEY_CONFIGURATION = "configuration";
 
     ActivityManager mAm;
+    PowerManager mPower;
     AlarmManager mAlarm;
     Configuration mOverrideConfig;
     int mSecondUser;
@@ -158,8 +162,9 @@
 
         Log.i(TAG, "Referrer: " + getReferrer());
 
-        mAm = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
-        mAlarm = (AlarmManager)getSystemService(ALARM_SERVICE);
+        mAm = getSystemService(ActivityManager.class);
+        mPower = getSystemService(PowerManager.class);
+        mAlarm = getSystemService(AlarmManager.class);
         if (savedInstanceState != null) {
             mOverrideConfig = savedInstanceState.getParcelable(KEY_CONFIGURATION);
             if (mOverrideConfig != null) {
@@ -445,7 +450,7 @@
                 new MenuItem.OnMenuItemClickListener() {
             @Override public boolean onMenuItemClick(MenuItem item) {
                 Intent intent = new Intent(Intent.ACTION_MAIN);
-                intent.putExtra("gulp", new int[1024*1024]);
+                intent.putExtra("gulp", new int[1024 * 1024]);
                 startActivity(intent);
                 return true;
             }
@@ -457,6 +462,17 @@
                 return true;
             }
         });
+        menu.add("Ignore battery optimizations").setOnMenuItemClickListener(
+                new MenuItem.OnMenuItemClickListener() {
+            @Override public boolean onMenuItemClick(MenuItem item) {
+                Intent intent = new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
+                if (!mPower.isIgnoringBatteryOptimizations(getPackageName())) {
+                    intent.setData(Uri.fromParts("package", getPackageName(), null));
+                }
+                startActivity(intent);
+                return true;
+            }
+        });
         return true;
     }