Merge "Allow clamped bound position to be INVALID_POSITION"
diff --git a/api/current.txt b/api/current.txt
index ffc7ad4..3e1c3ed 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6467,6 +6467,7 @@
     field public static final java.lang.String ALARM_SERVICE = "alarm";
     field public static final java.lang.String APP_OPS_SERVICE = "appops";
     field public static final java.lang.String AUDIO_SERVICE = "audio";
+    field public static final java.lang.String BATTERY_SERVICE = "batterymanager";
     field public static final int BIND_ABOVE_CLIENT = 8; // 0x8
     field public static final int BIND_ADJUST_WITH_ACTIVITY = 128; // 0x80
     field public static final int BIND_ALLOW_OOM_MANAGEMENT = 16; // 0x10
@@ -18977,6 +18978,7 @@
 
   public class BatteryManager {
     ctor public BatteryManager();
+    method public android.os.BatteryProperty getProperty(int) throws android.os.RemoteException;
     field public static final int BATTERY_HEALTH_COLD = 7; // 0x7
     field public static final int BATTERY_HEALTH_DEAD = 4; // 0x4
     field public static final int BATTERY_HEALTH_GOOD = 2; // 0x2
@@ -19004,6 +19006,18 @@
     field public static final java.lang.String EXTRA_VOLTAGE = "voltage";
   }
 
+  public class BatteryProperty implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getInt();
+    method public void readFromParcel(android.os.Parcel);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int CAPACITY = 4; // 0x4
+    field public static final int CHARGE_COUNTER = 1; // 0x1
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final int CURRENT_AVERAGE = 3; // 0x3
+    field public static final int CURRENT_NOW = 2; // 0x2
+  }
+
   public class Binder implements android.os.IBinder {
     ctor public Binder();
     method public void attachInterface(android.os.IInterface, java.lang.String);
@@ -27817,14 +27831,6 @@
     method public abstract boolean onTune(android.net.Uri);
   }
 
-  public abstract class TvInputSession {
-    ctor public TvInputSession();
-    method public void release();
-    method public void setSurface(android.view.Surface);
-    method public void setVolume(float);
-    method public void tune(android.net.Uri);
-  }
-
 }
 
 package android.util {
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 1c02102..f444680 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -82,6 +82,7 @@
 import android.net.wifi.p2p.IWifiP2pManager;
 import android.net.wifi.p2p.WifiP2pManager;
 import android.nfc.NfcManager;
+import android.os.BatteryManager;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Debug;
@@ -404,6 +405,11 @@
                     return new DownloadManager(ctx.getContentResolver(), ctx.getPackageName());
                 }});
 
+        registerService(BATTERY_SERVICE, new ServiceFetcher() {
+                public Object createService(ContextImpl ctx) {
+                    return new BatteryManager();
+                }});
+
         registerService(NFC_SERVICE, new ServiceFetcher() {
                 public Object createService(ContextImpl ctx) {
                     return new NfcManager(ctx);
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index ed0cc23..decd59c 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2009,6 +2009,7 @@
             CAMERA_SERVICE,
             PRINT_SERVICE,
             MEDIA_SESSION_SERVICE,
+            BATTERY_SERVICE,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ServiceName {}
@@ -2060,6 +2061,8 @@
      * <dd> An {@link android.app.UiModeManager} for controlling UI modes.
      * <dt> {@link #DOWNLOAD_SERVICE} ("download")
      * <dd> A {@link android.app.DownloadManager} for requesting HTTP downloads
+     * <dt> {@link #BATTERY_SERVICE} ("batterymanager")
+     * <dd> A {@link android.os.Battery} for managing battery state
      * </dl>
      *
      * <p>Note:  System services obtained via this API may be closely associated with
@@ -2113,6 +2116,8 @@
      * @see android.app.UiModeManager
      * @see #DOWNLOAD_SERVICE
      * @see android.app.DownloadManager
+     * @see #BATTERY_SERVICE
+     * @see android.os.BatteryManager
      */
     public abstract Object getSystemService(@ServiceName @NonNull String name);
 
@@ -2481,6 +2486,14 @@
 
     /**
      * Use with {@link #getSystemService} to retrieve a
+     * {@link android.os.BatteryManager} for managing battery state.
+     *
+     * @see #getSystemService
+     */
+    public static final String BATTERY_SERVICE = "batterymanager";
+
+    /**
+     * Use with {@link #getSystemService} to retrieve a
      * {@link android.nfc.NfcManager} for using NFC.
      *
      * @see #getSystemService
diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java
index 2e38960..f339e52 100644
--- a/core/java/android/os/BatteryManager.java
+++ b/core/java/android/os/BatteryManager.java
@@ -16,9 +16,15 @@
 
 package android.os;
 
+import android.os.BatteryProperty;
+import android.os.IBatteryPropertiesRegistrar;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+
 /**
  * The BatteryManager class contains strings and constants used for values
- * in the {@link android.content.Intent#ACTION_BATTERY_CHANGED} Intent.
+ * in the {@link android.content.Intent#ACTION_BATTERY_CHANGED} Intent, and
+ * provides a method for querying battery and charging properties.
  */
 public class BatteryManager {
     /**
@@ -121,4 +127,30 @@
     /** @hide */
     public static final int BATTERY_PLUGGED_ANY =
             BATTERY_PLUGGED_AC | BATTERY_PLUGGED_USB | BATTERY_PLUGGED_WIRELESS;
+
+    private IBatteryPropertiesRegistrar mBatteryPropertiesRegistrar;
+
+    /**
+     * Return the requested battery property.
+     *
+     * @param id identifier from {@link BatteryProperty} of the requested property
+     * @return a {@link BatteryProperty} object that returns the property value, or null on error
+     */
+    public BatteryProperty getProperty(int id) throws RemoteException {
+        if (mBatteryPropertiesRegistrar == null) {
+            IBinder b = ServiceManager.getService("batteryproperties");
+            mBatteryPropertiesRegistrar =
+                IBatteryPropertiesRegistrar.Stub.asInterface(b);
+
+            if (mBatteryPropertiesRegistrar == null)
+                return null;
+        }
+
+        BatteryProperty prop = new BatteryProperty(Integer.MIN_VALUE);
+        if ((mBatteryPropertiesRegistrar.getProperty(id, prop) == 0) &&
+            (prop.getInt() != Integer.MIN_VALUE))
+            return prop;
+        else
+            return null;
+    }
 }
diff --git a/core/java/android/os/BatteryProperty.java b/core/java/android/os/BatteryProperty.java
index 76b0dc4..ec73952 100644
--- a/core/java/android/os/BatteryProperty.java
+++ b/core/java/android/os/BatteryProperty.java
@@ -19,22 +19,67 @@
 import android.os.Parcelable;
 
 /**
- * {@hide}
+ * Battery properties that may be queried using
+ * {@link BatteryManager#getProperty
+ * BatteryManager.getProperty()}
  */
 public class BatteryProperty implements Parcelable {
     /*
      * Battery property identifiers.  These must match the values in
      * frameworks/native/include/batteryservice/BatteryService.h
      */
-    public static final int BATTERY_PROP_CHARGE_COUNTER = 1;
-    public static final int BATTERY_PROP_CURRENT_NOW = 2;
-    public static final int BATTERY_PROP_CURRENT_AVG = 3;
-    public static final int BATTERY_PROP_CAPACITY = 4;
+    /** Battery capacity in microampere-hours, as an integer. */
+    public static final int CHARGE_COUNTER = 1;
 
-    public int valueInt;
+    /**
+     * Instantaneous battery current in microamperes, as an integer.  Positive
+     * values indicate net current entering the battery from a charge source,
+     * negative values indicate net current discharging from the battery.
+     */
+    public static final int CURRENT_NOW = 2;
 
+    /**
+     * Average battery current in microamperes, as an integer.  Positive
+     * values indicate net current entering the battery from a charge source,
+     * negative values indicate net current discharging from the battery.
+     * The time period over which the average is computed may depend on the
+     * fuel gauge hardware and its configuration.
+     */
+    public static final int CURRENT_AVERAGE = 3;
+
+    /**
+     * Remaining battery capacity as an integer percentage of total capacity
+     * (with no fractional part).
+     */
+    public static final int CAPACITY = 4;
+
+    private int mValueInt;
+
+    /**
+     * @hide
+     */
+    public BatteryProperty(int value) {
+        mValueInt = value;
+    }
+
+    /**
+     * @hide
+     */
     public BatteryProperty() {
-        valueInt = Integer.MIN_VALUE;
+        mValueInt = Integer.MIN_VALUE;
+    }
+
+    /**
+     * Return the value of a property of integer type previously queried
+     * via {@link BatteryManager#getProperty
+     * BatteryManager.getProperty()}.  If the platform does
+     * not provide the property queried, this value will be
+     * Integer.MIN_VALUE.
+     *
+     * @return The queried property value, or Integer.MIN_VALUE if not supported.
+     */
+    public int getInt() {
+        return mValueInt;
     }
 
     /*
@@ -47,11 +92,11 @@
     }
 
     public void readFromParcel(Parcel p) {
-        valueInt = p.readInt();
+        mValueInt = p.readInt();
     }
 
     public void writeToParcel(Parcel p, int flags) {
-        p.writeInt(valueInt);
+        p.writeInt(mValueInt);
     }
 
     public static final Parcelable.Creator<BatteryProperty> CREATOR
diff --git a/core/java/android/tv/ITvInputSessionWrapper.java b/core/java/android/tv/ITvInputSessionWrapper.java
index fd4e1e3..66fe5e1 100644
--- a/core/java/android/tv/ITvInputSessionWrapper.java
+++ b/core/java/android/tv/ITvInputSessionWrapper.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.net.Uri;
 import android.os.Message;
+import android.tv.TvInputService.TvInputSessionImpl;
 import android.util.Log;
 import android.view.Surface;
 
@@ -38,10 +39,10 @@
     private static final int DO_SET_VOLUME = 3;
     private static final int DO_TUNE = 4;
 
-    private TvInputSession mTvInputSession;
+    private TvInputSessionImpl mTvInputSession;
     private final HandlerCaller mCaller;
 
-    public ITvInputSessionWrapper(Context context, TvInputSession session) {
+    public ITvInputSessionWrapper(Context context, TvInputSessionImpl session) {
         mCaller = new HandlerCaller(context, null, this, true /* asyncHandler */);
         mTvInputSession = session;
     }
diff --git a/core/java/android/tv/TvInputManager.java b/core/java/android/tv/TvInputManager.java
index 0b6ab64..4cf2b35 100644
--- a/core/java/android/tv/TvInputManager.java
+++ b/core/java/android/tv/TvInputManager.java
@@ -282,7 +282,7 @@
     }
 
     /**
-     * Creates a {@link TvInputSession} interface for a given TV input.
+     * Creates a {@link Session} for a given TV input.
      * <p>
      * The number of sessions that can be created at the same time is limited by the capability of
      * the given TV input.
diff --git a/core/java/android/tv/TvInputService.java b/core/java/android/tv/TvInputService.java
index e43cc95..d7f6c32 100644
--- a/core/java/android/tv/TvInputService.java
+++ b/core/java/android/tv/TvInputService.java
@@ -123,7 +123,7 @@
     public abstract TvInputSessionImpl onCreateSession();
 
     /**
-     * Base class for derived classes to implement to provide {@link TvInputSession}.
+     * Base class for derived classes to implement to provide {@link TvInputManager.Session}.
      */
     public abstract static class TvInputSessionImpl {
         /**
@@ -155,52 +155,35 @@
          * @return {@code true} the tuning was successful, {@code false} otherwise.
          */
         public abstract boolean onTune(Uri channelUri);
-    }
-
-    /**
-     * Internal implementation of {@link TvInputSession}. This takes care of basic maintenance of
-     * the TV input session but most behavior must be implemented in {@link TvInputSessionImpl}
-     * returned by {@link TvInputService#onCreateSession}.
-     */
-    private static class TvInputSessionImplInternal extends TvInputSession {
-        private final TvInputSessionImpl mSessionImpl;
-
-        public TvInputSessionImplInternal(TvInputSessionImpl sessionImpl) {
-            mSessionImpl = sessionImpl;
-        }
 
         /**
          * This method is called when the application would like to stop using the current input
          * session.
          */
-        @Override
-        public final void release() {
-            mSessionImpl.onRelease();
+        void release() {
+            onRelease();
         }
 
         /**
-         * Calls {@link TvInputSessionImpl#onSetSurface}.
+         * Calls {@link onSetSurface}.
          */
-        @Override
-        public final void setSurface(Surface surface) {
-            mSessionImpl.onSetSurface(surface);
+        void setSurface(Surface surface) {
+            onSetSurface(surface);
             // TODO: Handle failure.
         }
 
         /**
-         * Calls {@link TvInputSessionImpl#onSetVolume}.
+         * Calls {@link onSetVolume}.
          */
-        @Override
-        public final void setVolume(float volume) {
-            mSessionImpl.onSetVolume(volume);
+        void setVolume(float volume) {
+            onSetVolume(volume);
         }
 
         /**
-         * Calls {@link TvInputSessionImpl#onTune}.
+         * Calls {@link onTune}.
          */
-        @Override
-        public final void tune(Uri channelUri) {
-            mSessionImpl.onTune(channelUri);
+        void tune(Uri channelUri) {
+            onTune(channelUri);
             // TODO: Handle failure.
         }
     }
@@ -222,7 +205,7 @@
                             return;
                         }
                         ITvInputSession stub = new ITvInputSessionWrapper(TvInputService.this,
-                                new TvInputSessionImplInternal(sessionImpl));
+                                sessionImpl);
                         cb.onSessionCreated(stub);
                     } catch (RemoteException e) {
                         Log.e(TAG, "error in onSessionCreated");
diff --git a/core/java/android/tv/TvInputSession.java b/core/java/android/tv/TvInputSession.java
deleted file mode 100644
index cdd363b..0000000
--- a/core/java/android/tv/TvInputSession.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.tv;
-
-import android.net.Uri;
-import android.view.Surface;
-
-/**
- * The TvInputSession provides the per-session functionality of TvInputService.
- */
-public abstract class TvInputSession {
-    /**
-     * This method is called when the application would like to stop using the current input
-     * session.
-     */
-    public void release() { }
-
-    /**
-     * Sets the {@link Surface} for the current input session on which the TV input renders video.
-     *
-     * @param surface {@link Surface} to be used for the video playback of this session.
-     */
-    public void setSurface(Surface surface) { }
-
-    /**
-     * This method is called when the application needs to handle the change of audio focus by
-     * setting the relative volume of the current TV input service session.
-     *
-     * @param volume Volume scale from 0.0 to 1.0.
-     */
-    // TODO: Remove this once it becomes irrelevant for applications to handle audio focus. The plan
-    // is to introduce some new concepts that will solve a number of problems in audio policy today.
-    public void setVolume(float volume) { }
-
-    /**
-     * Tunes to a given channel.
-     *
-     * @param channelUri The URI of the channel.
-     */
-    public void tune(Uri channelUri) { }
-}