Merge "TIF: Address the feedback from the API review - 3/3" into lmp-preview-dev
diff --git a/Android.mk b/Android.mk
index a1d91c36..c1de8a0 100644
--- a/Android.mk
+++ b/Android.mk
@@ -146,8 +146,6 @@
 	core/java/android/hardware/ISerialManager.aidl \
 	core/java/android/hardware/display/IDisplayManager.aidl \
 	core/java/android/hardware/display/IDisplayManagerCallback.aidl \
-	core/java/android/hardware/hdmi/IHdmiCecListener.aidl \
-	core/java/android/hardware/hdmi/IHdmiCecService.aidl \
 	core/java/android/hardware/hdmi/IHdmiControlCallback.aidl \
 	core/java/android/hardware/hdmi/IHdmiControlService.aidl \
 	core/java/android/hardware/hdmi/IHdmiHotplugEventListener.aidl \
diff --git a/api/current.txt b/api/current.txt
index fb71d36..d0eb6d0 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -705,7 +705,6 @@
     field public static final int l_resource_pad23 = 16843770; // 0x10103fa
     field public static final int l_resource_pad24 = 16843769; // 0x10103f9
     field public static final int l_resource_pad25 = 16843768; // 0x10103f8
-    field public static final int l_resource_pad26 = 16843767; // 0x10103f7
     field public static final int l_resource_pad3 = 16843790; // 0x101040e
     field public static final int l_resource_pad4 = 16843789; // 0x101040d
     field public static final int l_resource_pad5 = 16843788; // 0x101040c
@@ -1247,6 +1246,7 @@
     field public static final int trimPathEnd = 16843813; // 0x1010425
     field public static final int trimPathOffset = 16843814; // 0x1010426
     field public static final int trimPathStart = 16843812; // 0x1010424
+    field public static final int tvInputType = 16843767; // 0x10103f7
     field public static final int type = 16843169; // 0x10101a1
     field public static final int typeface = 16842902; // 0x1010096
     field public static final int uiOptions = 16843672; // 0x1010398
@@ -4483,6 +4483,7 @@
     field public static final int FLAG_ONGOING_EVENT = 2; // 0x2
     field public static final int FLAG_ONLY_ALERT_ONCE = 8; // 0x8
     field public static final int FLAG_SHOW_LIGHTS = 1; // 0x1
+    field public static final java.lang.String INTENT_CATEGORY_NOTIFICATION_PREFERENCES = "android.intent.category.NOTIFICATION_PREFERENCES";
     field public static final int PRIORITY_DEFAULT = 0; // 0x0
     field public static final int PRIORITY_HIGH = 1; // 0x1
     field public static final int PRIORITY_LOW = -1; // 0xffffffff
@@ -6993,7 +6994,6 @@
     field public static final java.lang.String DISPLAY_SERVICE = "display";
     field public static final java.lang.String DOWNLOAD_SERVICE = "download";
     field public static final java.lang.String DROPBOX_SERVICE = "dropbox";
-    field public static final java.lang.String HDMI_CEC_SERVICE = "hdmi_cec";
     field public static final java.lang.String HDMI_CONTROL_SERVICE = "hdmi_control";
     field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
     field public static final java.lang.String INPUT_SERVICE = "input";
@@ -7462,7 +7462,6 @@
     field public static final java.lang.String CATEGORY_LEANBACK_LAUNCHER = "android.intent.category.LEANBACK_LAUNCHER";
     field public static final java.lang.String CATEGORY_LE_DESK_DOCK = "android.intent.category.LE_DESK_DOCK";
     field public static final java.lang.String CATEGORY_MONKEY = "android.intent.category.MONKEY";
-    field public static final java.lang.String CATEGORY_NOTIFICATION_PREFERENCES = "android.intent.category.NOTIFICATION_PREFERENCES";
     field public static final java.lang.String CATEGORY_OPENABLE = "android.intent.category.OPENABLE";
     field public static final java.lang.String CATEGORY_PREFERENCE = "android.intent.category.PREFERENCE";
     field public static final java.lang.String CATEGORY_SAMPLE_CODE = "android.intent.category.SAMPLE_CODE";
@@ -8369,7 +8368,7 @@
     field public static final java.lang.String FEATURE_LOCATION = "android.hardware.location";
     field public static final java.lang.String FEATURE_LOCATION_GPS = "android.hardware.location.gps";
     field public static final java.lang.String FEATURE_LOCATION_NETWORK = "android.hardware.location.network";
-    field public static final java.lang.String FEATURE_MANAGEDPROFILES = "android.software.managedprofiles";
+    field public static final java.lang.String FEATURE_MANAGED_PROFILES = "android.software.managed_profiles";
     field public static final java.lang.String FEATURE_MICROPHONE = "android.hardware.microphone";
     field public static final java.lang.String FEATURE_NFC = "android.hardware.nfc";
     field public static final java.lang.String FEATURE_NFC_HOST_CARD_EMULATION = "android.hardware.nfc.hce";
@@ -12828,21 +12827,6 @@
     field public static final int UNKNOWN_VENDOR_ID = 16777215; // 0xffffff
   }
 
-  public final class HdmiCecClient {
-    method public boolean isTvOn();
-    method public void sendActiveSource();
-    method public void sendGiveDevicePowerStatus(int);
-    method public void sendImageViewOn();
-    method public void sendInactiveSource();
-    method public void sendTextViewOn();
-  }
-
-  public static abstract class HdmiCecClient.Listener {
-    ctor public HdmiCecClient.Listener();
-    method public void onCableStatusChanged(boolean);
-    method public void onMessageReceived(android.hardware.hdmi.HdmiCecMessage);
-  }
-
   public final class HdmiCecDeviceInfo implements android.os.Parcelable {
     method public int describeContents();
     method public int getDeviceType();
@@ -12854,10 +12838,6 @@
     field public static final android.os.Parcelable.Creator CREATOR;
   }
 
-  public final class HdmiCecManager {
-    method public android.hardware.hdmi.HdmiCecClient getClient(int, android.hardware.hdmi.HdmiCecClient.Listener);
-  }
-
   public final class HdmiCecMessage implements android.os.Parcelable {
     ctor public HdmiCecMessage(int, int, int, byte[]);
     method public int describeContents();
@@ -15928,9 +15908,14 @@
     method public android.content.Intent getIntentForSettingsActivity();
     method public android.content.Intent getIntentForSetupActivity();
     method public android.content.pm.ServiceInfo getServiceInfo();
+    method public int getType();
     method public java.lang.CharSequence loadLabel(android.content.pm.PackageManager);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final java.lang.String EXTRA_SERVICE_NAME = "serviceName";
+    field public static final int TYPE_HDMI = 1; // 0x1
+    field public static final int TYPE_PASSTHROUGH = 3; // 0x3
+    field public static final int TYPE_TUNER = 2; // 0x2
+    field public static final int TYPE_VIRTUAL = 0; // 0x0
   }
 
   public final class TvInputManager {
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index ac25a53..5bbc43c 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -57,9 +57,7 @@
 import android.hardware.ISerialManager;
 import android.hardware.SerialManager;
 import android.hardware.SystemSensorManager;
-import android.hardware.hdmi.HdmiCecManager;
 import android.hardware.hdmi.HdmiControlManager;
-import android.hardware.hdmi.IHdmiCecService;
 import android.hardware.hdmi.IHdmiControlService;
 import android.hardware.camera2.CameraManager;
 import android.hardware.display.DisplayManager;
@@ -384,12 +382,6 @@
                     return new BluetoothManager(ctx);
                 }});
 
-        registerService(HDMI_CEC_SERVICE, new StaticServiceFetcher() {
-                public Object createStaticService() {
-                    IBinder b = ServiceManager.getService(HDMI_CEC_SERVICE);
-                    return new HdmiCecManager(IHdmiCecService.Stub.asInterface(b));
-                }});
-
         registerService(HDMI_CONTROL_SERVICE, new StaticServiceFetcher() {
                 public Object createStaticService() {
                     IBinder b = ServiceManager.getService(HDMI_CONTROL_SERVICE);
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 72b5cd90..a1cdf59 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -17,6 +17,8 @@
 package android.app;
 
 import android.annotation.IntDef;
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
@@ -74,6 +76,15 @@
     private static final String TAG = "Notification";
 
     /**
+     * An activity that provides a user interface for adjusting notification preferences for its
+     * containing application. Optional but recommended for apps that post
+     * {@link android.app.Notification Notifications}.
+     */
+    @SdkConstant(SdkConstantType.INTENT_CATEGORY)
+    public static final String INTENT_CATEGORY_NOTIFICATION_PREFERENCES
+            = "android.intent.category.NOTIFICATION_PREFERENCES";
+
+    /**
      * Use all default values (where applicable).
      */
     public static final int DEFAULT_ALL = ~0;
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 9baac32..571bb4d 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2148,8 +2148,6 @@
      * @see android.app.SearchManager
      * @see #SENSOR_SERVICE
      * @see android.hardware.SensorManager
-     * @see #HDMI_CEC_SERVICE
-     * @see android.hardware.hdmi.HdmiCecManager
      * @see #STORAGE_SERVICE
      * @see android.os.storage.StorageManager
      * @see #VIBRATOR_SERVICE
@@ -2638,17 +2636,6 @@
 
     /**
      * Use with {@link #getSystemService} to retrieve a
-     * {@link android.hardware.hdmi.HdmiCecManager} for controlling and managing
-     * HDMI-CEC protocol.
-     *
-     * @see #getSystemService
-     * @see android.hardware.hdmi.HdmiCecManager
-     */
-    // TODO: Remove this once HdmiControlService is ready.
-    public static final String HDMI_CEC_SERVICE = "hdmi_cec";
-
-    /**
-     * Use with {@link #getSystemService} to retrieve a
      * {@link android.hardware.hdmi.HdmiControlManager} for controlling and managing
      * HDMI-CEC protocol.
      *
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index bd07470..fad3851 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2976,14 +2976,6 @@
     @SdkConstant(SdkConstantType.INTENT_CATEGORY)
     public static final String CATEGORY_CAR_MODE = "android.intent.category.CAR_MODE";
 
-    /**
-     * An activity that provides a user interface for adjusting notification preferences for its
-     * containing application. Optional but recommended for apps that post
-     * {@link android.app.Notification Notifications}.
-     */
-    @SdkConstant(SdkConstantType.INTENT_CATEGORY)
-    public static final String CATEGORY_NOTIFICATION_PREFERENCES = "android.intent.category.NOTIFICATION_PREFERENCES";
-
     // ---------------------------------------------------------------------
     // ---------------------------------------------------------------------
     // Application launch intent categories (see addCategory()).
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 35bcc02..aadb10e 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1402,7 +1402,7 @@
      * The device supports managed profiles for enterprise users.
      */
     @SdkConstant(SdkConstantType.FEATURE)
-    public static final String FEATURE_MANAGEDPROFILES = "android.software.managedprofiles";
+    public static final String FEATURE_MANAGED_PROFILES = "android.software.managed_profiles";
 
     /**
      * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
diff --git a/core/java/android/hardware/hdmi/HdmiCecClient.java b/core/java/android/hardware/hdmi/HdmiCecClient.java
deleted file mode 100644
index dcb3624..0000000
--- a/core/java/android/hardware/hdmi/HdmiCecClient.java
+++ /dev/null
@@ -1,119 +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.hardware.hdmi;
-
-import android.os.IBinder;
-import android.os.RemoteException;
-
-import android.util.Log;
-
-/**
- * HdmiCecClient is used to control HDMI-CEC logical device instance in the system.
- * It is connected to actual hardware part via HdmiCecService. It provides with methods
- * to send CEC messages to other device on the bus, and listener that allows to receive
- * incoming messages to the device.
- */
-public final class HdmiCecClient {
-    private static final String TAG = "HdmiCecClient";
-
-    private final IHdmiCecService mService;
-    private final IBinder mBinder;
-
-    /**
-     * Listener used by the client to get the incoming messages.
-     */
-    public static abstract class Listener {
-        /**
-         * Called when CEC message arrives. Override this method to receive the incoming
-         * CEC messages from other device on the bus.
-         *
-         * @param message {@link HdmiCecMessage} object
-         */
-        public void onMessageReceived(HdmiCecMessage message) { }
-
-        /**
-         * Called when hotplug event occurs. Override this method to receive the events.
-         *
-         * @param connected true if the cable is connected; otherwise false.
-         */
-        public void onCableStatusChanged(boolean connected) { }
-    }
-
-    // Private constructor.
-    private HdmiCecClient(IHdmiCecService service, IBinder b) {
-        mService = service;
-        mBinder = b;
-    }
-
-    // Factory method for HdmiCecClient.
-    // Declared package-private. Accessed by HdmiCecManager only.
-    static HdmiCecClient create(IHdmiCecService service, IBinder b) {
-        return new HdmiCecClient(service, b);
-    }
-
-    /**
-     * Send <Active Source> message.
-     */
-    public void sendActiveSource() {
-        Log.w(TAG, "In transition to HdmiControlManager. Will not work.");
-    }
-
-    /**
-     * Send <Inactive Source> message.
-     */
-    public void sendInactiveSource() {
-        Log.w(TAG, "In transition to HdmiControlManager. Will not work.");
-    }
-
-    /**
-     * Send <Text View On> message.
-     */
-    public void sendTextViewOn() {
-        Log.w(TAG, "In transition to HdmiControlManager. Will not work.");
-    }
-
-    /**
-     * Send <Image View On> message.
-     */
-    public void sendImageViewOn() {
-        Log.w(TAG, "In transition to HdmiControlManager. Will not work.");
-    }
-
-    /**
-     * Send <Give Device Power Status> message.
-     *
-     * @param address logical address of the device to send the message to, such as
-     *        {@link HdmiCec#ADDR_TV}.
-     */
-    public void sendGiveDevicePowerStatus(int address) {
-        Log.w(TAG, "In transition to HdmiControlManager. Will not work.");
-    }
-
-    /**
-     * Returns true if the TV or attached display is powered on.
-     * <p>
-     * The result of this method is only meaningful on playback devices (where the device
-     * type is {@link HdmiCec#DEVICE_PLAYBACK}).
-     * </p>
-     *
-     * @return true if TV is on; otherwise false.
-     */
-    public boolean isTvOn() {
-        Log.w(TAG, "In transition to HdmiControlManager. Will not work.");
-        return true;
-    }
-}
diff --git a/core/java/android/hardware/hdmi/HdmiCecManager.java b/core/java/android/hardware/hdmi/HdmiCecManager.java
deleted file mode 100644
index 03c46d8..0000000
--- a/core/java/android/hardware/hdmi/HdmiCecManager.java
+++ /dev/null
@@ -1,68 +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.hardware.hdmi;
-
-import android.os.IBinder;
-import android.os.RemoteException;
-
-/**
- * The HdmiCecManager class is used to provide an HdmiCecClient instance,
- * get various information on HDMI ports configuration. It is connected to actual hardware
- * via HdmiCecService.
- */
-public final class HdmiCecManager {
-    private final IHdmiCecService mService;
-
-    /**
-     * @hide - hide this constructor because it has a parameter of type IHdmiCecService,
-     * which is a system private class. The right way to create an instance of this class
-     * is using the factory Context.getSystemService.
-     */
-    public HdmiCecManager(IHdmiCecService service) {
-        mService = service;
-    }
-
-    /**
-     * Provide the HdmiCecClient instance of the given type. It also registers the listener
-     * for client to get the events coming to the device.
-     *
-     * @param type type of the HDMI-CEC logical device
-     * @param listener listener to be called
-     * @return {@link HdmiCecClient} instance. {@code null} on failure.
-     */
-    public HdmiCecClient getClient(int type, HdmiCecClient.Listener listener) {
-        return HdmiCecClient.create(mService, null);
-    }
-
-    private IHdmiCecListener getListenerWrapper(final HdmiCecClient.Listener listener) {
-        // TODO: The message/events are not yet forwarded to client since it is not clearly
-        //       defined as to how/who to handle them. Revisit it once the decision is
-        //       made on what messages will have to reach the clients, what will be
-        //       handled by service/manager.
-        return new IHdmiCecListener.Stub() {
-            @Override
-            public void onMessageReceived(HdmiCecMessage message) {
-                // Do nothing.
-            }
-
-            @Override
-            public void onCableStatusChanged(boolean connected) {
-                // Do nothing.
-            }
-        };
-    }
-}
diff --git a/core/java/android/hardware/hdmi/IHdmiCecListener.aidl b/core/java/android/hardware/hdmi/IHdmiCecListener.aidl
deleted file mode 100644
index d281ce6..0000000
--- a/core/java/android/hardware/hdmi/IHdmiCecListener.aidl
+++ /dev/null
@@ -1,29 +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.hardware.hdmi;
-
-import android.hardware.hdmi.HdmiCecMessage;
-
-/**
- * Interface definition for HdmiCecService to do interprocess communcation.
- *
- * @hide
- */
-oneway interface IHdmiCecListener {
-    void onMessageReceived(in HdmiCecMessage message);
-    void onCableStatusChanged(in boolean connected);
-}
diff --git a/core/java/android/hardware/hdmi/IHdmiCecService.aidl b/core/java/android/hardware/hdmi/IHdmiCecService.aidl
deleted file mode 100644
index ecdd345..0000000
--- a/core/java/android/hardware/hdmi/IHdmiCecService.aidl
+++ /dev/null
@@ -1,40 +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.hardware.hdmi;
-
-import android.hardware.hdmi.HdmiCecMessage;
-import android.hardware.hdmi.IHdmiCecListener;
-import android.os.IBinder;
-
-/**
- * Binder interface that components running in the appplication process
- * will use to enable HDMI-CEC protocol exchange with other devices.
- *
- * @hide
- */
-interface IHdmiCecService {
-    IBinder allocateLogicalDevice(int type, IHdmiCecListener listener);
-    void removeServiceListener(IBinder b, IHdmiCecListener listener);
-    void sendActiveSource(IBinder b);
-    void sendInactiveSource(IBinder b);
-    void sendImageViewOn(IBinder b);
-    void sendTextViewOn(IBinder b);
-    void sendGiveDevicePowerStatus(IBinder b, int address);
-    boolean isTvOn(IBinder b);
-    void sendMessage(IBinder b, in HdmiCecMessage message);
-}
-
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index f642d01..4fa04a9 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -6722,5 +6722,19 @@
         <!-- Component name of an activity that allows the user to modify
              the settings for this service. -->
         <attr name="settingsActivity" />
+        <!-- Type of this service. -->
+        <attr name="tvInputType">
+            <!-- Should be in sync with constant values defined in
+                 {@link android.media.tv.TvInputInfo}. -->
+
+            <!-- Virtual input (default) -->
+            <enum name="virtual" value="0" />
+            <!-- HDMI -->
+            <enum name="hdmi" value="1" />
+            <!-- Built-in tuner -->
+            <enum name="tuner" value="2" />
+            <!-- Pass-through -->
+            <enum name="passthrough" value="3" />
+        </attr>
     </declare-styleable>
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 33bdf58..b3e111b 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2097,6 +2097,7 @@
   <public type="attr" name="isGame" id="0x10103f4" />
   <public type="attr" name="allowEmbedded" id="0x10103f5" />
   <public type="attr" name="setupActivity" id="0x10103f6"/>
+  <public type="attr" name="tvInputType" id="0x10103f7"/>
 
 <!-- ===============================================================
      Resources added in version 21 of the platform
diff --git a/media/java/android/media/tv/TvInputInfo.java b/media/java/android/media/tv/TvInputInfo.java
index 9525c08..868c5bf 100644
--- a/media/java/android/media/tv/TvInputInfo.java
+++ b/media/java/android/media/tv/TvInputInfo.java
@@ -46,6 +46,27 @@
     private static final String TAG = "TvInputInfo";
 
     /**
+     * TV input type: the TV input service is not handling input from hardware. For example,
+     * services showing streaming from the internet falls into this type.
+     */
+    public static final int TYPE_VIRTUAL = 0;
+
+    // Should be in sync with hardware/libhardware/include/hardware/tv_input.h
+
+    /**
+     * TV input type: the TV input service is HDMI. (e.g. HDMI 1)
+     */
+    public static final int TYPE_HDMI = 1;
+    /**
+     * TV input type: the TV input service is a tuner. (e.g. terrestrial tuner)
+     */
+    public static final int TYPE_TUNER = 2;
+    /**
+     * TV input type: the TV input service is stateless pass-through. (e.g. RGB, composite, etc.)
+     */
+    public static final int TYPE_PASSTHROUGH = 3;
+
+    /**
      * The name of the TV input service to provide to the setup activity and settings activity.
      */
     public static final String EXTRA_SERVICE_NAME = "serviceName";
@@ -58,6 +79,7 @@
     // Attributes from XML meta data.
     private String mSetupActivity;
     private String mSettingsActivity;
+    private int mType;
 
     /**
      * Create a new instance of the TvInputInfo class,
@@ -105,6 +127,11 @@
                 Log.d(TAG, "Settings activity loaded. [" + input.mSettingsActivity + "] for "
                         + si.name);
             }
+            input.mType = sa.getInt(
+                    com.android.internal.R.styleable.TvInputService_tvInputType, TYPE_VIRTUAL);
+            if (DEBUG) {
+                Log.d(TAG, "Type loaded. [" + input.mType + "] for " + si.name);
+            }
             sa.recycle();
 
             return input;
@@ -179,6 +206,13 @@
     }
 
     /**
+     * Returns the type of this TV input service.
+     */
+    public int getType() {
+        return mType;
+    }
+
+    /**
      * Loads the user-displayed label for this TV input service.
      *
      * @param pm Supplies a PackageManager used to load the TV input's resources.
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index 4495195..2831d9e 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -66,6 +66,8 @@
     private MySessionCallback mSessionCallback;
     private TvInputListener mListener;
     private OnUnhandledInputEventListener mOnUnhandledInputEventListener;
+    private boolean mHasStreamVolume;
+    private float mStreamVolume;
 
     private final SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() {
         @Override
@@ -152,7 +154,10 @@
      */
     public void setStreamVolume(float volume) {
         if (DEBUG) Log.d(TAG, "setStreamVolume(" + volume + ")");
+        mHasStreamVolume = true;
+        mStreamVolume = volume;
         if (mSession == null) {
+            // Volume will be set once the connection has been made.
             return;
         }
         mSession.setStreamVolume(volume);
@@ -500,6 +505,9 @@
                 }
                 createSessionOverlayView();
                 mSession.tune(mChannelUri);
+                if (mHasStreamVolume) {
+                    mSession.setStreamVolume(mStreamVolume);
+                }
             } else {
                 if (mListener != null) {
                     mListener.onError(mInputId, ERROR_BUSY);
diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
index eaa2558..aa62daa 100644
--- a/packages/SystemUI/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -111,47 +111,13 @@
                 />
         </LinearLayout>
     </LinearLayout>
-        
-    <LinearLayout android:id="@+id/ticker"
+
+    <ViewStub
+        android:id="@+id/ticker_stub"
+        android:inflatedId="@+id/ticker"
+        android:layout="@layout/status_bar_ticker"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:paddingStart="6dip"
-        android:animationCache="false"
-        android:orientation="horizontal" >
-        <ImageSwitcher android:id="@+id/tickerIcon"
-            android:layout_width="@dimen/status_bar_icon_size"
-            android:layout_height="@dimen/status_bar_icon_size"
-            android:layout_marginEnd="4dip"
-            >
-            <com.android.systemui.statusbar.AnimatedImageView
-                android:layout_width="@dimen/status_bar_icon_size"
-                android:layout_height="@dimen/status_bar_icon_size"
-                android:scaleType="center"
-                />
-            <com.android.systemui.statusbar.AnimatedImageView
-                android:layout_width="@dimen/status_bar_icon_size"
-                android:layout_height="@dimen/status_bar_icon_size"
-                android:scaleType="center"
-                />
-        </ImageSwitcher>
-        <com.android.systemui.statusbar.phone.TickerView android:id="@+id/tickerText"
-            android:layout_width="0dip"
-            android:layout_weight="1"
-            android:layout_height="wrap_content"
-            android:paddingTop="2dip"
-            android:paddingEnd="10dip">
-            <TextView
-                android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:singleLine="true"
-                />
-            <TextView
-                android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:singleLine="true"
-                />
-        </com.android.systemui.statusbar.phone.TickerView>
-    </LinearLayout>
+        />
+
 </com.android.systemui.statusbar.phone.PhoneStatusBarView>
diff --git a/packages/SystemUI/res/layout/status_bar_ticker.xml b/packages/SystemUI/res/layout/status_bar_ticker.xml
new file mode 100644
index 0000000..dd9b3ef
--- /dev/null
+++ b/packages/SystemUI/res/layout/status_bar_ticker.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  - Copyright 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.
+  -->
+<LinearLayout android:id="@+id/ticker"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:paddingStart="6dip"
+    android:animationCache="false"
+    android:orientation="horizontal">
+
+    <ImageSwitcher android:id="@+id/tickerIcon"
+        android:layout_width="@dimen/status_bar_icon_size"
+        android:layout_height="@dimen/status_bar_icon_size"
+        android:layout_marginEnd="4dip"
+        >
+        <com.android.systemui.statusbar.AnimatedImageView
+            android:layout_width="@dimen/status_bar_icon_size"
+            android:layout_height="@dimen/status_bar_icon_size"
+            android:scaleType="center"
+            />
+        <com.android.systemui.statusbar.AnimatedImageView
+            android:layout_width="@dimen/status_bar_icon_size"
+            android:layout_height="@dimen/status_bar_icon_size"
+            android:scaleType="center"
+            />
+    </ImageSwitcher>
+    <com.android.systemui.statusbar.phone.TickerView android:id="@+id/tickerText"
+        android:layout_width="0dip"
+        android:layout_weight="1"
+        android:layout_height="wrap_content"
+        android:paddingTop="2dip"
+        android:paddingEnd="10dip">
+        <TextView
+            android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:singleLine="true"
+            />
+        <TextView
+            android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:singleLine="true"
+            />
+    </com.android.systemui.statusbar.phone.TickerView>
+</LinearLayout>
+
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 79a1df4..1ef5bcd 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -141,5 +141,10 @@
 
     <!-- Wait on the touch feedback this long before performing an action. -->
     <integer name="feedback_start_delay">300</integer>
+
+    <!-- Set to true to enable the classic notification ticker that scrolls
+         Notification.tickerText across the status bar for what seems like an
+         eternity. -->
+    <bool name="enable_ticker">false</bool>
 </resources>
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index ac9866c..4749b9c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -81,6 +81,7 @@
 import android.view.ViewGroup;
 import android.view.ViewGroup.LayoutParams;
 import android.view.ViewPropertyAnimator;
+import android.view.ViewStub;
 import android.view.ViewTreeObserver;
 import android.view.WindowManager;
 import android.view.animation.AccelerateInterpolator;
@@ -289,6 +290,7 @@
     int mTrackingPosition; // the position of the top of the tracking view.
 
     // ticker
+    private boolean mTickerEnabled;
     private Ticker mTicker;
     private View mTickerView;
     private boolean mTicking;
@@ -644,7 +646,6 @@
         mMoreIcon = mStatusBarView.findViewById(R.id.moreIcon);
         mNotificationIcons.setOverflowIndicator(mMoreIcon);
         mStatusBarContents = (LinearLayout)mStatusBarView.findViewById(R.id.status_bar_contents);
-        mTickerView = mStatusBarView.findViewById(R.id.ticker);
 
         mStackScroller = (NotificationStackScrollLayout) mStatusBarWindow.findViewById(
                 R.id.notification_stack_scroller);
@@ -684,10 +685,17 @@
             mDateTimeView.setEnabled(true);
         }
 
-        mTicker = new MyTicker(context, mStatusBarView);
+        mTickerEnabled = res.getBoolean(R.bool.enable_ticker);
+        if (mTickerEnabled) {
+            final ViewStub tickerStub = (ViewStub) mStatusBarView.findViewById(R.id.ticker_stub);
+            if (tickerStub != null) {
+                mTickerView = tickerStub.inflate();
+                mTicker = new MyTicker(context, mStatusBarView);
 
-        TickerView tickerView = (TickerView)mStatusBarView.findViewById(R.id.tickerText);
-        tickerView.mTicker = mTicker;
+                TickerView tickerView = (TickerView) mStatusBarView.findViewById(R.id.tickerText);
+                tickerView.mTicker = mTicker;
+            }
+        }
 
         mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
 
@@ -1145,7 +1153,9 @@
 
         if (old != null) {
             // Cancel the ticker if it's still running
-            mTicker.removeEntry(old);
+            if (mTickerEnabled) {
+                mTicker.removeEntry(old);
+            }
 
             // Recalculate the position of the sliding windows and the titles.
             updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
@@ -2118,6 +2128,8 @@
 
     @Override
     protected void tick(StatusBarNotification n, boolean firstTime) {
+        if (!mTickerEnabled) return;
+
         // no ticking in lights-out mode
         if (!areLightsOn()) return;
 
@@ -2134,7 +2146,7 @@
         if (n.getNotification().tickerText != null && mStatusBarWindow != null
                 && mStatusBarWindow.getWindowToken() != null) {
             if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS
-                            | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) {
+                    | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) {
                 mTicker.addEntry(n);
             }
         }
@@ -2143,10 +2155,14 @@
     private class MyTicker extends Ticker {
         MyTicker(Context context, View sb) {
             super(context, sb);
+            if (!mTickerEnabled) {
+                Log.w(TAG, "MyTicker instantiated with mTickerEnabled=false", new Throwable());
+            }
         }
 
         @Override
         public void tickerStarting() {
+            if (!mTickerEnabled) return;
             mTicking = true;
             mStatusBarContents.setVisibility(View.GONE);
             mTickerView.setVisibility(View.VISIBLE);
@@ -2156,6 +2172,7 @@
 
         @Override
         public void tickerDone() {
+            if (!mTickerEnabled) return;
             mStatusBarContents.setVisibility(View.VISIBLE);
             mTickerView.setVisibility(View.GONE);
             mStatusBarContents.startAnimation(loadAnim(com.android.internal.R.anim.push_down_in, null));
@@ -2164,6 +2181,7 @@
         }
 
         public void tickerHalting() {
+            if (!mTickerEnabled) return;
             if (mStatusBarContents.getVisibility() != View.VISIBLE) {
                 mStatusBarContents.setVisibility(View.VISIBLE);
                 mStatusBarContents
@@ -2202,11 +2220,14 @@
             pw.println("Current Status Bar state:");
             pw.println("  mExpandedVisible=" + mExpandedVisible
                     + ", mTrackingPosition=" + mTrackingPosition);
-            pw.println("  mTicking=" + mTicking);
+            pw.println("  mTickerEnabled=" + mTickerEnabled);
+            if (mTickerEnabled) {
+                pw.println("  mTicking=" + mTicking);
+                pw.println("  mTickerView: " + viewInfo(mTickerView));
+            }
             pw.println("  mTracking=" + mTracking);
             pw.println("  mDisplayMetrics=" + mDisplayMetrics);
             pw.println("  mStackScroller: " + viewInfo(mStackScroller));
-            pw.println("  mTickerView: " + viewInfo(mTickerView));
             pw.println("  mStackScroller: " + viewInfo(mStackScroller)
                     + " scroll " + mStackScroller.getScrollX()
                     + "," + mStackScroller.getScrollY());
@@ -2676,7 +2697,9 @@
 
     @Override
     protected void haltTicker() {
-        mTicker.halt();
+        if (mTickerEnabled) {
+            mTicker.halt();
+        }
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TickerView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TickerView.java
index 8aa3837..bf13751 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TickerView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TickerView.java
@@ -32,7 +32,7 @@
     @Override
     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
         super.onSizeChanged(w, h, oldw, oldh);
-        mTicker.reflowText();
+        if (mTicker != null) mTicker.reflowText();
     }
 
     public void setTicker(Ticker t) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecDevice.java
deleted file mode 100644
index baae1d99..0000000
--- a/services/core/java/com/android/server/hdmi/HdmiCecDevice.java
+++ /dev/null
@@ -1,230 +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 com.android.server.hdmi;
-
-import android.hardware.hdmi.HdmiCec;
-import android.hardware.hdmi.HdmiCecMessage;
-import android.hardware.hdmi.IHdmiCecListener;
-import android.os.Binder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * HdmiCecDevice class represents a CEC logical device characterized
- * by its device type. It is a superclass of those serving concrete device type.
- * Currently we're interested in playback(one of sources), display(sink) device type
- * only. The support for the other types like recorder, audio system will come later.
- *
- * <p>A physical device can contain the functions of
- * more than one logical device, in which case it should create
- * as many logical devices as necessary.
- *
- * <p>Note that if a physical device has multiple instances of a particular
- * functionality, it should advertize only one instance. For instance, if
- * a device has multiple tuners, it should only expose one for control
- * via CEC. In this case, it is up to the device itself to manage multiple tuners.
- *
- * <p>The version of HDMI-CEC protocol supported in this class is 1.3a.
- *
- * <p>Declared as package-private, accessed by HdmiCecService only.
- */
-abstract class HdmiCecDevice {
-    private static final String TAG = "HdmiCecDevice";
-
-    private final int mType;
-
-    // List of listeners to the message/event coming to the device.
-    private final List<IHdmiCecListener> mListeners = new ArrayList<IHdmiCecListener>();
-    private final Binder mBinder = new Binder();
-    private final HdmiCecService mService;
-
-    private boolean mIsActiveSource;
-
-    /**
-     * Factory method that creates HdmiCecDevice instance to the device type.
-     */
-    public static HdmiCecDevice create(HdmiCecService service, int type) {
-        if (type == HdmiCec.DEVICE_PLAYBACK) {
-            return new HdmiCecDevicePlayback(service, type);
-        } else if (type == HdmiCec.DEVICE_TV) {
-            return new HdmiCecDeviceTv(service, type);
-        }
-        return null;
-    }
-
-    /**
-     * Constructor.
-     */
-    public HdmiCecDevice(HdmiCecService service, int type) {
-        mService = service;
-        mType = type;
-        mIsActiveSource = false;
-    }
-
-    /**
-     * Called right after the class is instantiated. This method can be used to
-     * implement any initialization tasks for the instance.
-     */
-    abstract public void initialize();
-
-    /**
-     * Return the binder token that identifies this instance.
-     */
-    public Binder getToken() {
-        return mBinder;
-    }
-
-    /**
-     * Return the service instance.
-     */
-    public HdmiCecService getService() {
-        return mService;
-    }
-
-    /**
-     * Return the type of this device.
-     */
-    public int getType() {
-        return mType;
-    }
-
-    /**
-     * Register a listener to be invoked when events occur.
-     *
-     * @param listener the listern that will run
-     */
-    public void addListener(IHdmiCecListener listener) {
-        mListeners.add(listener);
-    }
-
-    /**
-     * Remove the listener that was previously registered.
-     *
-     * @param listener IHdmiCecListener instance to be removed
-     */
-    public void removeListener(IHdmiCecListener listener) {
-        mListeners.remove(listener);
-    }
-
-    /**
-     * Indicate if the device has listeners.
-     *
-     * @return true if there are listener instances for this device
-     */
-    public boolean hasListener() {
-        return !mListeners.isEmpty();
-    }
-
-    /**
-     * Handle HDMI-CEC message coming to the device by invoking the registered
-     * listeners.
-     */
-    public void handleMessage(int srcAddress, int dstAddress, int opcode, byte[] params) {
-        if (opcode == HdmiCec.MESSAGE_ACTIVE_SOURCE) {
-            mIsActiveSource = false;
-        }
-
-        if (mListeners.size() == 0) {
-            return;
-        }
-        HdmiCecMessage message = new HdmiCecMessage(srcAddress, dstAddress, opcode, params);
-        for (IHdmiCecListener listener : mListeners) {
-            try {
-                listener.onMessageReceived(message);
-            } catch (RemoteException e) {
-                Log.e(TAG, "listener.onMessageReceived failed.");
-            }
-        }
-    }
-
-    public void handleHotplug(boolean connected) {
-        for (IHdmiCecListener listener : mListeners) {
-            try {
-                listener.onCableStatusChanged(connected);
-            } catch (RemoteException e) {
-                Log.e(TAG, "listener.onCableStatusChanged failed.");
-            }
-        }
-    }
-
-    /**
-     * Return the active status of the device.
-     *
-     * @return true if the device is the active source among the connected
-     *         HDMI-CEC-enabled devices; otherwise false.
-     */
-    public boolean isActiveSource() {
-        return mIsActiveSource;
-    }
-
-    /**
-     * Update the active source state of the device.
-     */
-    public void setIsActiveSource(boolean state) {
-        mIsActiveSource = state;
-    }
-
-    /**
-     * Send &lt;Active Source&gt; command. The default implementation does nothing. Should be
-     * overriden by subclass.
-     */
-    public void sendActiveSource(int physicalAddress) {
-        logWarning("<Active Source> not valid for the device type: " + mType
-                + " address:" + physicalAddress);
-    }
-
-    /**
-     * Send &lt;Inactive Source&gt; command. The default implementation does nothing. Should be
-     * overriden by subclass.
-     */
-    public void sendInactiveSource(int physicalAddress) {
-        logWarning("<Inactive Source> not valid for the device type: " + mType
-                + " address:" + physicalAddress);
-    }
-
-    /**
-     * Send &lt;Image View On&gt; command. The default implementation does nothing. Should be
-     * overriden by subclass.
-     */
-    public void sendImageViewOn() {
-        logWarning("<Image View On> not valid for the device type: " + mType);
-    }
-
-    /**
-     * Send &lt;Text View On&gt; command. The default implementation does nothing. Should be
-     * overriden by subclass.
-     */
-    public void sendTextViewOn() {
-        logWarning("<Text View On> not valid for the device type: " + mType);
-    }
-
-    /**
-     * Check if the connected sink device is in powered-on state. The default implementation
-     * simply returns false. Should be overriden by subclass to report the correct state.
-     */
-    public boolean isSinkDeviceOn() {
-        logWarning("isSinkDeviceOn() not valid for the device type: " + mType);
-        return false;
-    }
-
-    private void logWarning(String msg) {
-        Log.w(TAG, msg);
-    }
-}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecDevicePlayback.java
deleted file mode 100644
index f8cf11d..0000000
--- a/services/core/java/com/android/server/hdmi/HdmiCecDevicePlayback.java
+++ /dev/null
@@ -1,129 +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 com.android.server.hdmi;
-
-import android.hardware.hdmi.HdmiCec;
-
-/**
- * Class for the logical device of playback type. Devices such as DVD/Blueray player
- * that support 'playback' feature are classified as playback device. It is common
- * that they don't have built-in display, therefore need to talk, stream their contents
- * to TV/display device which is connected through HDMI cable.
- *
- * <p>It closely monitors the status of display device (other devices can be of interest
- * too, but with much less priority), declares itself as 'active source' to have
- * display show its output, switch the source state as ordered by display that may be
- * talking to many other devices connected to it. It also receives commands from display
- * such as remote control signal, standby, status report, playback mode.
- *
- * <p>Declared as package-private, accessed by HdmiCecService only.
- */
-final class HdmiCecDevicePlayback extends HdmiCecDevice {
-    private static final String TAG = "HdmiCecDevicePlayback";
-
-    private int mSinkDevicePowerStatus;
-
-    /**
-     * Constructor.
-     */
-    public HdmiCecDevicePlayback(HdmiCecService service, int type) {
-        super(service, type);
-        mSinkDevicePowerStatus = HdmiCec.POWER_STATUS_UNKNOWN;
-    }
-
-    @Override
-    public void initialize() {
-        // Playback device tries to obtain the power status of TV/display when created,
-        // and maintains it all through its lifecycle. CEC spec says there is
-        // a maximum 1 second response time. Therefore it should be kept in mind
-        // that there can be as much amount of period of time the power status
-        // of the display remains unknown after the query is sent out.
-        queryTvPowerStatus();
-    }
-
-    private void queryTvPowerStatus() {
-        getService().sendMessage(getType(), HdmiCec.ADDR_TV,
-                HdmiCec.MESSAGE_GIVE_DEVICE_POWER_STATUS, HdmiCecService.EMPTY_PARAM);
-    }
-
-    @Override
-    public void handleMessage(int srcAddress, int dstAddress, int opcode, byte[] params) {
-        // Updates power status of display. The cases are:
-        // 1) Response for the queried power status request arrives. Update the status.
-        // 2) Broadcast or direct <Standby> command from TV, which is sent as TV itself is going
-        //    into standby mode too.
-        if (opcode == HdmiCec.MESSAGE_REPORT_POWER_STATUS) {
-            mSinkDevicePowerStatus = params[0];
-        } else if (srcAddress == HdmiCec.ADDR_TV) {
-            if (opcode == HdmiCec.MESSAGE_STANDBY) {
-                mSinkDevicePowerStatus = HdmiCec.POWER_STATUS_STANDBY;
-            }
-        }
-        super.handleMessage(srcAddress, dstAddress, opcode, params);
-    }
-
-    @Override
-    public void handleHotplug(boolean connected) {
-        // If cable get disconnected sink device becomes unreachable. Switch the status
-        // to unknown, and query the status once the cable gets connected back.
-        if (!connected) {
-            mSinkDevicePowerStatus = HdmiCec.POWER_STATUS_UNKNOWN;
-        } else {
-            queryTvPowerStatus();
-        }
-        super.handleHotplug(connected);
-    }
-
-    @Override
-    public boolean isSinkDeviceOn() {
-        return mSinkDevicePowerStatus == HdmiCec.POWER_STATUS_ON;
-    }
-
-    @Override
-    public void sendActiveSource(int physicalAddress) {
-        setIsActiveSource(true);
-        byte[] param = new byte[] {
-                (byte) ((physicalAddress >> 8) & 0xff),
-                (byte) (physicalAddress & 0xff)
-        };
-        getService().sendMessage(getType(), HdmiCec.ADDR_BROADCAST, HdmiCec.MESSAGE_ACTIVE_SOURCE,
-                param);
-    }
-
-    @Override
-    public void sendInactiveSource(int physicalAddress) {
-        setIsActiveSource(false);
-        byte[] param = new byte[] {
-                (byte) ((physicalAddress >> 8) & 0xff),
-                (byte) (physicalAddress & 0xff)
-        };
-        getService().sendMessage(getType(), HdmiCec.ADDR_TV, HdmiCec.MESSAGE_INACTIVE_SOURCE,
-                param);
-    }
-
-    @Override
-    public void sendImageViewOn() {
-        getService().sendMessage(getType(), HdmiCec.ADDR_TV, HdmiCec.MESSAGE_IMAGE_VIEW_ON,
-                HdmiCecService.EMPTY_PARAM);
-    }
-
-    @Override
-    public void sendTextViewOn() {
-        getService().sendMessage(getType(), HdmiCec.ADDR_TV, HdmiCec.MESSAGE_TEXT_VIEW_ON,
-                HdmiCecService.EMPTY_PARAM);
-    }
-}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecDeviceTv.java
deleted file mode 100644
index 09ff3ca..0000000
--- a/services/core/java/com/android/server/hdmi/HdmiCecDeviceTv.java
+++ /dev/null
@@ -1,35 +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 com.android.server.hdmi;
-
-/**
- * Class for logical device of TV type.
- */
-final class HdmiCecDeviceTv extends HdmiCecDevice {
-    private static final String TAG = "HdmiCecDeviceTv";
-
-    /**
-     * Constructor.
-     */
-    public HdmiCecDeviceTv(HdmiCecService service, int type) {
-        super(service, type);
-    }
-
-    public void initialize() {
-        // TODO: Do the initialization task for TV device here.
-    }
-}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecService.java b/services/core/java/com/android/server/hdmi/HdmiCecService.java
deleted file mode 100644
index 98dc72f..0000000
--- a/services/core/java/com/android/server/hdmi/HdmiCecService.java
+++ /dev/null
@@ -1,383 +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 com.android.server.hdmi;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.hardware.hdmi.HdmiCec;
-import android.hardware.hdmi.HdmiCecMessage;
-import android.hardware.hdmi.IHdmiCecListener;
-import android.hardware.hdmi.IHdmiCecService;
-import android.os.Binder;
-import android.os.Build;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.SparseArray;
-
-import com.android.server.SystemService;
-import libcore.util.EmptyArray;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Locale;
-
-/**
- * Provides a service for sending and processing HDMI-CEC messages, and providing
- * the information on HDMI settings in general.
- */
-public final class HdmiCecService extends SystemService {
-    private static final String TAG = "HdmiCecService";
-
-    // Maintains the allocated logical devices. Device type, not logical address,
-    // is used for key as logical address is likely to change over time while
-    // device type is permanent. Type-address mapping is maintained only at
-    // native level.
-    private final SparseArray<HdmiCecDevice> mLogicalDevices = new SparseArray<HdmiCecDevice>();
-
-    // List of IBinder.DeathRecipient instances to handle dead IHdmiCecListener
-    // objects.
-    private final ArrayList<ListenerRecord> mListenerRecords = new ArrayList<ListenerRecord>();
-
-    // Used to synchronize the access to the service.
-    private final Object mLock = new Object();
-
-    // Stores the pointer to the native implementation of the service that
-    // interacts with HAL.
-    private long mNativePtr;
-
-    private static final String PERMISSION = "android.permission.HDMI_CEC";
-
-    static final byte[] EMPTY_PARAM = EmptyArray.BYTE;
-
-    public HdmiCecService(Context context) {
-        super(context);
-    }
-
-    private static native long nativeInit(HdmiCecService service);
-
-    @Override
-    public void onStart() {
-        // Stop publishing the service. Soon to be deprecated.
-        Log.w(TAG, "In transition to HdmiControlService. May not work.");
-    }
-
-    /**
-     * Called by native when an HDMI-CEC message arrived. Invokes the registered
-     * listeners to handle the message.
-     */
-    private void handleMessage(int srcAddress, int dstAddress, int opcode, byte[] params) {
-        // TODO: Messages like <Standby> may not need be passed to listener
-        //       but better be handled in service by turning off the screen
-        //       or putting the device into suspend mode. List up such messages
-        //       and handle them here.
-        synchronized (mLock) {
-            if (dstAddress == HdmiCec.ADDR_BROADCAST) {
-                for (int i = 0; i < mLogicalDevices.size(); ++i) {
-                    mLogicalDevices.valueAt(i).handleMessage(srcAddress, dstAddress, opcode,
-                            params);
-                }
-            } else {
-                int type = HdmiCec.getTypeFromAddress(dstAddress);
-                HdmiCecDevice device = mLogicalDevices.get(type);
-                if (device == null) {
-                    Log.w(TAG, "logical device not found. type: " + type);
-                    return;
-                }
-                device.handleMessage(srcAddress, dstAddress, opcode, params);
-            }
-        }
-    }
-
-    /**
-     * Called by native when internal HDMI hotplug event occurs. Invokes the registered
-     * listeners to handle the event.
-     */
-    private void handleHotplug(boolean connected) {
-        synchronized(mLock) {
-            for (int i = 0; i < mLogicalDevices.size(); ++i) {
-                mLogicalDevices.valueAt(i).handleHotplug(connected);
-            }
-        }
-    }
-
-    /**
-     * Called by native when it needs to know whether we have an active source.
-     * The native part uses the return value to respond to &lt;Request Active
-     * Source &gt;.
-     *
-     * @return type of the device which is active; DEVICE_INACTIVE if there is
-     *        no active logical device in the system.
-     */
-    private int getActiveSource() {
-        synchronized(mLock) {
-            for (int i = 0; i < mLogicalDevices.size(); ++i) {
-                if (mLogicalDevices.valueAt(i).isActiveSource()) {
-                    return mLogicalDevices.keyAt(i);
-                }
-            }
-        }
-        return HdmiCec.DEVICE_INACTIVE;
-    }
-
-    /**
-     * Called by native when a request for the menu language of the device was
-     * received. The native part uses the return value to generate the message
-     * &lt;Set Menu Language&gt; in response. The language should be of
-     * the 3-letter format as defined in ISO/FDIS 639-2. We use system default
-     * locale.
-     */
-    private String getLanguage(int type) {
-        return Locale.getDefault().getISO3Language();
-    }
-
-    private void enforceAccessPermission() {
-        getContext().enforceCallingOrSelfPermission(PERMISSION, "HdmiCecService");
-    }
-
-    private void dumpInternal(PrintWriter pw) {
-        pw.println("HdmiCecService (dumpsys hdmi_cec)");
-        pw.println("");
-        synchronized (mLock) {
-            for (int i = 0; i < mLogicalDevices.size(); ++i) {
-                HdmiCecDevice device = mLogicalDevices.valueAt(i);
-                pw.println("Device: type=" + device.getType() +
-                           ", active=" + device.isActiveSource());
-            }
-        }
-    }
-
-    // Remove logical device of a given type.
-    private void removeLogicalDeviceLocked(int type) {
-        ensureValidType(type);
-        mLogicalDevices.remove(type);
-        nativeRemoveLogicalAddress(mNativePtr, type);
-    }
-
-    private static void ensureValidType(int type) {
-        if (!HdmiCec.isValidType(type)) {
-            throw new IllegalArgumentException("invalid type: " + type);
-        }
-    }
-
-    // Return the logical device identified by the given binder token.
-    private HdmiCecDevice getLogicalDeviceLocked(IBinder b) {
-        for (int i = 0; i < mLogicalDevices.size(); ++i) {
-            HdmiCecDevice device = mLogicalDevices.valueAt(i);
-            if (device.getToken() == b) {
-                return device;
-            }
-        }
-        throw new IllegalArgumentException("Device not found");
-    }
-
-    // package-private. Used by HdmiCecDevice and its subclasses only.
-    void sendMessage(int type, int address, int opcode, byte[] params) {
-        nativeSendMessage(mNativePtr, type, address, opcode, params);
-    }
-
-    private void setOsdNameLocked(String name) {
-        nativeSetOsdName(mNativePtr, name.getBytes(Charset.forName("US-ASCII")));
-    }
-
-    private final class ListenerRecord implements IBinder.DeathRecipient {
-        private final IHdmiCecListener mListener;
-        private final int mType;
-
-        public ListenerRecord(IHdmiCecListener listener, int type) {
-            mListener = listener;
-            mType = type;
-        }
-
-        @Override
-        public void binderDied() {
-            synchronized (mLock) {
-                mListenerRecords.remove(this);
-                HdmiCecDevice device = mLogicalDevices.get(mType);
-                if (device != null) {
-                    device.removeListener(mListener);
-                    if (!device.hasListener()) {
-                        removeLogicalDeviceLocked(mType);
-                    }
-                }
-            }
-        }
-    }
-
-    private final class BinderService extends IHdmiCecService.Stub {
-
-        @Override
-        public IBinder allocateLogicalDevice(int type, IHdmiCecListener listener) {
-            enforceAccessPermission();
-            ensureValidType(type);
-            if (listener == null) {
-                throw new IllegalArgumentException("listener must not be null");
-            }
-            synchronized (mLock) {
-                HdmiCecDevice device = mLogicalDevices.get(type);
-                if (device != null) {
-                    Log.v(TAG, "Logical address already allocated. Adding listener only.");
-                } else {
-                    int address = nativeAllocateLogicalAddress(mNativePtr, type);
-                    if (!HdmiCec.isValidAddress(address)) {
-                        Log.e(TAG, "Logical address was not allocated");
-                        return null;
-                    } else {
-                        device = HdmiCecDevice.create(HdmiCecService.this, type);
-                        if (device == null) {
-                            Log.e(TAG, "Device type not supported yet.");
-                            return null;
-                        }
-                        device.initialize();
-                        mLogicalDevices.put(type, device);
-                    }
-                }
-
-                // Adds the listener and its monitor
-                ListenerRecord record = new ListenerRecord(listener, type);
-                try {
-                    listener.asBinder().linkToDeath(record, 0);
-                } catch (RemoteException e) {
-                    Log.w(TAG, "Listener already died");
-                    if (!device.hasListener()) {
-                         removeLogicalDeviceLocked(type);
-                    }
-                    return null;
-                }
-                mListenerRecords.add(record);
-                device.addListener(listener);
-                return device.getToken();
-            }
-        }
-
-        @Override
-        public void sendActiveSource(IBinder b) {
-            enforceAccessPermission();
-            synchronized (mLock) {
-                HdmiCecDevice device = getLogicalDeviceLocked(b);
-                device.sendActiveSource(nativeGetPhysicalAddress(mNativePtr));
-            }
-        }
-
-        @Override
-        public void sendInactiveSource(IBinder b) {
-            enforceAccessPermission();
-            synchronized (mLock) {
-                HdmiCecDevice device = getLogicalDeviceLocked(b);
-                device.sendInactiveSource(nativeGetPhysicalAddress(mNativePtr));
-            }
-        }
-
-        @Override
-        public void sendImageViewOn(IBinder b) {
-            enforceAccessPermission();
-            synchronized (mLock) {
-                HdmiCecDevice device = getLogicalDeviceLocked(b);
-                device.sendImageViewOn();
-            }
-        }
-
-        @Override
-        public void sendTextViewOn(IBinder b) {
-            enforceAccessPermission();
-            synchronized (mLock) {
-                HdmiCecDevice device = getLogicalDeviceLocked(b);
-                device.sendTextViewOn();
-            }
-        }
-
-        public void sendGiveDevicePowerStatus(IBinder b, int address) {
-            enforceAccessPermission();
-            synchronized (mLock) {
-                HdmiCecDevice device = getLogicalDeviceLocked(b);
-                nativeSendMessage(mNativePtr, device.getType(), address,
-                        HdmiCec.MESSAGE_GIVE_DEVICE_POWER_STATUS, EMPTY_PARAM);
-            }
-        }
-
-        @Override
-        public boolean isTvOn(IBinder b) {
-            enforceAccessPermission();
-            synchronized (mLock) {
-                HdmiCecDevice device = getLogicalDeviceLocked(b);
-                return device.isSinkDeviceOn();
-            }
-        }
-
-        @Override
-        public void removeServiceListener(IBinder b, IHdmiCecListener listener) {
-            enforceAccessPermission();
-            if (listener == null) {
-                throw new IllegalArgumentException("listener must not be null");
-            }
-            synchronized (mLock) {
-                HdmiCecDevice device = getLogicalDeviceLocked(b);
-                for (ListenerRecord record : mListenerRecords) {
-                    if (record.mType == device.getType()
-                            && record.mListener.asBinder() == listener.asBinder()) {
-                        mListenerRecords.remove(record);
-                        device.removeListener(record.mListener);
-                        if (!device.hasListener()) {
-                            removeLogicalDeviceLocked(record.mType);
-                        }
-                        break;
-                    }
-                }
-            }
-        }
-
-        @Override
-        public void sendMessage(IBinder b, HdmiCecMessage message) {
-            enforceAccessPermission();
-            if (message == null) {
-                throw new IllegalArgumentException("message must not be null");
-            }
-            synchronized (mLock) {
-                HdmiCecDevice device = getLogicalDeviceLocked(b);
-                nativeSendMessage(mNativePtr, device.getType(), message.getDestination(),
-                        message.getOpcode(), message.getParams());
-            }
-        }
-
-        @Override
-        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-            if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
-                    != PackageManager.PERMISSION_GRANTED) {
-                pw.println("Permission denial: can't dump HdmiCecService from pid="
-                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
-                        + " without permission " + android.Manifest.permission.DUMP);
-                return;
-            }
-            final long ident = Binder.clearCallingIdentity();
-            try {
-                dumpInternal(pw);
-            } finally {
-                Binder.restoreCallingIdentity(ident);
-            }
-        }
-    }
-
-    private static native int nativeAllocateLogicalAddress(long handler, int deviceType);
-    private static native void nativeRemoveLogicalAddress(long handler, int deviceType);
-    private static native void nativeSendMessage(long handler, int deviceType, int destination,
-            int opcode, byte[] params);
-    private static native int nativeGetPhysicalAddress(long handler);
-    private static native void nativeSetOsdName(long handler, byte[] name);
-}
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 1c277a8..10a67c4 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -301,9 +301,8 @@
 
             Intent i = new Intent(TvInputService.SERVICE_INTERFACE).setComponent(
                     userState.inputMap.get(inputId).getComponent());
-            mContext.bindServiceAsUser(i, serviceState.mConnection, Context.BIND_AUTO_CREATE,
-                    new UserHandle(userId));
-            serviceState.mBound = true;
+            serviceState.mBound = mContext.bindServiceAsUser(
+                    i, serviceState.mConnection, Context.BIND_AUTO_CREATE, new UserHandle(userId));
         } else if (serviceState.mService != null && isStateEmpty) {
             // This means that the service is already connected but its state indicates that we have
             // nothing to do with it. Then, disconnect the service.
diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk
index 3cfb45b..db44d3a 100644
--- a/services/core/jni/Android.mk
+++ b/services/core/jni/Android.mk
@@ -12,7 +12,6 @@
     $(LOCAL_REL_DIR)/com_android_server_ConsumerIrService.cpp \
     $(LOCAL_REL_DIR)/com_android_server_dreams_McuHal.cpp \
     $(LOCAL_REL_DIR)/com_android_server_hdmi_HdmiCecController.cpp \
-    $(LOCAL_REL_DIR)/com_android_server_hdmi_HdmiCecService.cpp \
     $(LOCAL_REL_DIR)/com_android_server_hdmi_HdmiMhlController.cpp \
     $(LOCAL_REL_DIR)/com_android_server_input_InputApplicationHandle.cpp \
     $(LOCAL_REL_DIR)/com_android_server_input_InputManagerService.cpp \
diff --git a/services/core/jni/com_android_server_hdmi_HdmiCecService.cpp b/services/core/jni/com_android_server_hdmi_HdmiCecService.cpp
deleted file mode 100644
index 1d111a1..0000000
--- a/services/core/jni/com_android_server_hdmi_HdmiCecService.cpp
+++ /dev/null
@@ -1,756 +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.
- */
-
-#define LOG_TAG "HdmiCecJni"
-
-#define LOG_NDEBUG 1
-
-#include "ScopedPrimitiveArray.h"
-
-#include <string>
-#include <deque>
-#include <map>
-
-#include <android_runtime/AndroidRuntime.h>
-#include <android_runtime/Log.h>
-#include <hardware/hdmi_cec.h>
-
-namespace android {
-
-static struct {
-    jmethodID handleMessage;
-    jmethodID handleHotplug;
-    jmethodID getActiveSource;
-    jmethodID getLanguage;
-} gHdmiCecServiceClassInfo;
-
-#ifndef min
-#define min(a, b) ((a) > (b) ? (b) : (a))
-#endif
-
-class HdmiCecHandler {
-public:
-    enum HdmiCecError {
-        SUCCESS = 0,
-        FAILED = -1
-    };
-
-    // Data type to hold a CEC message or internal event data.
-    typedef union {
-        cec_message_t cec;
-        hotplug_event_t hotplug;
-    } queue_item_t;
-
-    // Entry used for message queue.
-    typedef std::pair<int, const queue_item_t> MessageEntry;
-
-    HdmiCecHandler(hdmi_cec_device_t* device, jobject callbacksObj);
-
-    void initialize();
-
-    // initialize individual logical device.
-    cec_logical_address_t initLogicalDevice(cec_device_type_t type);
-    void releaseLogicalDevice(cec_device_type_t type);
-
-    cec_logical_address_t getLogicalAddress(cec_device_type_t deviceType);
-    uint16_t getPhysicalAddress();
-    cec_device_type_t getDeviceType(cec_logical_address_t addr);
-    void queueMessage(const MessageEntry& message);
-    void queueOutgoingMessage(const cec_message_t& message);
-    void sendReportPhysicalAddress(cec_logical_address_t srcAddr);
-    void sendActiveSource(cec_logical_address_t srcAddr);
-    void sendFeatureAbort(cec_logical_address_t srcAddr, cec_logical_address_t dstAddr,
-            int opcode, int reason);
-    void sendCecVersion(cec_logical_address_t srcAddr, cec_logical_address_t dstAddr,
-            int version);
-    void sendDeviceVendorId(cec_logical_address_t srcAddr, cec_logical_address_t dstAddr);
-    void sendGiveDeviceVendorID(cec_logical_address_t srcAddr, cec_logical_address_t dstAddr);
-    void sendSetOsdName(cec_logical_address_t srcAddr, cec_logical_address_t dstAddr,
-            const char* name, size_t len);
-    void sendSetMenuLanguage(cec_logical_address_t srcAddr, cec_logical_address_t dstAddr);
-
-    void sendCecMessage(const cec_message_t& message);
-    void setOsdName(const char* name, size_t len);
-
-private:
-    enum {
-        EVENT_TYPE_RX,
-        EVENT_TYPE_TX,
-        EVENT_TYPE_HOTPLUG,
-        EVENT_TYPE_STANDBY
-    };
-
-    /*
-     * logical address pool for each device type.
-     */
-    static const cec_logical_address_t TV_ADDR_POOL[];
-    static const cec_logical_address_t PLAYBACK_ADDR_POOL[];
-    static const cec_logical_address_t RECORDER_ADDR_POOL[];
-    static const cec_logical_address_t TUNER_ADDR_POOL[];
-
-    static const unsigned int MAX_BUFFER_SIZE = 256;
-    static const uint16_t INVALID_PHYSICAL_ADDRESS = 0xFFFF;
-
-    static void onReceived(const hdmi_event_t* event, void* arg);
-    static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
-
-    void updatePhysicalAddress();
-    void updateLogicalAddress();
-
-    // Allocate logical address. The CEC standard recommends that we try to use the address
-    // we have ever used before, in case this is to allocate an address afte the cable is
-    // connected again. If preferredAddr is given a valid one (not CEC_ADDR_UNREGISTERED), then
-    // this method checks if the address is available first. If not, it tries other addresses
-    // int the address pool available for the given type.
-    cec_logical_address_t allocateLogicalAddress(cec_device_type_t type,
-            cec_logical_address_t preferredAddr);
-
-    // Send a CEC ping message. Returns true if successful.
-    bool sendPing(cec_logical_address_t addr);
-
-    // Return the pool of logical addresses that are used for a given device type.
-    // One of the addresses in the pool will be chosen in the allocation logic.
-    bool getLogicalAddressPool(cec_device_type_t type, const cec_logical_address_t** addrPool,
-            size_t* poolSize);
-
-    // Handles the message retrieved from internal message queue. The message can be
-    // for either rx or tx.
-    void dispatchMessage(const MessageEntry& message);
-    void processIncomingMessage(const cec_message_t& msg);
-
-    // Check the message before we pass it up to framework. If true, we proceed.
-    // otherwise do not propagate it.
-    bool precheckMessage(const cec_message_t& msg);
-
-    // Propagate the message up to Java layer.
-    void propagateMessage(const cec_message_t& msg);
-    void propagateHotplug(bool connected);
-
-    // Handles incoming <Request Active Source> message. If one of logical
-    // devices is active, it should reply with <Active Source> message.
-    void handleRequestActiveSource();
-    void handleGiveOsdName(const cec_message_t& msg);
-    void handleGiveDeviceVendorID(const cec_message_t& msg);
-    void handleGetCECVersion(const cec_message_t& msg);
-    void handleGetMenuLanguage(const cec_message_t& msg);
-
-    // Internal thread for message queue handler
-    class HdmiThread : public Thread {
-    public:
-        HdmiThread(HdmiCecHandler* hdmiCecHandler, bool canCallJava) :
-            Thread(canCallJava),
-            mHdmiCecHandler(hdmiCecHandler) {
-        }
-    private:
-        virtual bool threadLoop() {
-            ALOGV("HdmiThread started");
-            AutoMutex _l(mHdmiCecHandler->mMessageQueueLock);
-            mHdmiCecHandler->mMessageQueueCondition.wait(mHdmiCecHandler->mMessageQueueLock);
-            /* Process all messages in the queue */
-            while (mHdmiCecHandler->mMessageQueue.size() > 0) {
-                MessageEntry entry = mHdmiCecHandler->mMessageQueue.front();
-                mHdmiCecHandler->dispatchMessage(entry);
-            }
-            return true;
-        }
-
-        HdmiCecHandler* mHdmiCecHandler;
-    };
-
-    // device type -> logical address mapping
-    std::map<cec_device_type_t, cec_logical_address_t> mLogicalDevices;
-
-    hdmi_cec_device_t* mDevice;
-    jobject mCallbacksObj;
-    Mutex mLock;
-    Mutex mMessageQueueLock;
-    Condition mMessageQueueCondition;
-    sp<HdmiThread> mMessageQueueHandler;
-
-    std::deque<MessageEntry> mMessageQueue;
-    uint16_t mPhysicalAddress;
-    std::string mOsdName;
-};
-
-    const cec_logical_address_t HdmiCecHandler::TV_ADDR_POOL[] = {
-        CEC_ADDR_TV,
-        CEC_ADDR_FREE_USE,
-    };
-
-    const cec_logical_address_t HdmiCecHandler::PLAYBACK_ADDR_POOL[] = {
-        CEC_ADDR_PLAYBACK_1,
-        CEC_ADDR_PLAYBACK_2,
-        CEC_ADDR_PLAYBACK_3
-    };
-
-    const cec_logical_address_t HdmiCecHandler::RECORDER_ADDR_POOL[] = {
-        CEC_ADDR_RECORDER_1,
-        CEC_ADDR_RECORDER_2,
-        CEC_ADDR_RECORDER_3
-    };
-
-    const cec_logical_address_t HdmiCecHandler::TUNER_ADDR_POOL[] = {
-        CEC_ADDR_TUNER_1,
-        CEC_ADDR_TUNER_2,
-        CEC_ADDR_TUNER_3,
-        CEC_ADDR_TUNER_4
-    };
-
-HdmiCecHandler::HdmiCecHandler(hdmi_cec_device_t* device, jobject callbacksObj) :
-    mDevice(device),
-    mCallbacksObj(callbacksObj) {
-}
-
-void HdmiCecHandler::initialize() {
-    mDevice->register_event_callback(mDevice, HdmiCecHandler::onReceived, this);
-    mMessageQueueHandler = new HdmiThread(this, true /* canCallJava */);
-    mMessageQueueHandler->run("MessageHandler");
-    updatePhysicalAddress();
-}
-
-uint16_t HdmiCecHandler::getPhysicalAddress() {
-    return mPhysicalAddress;
-}
-
-cec_logical_address_t HdmiCecHandler::initLogicalDevice(cec_device_type_t type) {
-    cec_logical_address addr = allocateLogicalAddress(type, CEC_ADDR_UNREGISTERED);
-    if (addr != CEC_ADDR_UNREGISTERED && !mDevice->add_logical_address(mDevice, addr)) {
-        mLogicalDevices.insert(std::pair<cec_device_type_t, cec_logical_address_t>(type, addr));
-
-        // Broadcast <Report Physical Address> when a new logical address was allocated to let
-        // other devices discover the new logical device and its logical - physical address
-        // association.
-        sendReportPhysicalAddress(addr);
-    }
-    return addr;
-}
-
-void HdmiCecHandler::releaseLogicalDevice(cec_device_type_t type) {
-    std::map<cec_device_type_t, cec_logical_address_t>::iterator it = mLogicalDevices.find(type);
-    if (it != mLogicalDevices.end()) {
-        mLogicalDevices.erase(it);
-    }
-    // TODO: remove the address monitored in HAL as well.
-}
-
-cec_logical_address_t HdmiCecHandler::getLogicalAddress(cec_device_type_t type) {
-    std::map<cec_device_type_t, cec_logical_address_t>::iterator it = mLogicalDevices.find(type);
-    if (it != mLogicalDevices.end()) {
-        return it->second;
-    }
-    return CEC_ADDR_UNREGISTERED;
-}
-
-cec_device_type_t HdmiCecHandler::getDeviceType(cec_logical_address_t addr) {
-    std::map<cec_device_type_t, cec_logical_address_t>::iterator it = mLogicalDevices.begin();
-    for (; it != mLogicalDevices.end(); ++it) {
-        if (it->second == addr) {
-            return it->first;
-        }
-    }
-    return CEC_DEVICE_INACTIVE;
-}
-
-void HdmiCecHandler::queueMessage(const MessageEntry& entry) {
-    AutoMutex _l(mMessageQueueLock);
-    if (mMessageQueue.size() <=  MAX_BUFFER_SIZE) {
-        mMessageQueue.push_back(entry);
-        mMessageQueueCondition.signal();
-    } else {
-        ALOGW("Queue is full! Message dropped.");
-    }
-}
-
-void HdmiCecHandler::queueOutgoingMessage(const cec_message_t& message) {
-    queue_item_t item;
-    item.cec = message;
-    MessageEntry entry = std::make_pair(EVENT_TYPE_TX, item);
-    queueMessage(entry);
-}
-
-void HdmiCecHandler::sendReportPhysicalAddress(cec_logical_address_t addr) {
-    if (mPhysicalAddress == INVALID_PHYSICAL_ADDRESS) {
-        ALOGE("Invalid physical address.");
-        return;
-    }
-    cec_device_type_t deviceType = getDeviceType(addr);
-    if (deviceType == CEC_DEVICE_INACTIVE) {
-        ALOGE("Invalid logical address: %d", addr);
-        return;
-    }
-
-    cec_message_t msg;
-    msg.initiator = addr;
-    msg.destination = CEC_ADDR_BROADCAST;
-    msg.length = 4;
-    msg.body[0] = CEC_MESSAGE_REPORT_PHYSICAL_ADDRESS;
-    msg.body[1] = (mPhysicalAddress >> 8) & 0xff;
-    msg.body[2] = mPhysicalAddress & 0xff;
-    msg.body[3] = deviceType;
-    queueOutgoingMessage(msg);
-}
-
-void HdmiCecHandler::sendActiveSource(cec_logical_address_t srcAddr) {
-    if (mPhysicalAddress == INVALID_PHYSICAL_ADDRESS) {
-        ALOGE("Error getting physical address.");
-        return;
-    }
-    cec_message_t msg;
-    msg.initiator = srcAddr;
-    msg.destination = CEC_ADDR_BROADCAST;
-    msg.length = 3;
-    msg.body[0] = CEC_MESSAGE_ACTIVE_SOURCE;
-    msg.body[1] = (mPhysicalAddress >> 8) & 0xff;
-    msg.body[2] = mPhysicalAddress & 0xff;
-    queueOutgoingMessage(msg);
-}
-
-void HdmiCecHandler::sendFeatureAbort(cec_logical_address_t srcAddr,
-        cec_logical_address_t dstAddr, int opcode, int reason) {
-    cec_message_t msg;
-    msg.initiator = srcAddr;
-    msg.destination = dstAddr;
-    msg.length = 3;
-    msg.body[0] = CEC_MESSAGE_FEATURE_ABORT;
-    msg.body[1] = opcode;
-    msg.body[2] = reason;
-    queueOutgoingMessage(msg);
-}
-
-void HdmiCecHandler::sendCecVersion(cec_logical_address_t srcAddr,
-        cec_logical_address_t dstAddr, int version) {
-    cec_message_t msg;
-    msg.initiator = srcAddr;
-    msg.destination = dstAddr;
-    msg.length = 2;
-    msg.body[0] = CEC_MESSAGE_CEC_VERSION;
-    msg.body[1] = version;
-    queueOutgoingMessage(msg);
-}
-
-void HdmiCecHandler::sendGiveDeviceVendorID(cec_logical_address_t srcAddr,
-        cec_logical_address_t dstAddr) {
-    cec_message_t msg;
-    msg.initiator = srcAddr;
-    msg.destination = dstAddr;
-    msg.length = 1;
-    msg.body[0] = CEC_MESSAGE_GIVE_DEVICE_VENDOR_ID;
-    queueOutgoingMessage(msg);
-}
-
-void HdmiCecHandler::sendDeviceVendorId(cec_logical_address_t srcAddr,
-        cec_logical_address_t dstAddr) {
-    cec_message_t msg;
-    msg.initiator = srcAddr;
-    msg.destination = dstAddr;
-    msg.length = 4;
-    msg.body[0] = CEC_MESSAGE_DEVICE_VENDOR_ID;
-    uint32_t vendor_id;
-    mDevice->get_vendor_id(mDevice, &vendor_id);
-    msg.body[1] = (vendor_id >> 16) & 0xff;
-    msg.body[2] = (vendor_id >> 8) & 0xff;
-    msg.body[3] = vendor_id & 0xff;
-    queueOutgoingMessage(msg);
-}
-
-void HdmiCecHandler::sendSetOsdName(cec_logical_address_t srcAddr, cec_logical_address_t dstAddr,
-        const char* name, size_t len) {
-    cec_message_t msg;
-    msg.initiator = srcAddr;
-    msg.destination = dstAddr;
-    msg.body[0] = CEC_MESSAGE_SET_OSD_NAME;
-    msg.length = min(len + 1, CEC_MESSAGE_BODY_MAX_LENGTH);
-    std::memcpy(msg.body + 1, name, msg.length - 1);
-    queueOutgoingMessage(msg);
-}
-
-void HdmiCecHandler::sendSetMenuLanguage(cec_logical_address_t srcAddr,
-        cec_logical_address_t dstAddr) {
-    char lang[4];   // buffer for 3-letter language code
-    JNIEnv* env = AndroidRuntime::getJNIEnv();
-    jstring res = (jstring) env->CallObjectMethod(mCallbacksObj,
-            gHdmiCecServiceClassInfo.getLanguage,
-            getDeviceType(srcAddr));
-    const char *clang = env->GetStringUTFChars(res, NULL);
-    strlcpy(lang, clang, sizeof(lang));
-    env->ReleaseStringUTFChars(res, clang);
-
-    cec_message_t msg;
-    msg.initiator = srcAddr;
-    msg.destination = dstAddr;
-    msg.length = 4;  // opcode (1) + language code (3)
-    msg.body[0] = CEC_MESSAGE_SET_MENU_LANGUAGE;
-    std::memcpy(msg.body + 1, lang, 3);
-    queueOutgoingMessage(msg);
-    checkAndClearExceptionFromCallback(env, __FUNCTION__);
-}
-
-void HdmiCecHandler::sendCecMessage(const cec_message_t& message) {
-    AutoMutex _l(mLock);
-    ALOGV("sendCecMessage");
-    mDevice->send_message(mDevice, &message);
-}
-
-void HdmiCecHandler::setOsdName(const char* name, size_t len) {
-    mOsdName.assign(name, min(len, CEC_MESSAGE_BODY_MAX_LENGTH - 1));
-}
-
-// static
-void HdmiCecHandler::onReceived(const hdmi_event_t* event, void* arg) {
-    HdmiCecHandler* handler = static_cast<HdmiCecHandler*>(arg);
-    if (handler == NULL) {
-        return;
-    }
-    queue_item_t item;
-    if (event->type == HDMI_EVENT_CEC_MESSAGE) {
-        item.cec = event->cec;
-        MessageEntry entry = std::make_pair<int, const queue_item_t>(EVENT_TYPE_RX, item);
-        handler->queueMessage(entry);
-    } else if (event->type == HDMI_EVENT_HOT_PLUG) {
-        item.hotplug = event->hotplug;
-        MessageEntry entry = std::make_pair<int, const queue_item_t>(EVENT_TYPE_HOTPLUG, item);
-        handler->queueMessage(entry);
-    }
-}
-
-// static
-void HdmiCecHandler::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
-    if (env->ExceptionCheck()) {
-        ALOGE("An exception was thrown by callback '%s'.", methodName);
-        LOGE_EX(env);
-        env->ExceptionClear();
-    }
-}
-
-void HdmiCecHandler::updatePhysicalAddress() {
-    uint16_t addr;
-    if (!mDevice->get_physical_address(mDevice, &addr)) {
-        mPhysicalAddress = addr;
-    } else {
-        mPhysicalAddress = INVALID_PHYSICAL_ADDRESS;
-    }
-}
-
-void HdmiCecHandler::updateLogicalAddress() {
-    mDevice->clear_logical_address(mDevice);
-    std::map<cec_device_type_t, cec_logical_address_t>::iterator it = mLogicalDevices.begin();
-    for (; it != mLogicalDevices.end(); ++it) {
-        cec_logical_address_t addr;
-        cec_logical_address_t preferredAddr = it->second;
-        cec_device_type_t deviceType = it->first;
-        addr = allocateLogicalAddress(deviceType, preferredAddr);
-        if (!mDevice->add_logical_address(mDevice, addr)) {
-            it->second = addr;
-        } else {
-            it->second = CEC_ADDR_UNREGISTERED;
-        }
-    }
-}
-
-cec_logical_address_t HdmiCecHandler::allocateLogicalAddress(cec_device_type_t type,
-        cec_logical_address_t preferredAddr) {
-    const cec_logical_address_t* addrPool;
-    size_t poolSize;
-    if (getLogicalAddressPool(type, &addrPool, &poolSize) < 0) {
-        return CEC_ADDR_UNREGISTERED;
-    }
-    unsigned start = 0;
-
-    // Find the index of preferred address in the pool. If not found, the start
-    // position will be 0. This happens when the passed preferredAddr is set to
-    // CEC_ADDR_UNREGISTERED, meaning that no preferred address is given.
-    for (unsigned i = 0; i < poolSize; i++) {
-        if (addrPool[i] == preferredAddr) {
-            start = i;
-            break;
-        }
-    }
-    for (unsigned i = 0; i < poolSize; i++) {
-        cec_logical_address_t addr = addrPool[(start + i) % poolSize];
-        if (!sendPing(addr)) {
-            // Failure in pinging means the address is available, not taken by any device.
-            ALOGV("Logical Address Allocation success: %d", addr);
-            return addr;
-        }
-    }
-    ALOGE("Logical Address Allocation failed");
-    return CEC_ADDR_UNREGISTERED;
-}
-
-bool HdmiCecHandler::sendPing(cec_logical_address addr) {
-    cec_message_t msg;
-    msg.initiator = msg.destination = addr;
-    msg.length = 0;
-    return !mDevice->send_message(mDevice, &msg);
-
-}
-
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-
-bool HdmiCecHandler::getLogicalAddressPool(cec_device_type_t deviceType,
-        const cec_logical_address_t** addrPool, size_t* poolSize) {
-    switch (deviceType) {
-    case CEC_DEVICE_TV:
-        *addrPool = TV_ADDR_POOL;
-        *poolSize = ARRAY_SIZE(TV_ADDR_POOL);
-        break;
-    case CEC_DEVICE_RECORDER:
-        *addrPool = RECORDER_ADDR_POOL;
-        *poolSize = ARRAY_SIZE(RECORDER_ADDR_POOL);
-        break;
-    case CEC_DEVICE_TUNER:
-        *addrPool = TUNER_ADDR_POOL;
-        *poolSize = ARRAY_SIZE(TUNER_ADDR_POOL);
-        break;
-    case CEC_DEVICE_PLAYBACK:
-        *addrPool = PLAYBACK_ADDR_POOL;
-        *poolSize = ARRAY_SIZE(PLAYBACK_ADDR_POOL);
-        break;
-    default:
-        ALOGE("Unsupported device type: %d", deviceType);
-        return false;
-    }
-    return true;
-}
-
-#undef ARRAY_SIZE
-
-void HdmiCecHandler::dispatchMessage(const MessageEntry& entry) {
-    int type = entry.first;
-    mMessageQueueLock.unlock();
-    if (type == EVENT_TYPE_RX) {
-        mMessageQueue.pop_front();
-        processIncomingMessage(entry.second.cec);
-    } else if (type == EVENT_TYPE_TX) {
-        sendCecMessage(entry.second.cec);
-        mMessageQueue.pop_front();
-    } else if (type == EVENT_TYPE_HOTPLUG) {
-        mMessageQueue.pop_front();
-        bool connected = entry.second.hotplug.connected;
-        if (connected) {
-            updatePhysicalAddress();
-            updateLogicalAddress();
-        }
-        propagateHotplug(connected);
-    }
-    mMessageQueueLock.lock();
-}
-
-void HdmiCecHandler::processIncomingMessage(const cec_message_t& msg) {
-    int opcode = msg.body[0];
-    if (opcode == CEC_MESSAGE_GIVE_PHYSICAL_ADDRESS) {
-        sendReportPhysicalAddress(msg.destination);
-    } else if (opcode == CEC_MESSAGE_REQUEST_ACTIVE_SOURCE) {
-        handleRequestActiveSource();
-    } else if (opcode == CEC_MESSAGE_GIVE_OSD_NAME) {
-        handleGiveOsdName(msg);
-    } else if (opcode == CEC_MESSAGE_GIVE_DEVICE_VENDOR_ID) {
-        handleGiveDeviceVendorID(msg);
-    } else if (opcode == CEC_MESSAGE_GET_CEC_VERSION) {
-        handleGetCECVersion(msg);
-    } else if (opcode == CEC_MESSAGE_GET_MENU_LANGUAGE) {
-        handleGetMenuLanguage(msg);
-    } else if (opcode == CEC_MESSAGE_ABORT) {
-        // Compliance testing requires that abort message be responded with feature abort.
-        sendFeatureAbort(msg.destination, msg.initiator, msg.body[0], ABORT_REFUSED);
-    } else {
-        if (precheckMessage(msg)) {
-            propagateMessage(msg);
-        }
-    }
-}
-
-bool HdmiCecHandler::precheckMessage(const cec_message_t& msg) {
-    // Check if this is the broadcast message coming to itself, which need not be passed
-    // back to framework. This happens because CEC spec specifies that a physical device
-    // may host multiple logical devices. A broadcast message sent by one of them therefore
-    // should be able to reach the others by the loopback mechanism.
-    //
-    // Currently we don't deal with multiple logical devices, so this is not necessary.
-    // It should be revisited once we support hosting multiple logical devices.
-    int opcode = msg.body[0];
-    if (msg.destination == CEC_ADDR_BROADCAST &&
-            (opcode == CEC_MESSAGE_ACTIVE_SOURCE ||
-             opcode == CEC_MESSAGE_SET_STREAM_PATH ||
-             opcode == CEC_MESSAGE_INACTIVE_SOURCE)) {
-        uint16_t senderAddr = (msg.body[1] << 8) + msg.body[2];
-        if (senderAddr == mPhysicalAddress) {
-            return false;
-        }
-    }
-    return true;
-}
-
-void HdmiCecHandler::propagateMessage(const cec_message_t& msg) {
-    int paramLen = msg.length - 1;
-    jint srcAddr = msg.initiator;
-    jint dstAddr = msg.destination;
-    jint opcode = msg.body[0];
-    JNIEnv* env = AndroidRuntime::getJNIEnv();
-    jbyteArray params = env->NewByteArray(paramLen);
-    const jbyte* body = reinterpret_cast<const jbyte *>(msg.body + 1);
-    if (paramLen > 0) {
-        env->SetByteArrayRegion(params, 0, paramLen, body);
-    }
-    env->CallVoidMethod(mCallbacksObj,
-            gHdmiCecServiceClassInfo.handleMessage,
-            srcAddr, dstAddr, opcode, params);
-    env->DeleteLocalRef(params);
-    checkAndClearExceptionFromCallback(env, __FUNCTION__);
-}
-
-void HdmiCecHandler::propagateHotplug(bool connected) {
-    JNIEnv* env = AndroidRuntime::getJNIEnv();
-    env->CallVoidMethod(mCallbacksObj,
-            gHdmiCecServiceClassInfo.handleHotplug,
-            connected);
-    checkAndClearExceptionFromCallback(env, __FUNCTION__);
-}
-
-
-void HdmiCecHandler::handleRequestActiveSource() {
-    JNIEnv* env = AndroidRuntime::getJNIEnv();
-    jint activeDeviceType = env->CallIntMethod(mCallbacksObj,
-            gHdmiCecServiceClassInfo.getActiveSource);
-    if (activeDeviceType != CEC_DEVICE_INACTIVE) {
-        sendActiveSource(getLogicalAddress(static_cast<cec_device_type_t>(activeDeviceType)));
-    }
-    checkAndClearExceptionFromCallback(env, __FUNCTION__);
-}
-
-void HdmiCecHandler::handleGiveOsdName(const cec_message_t& msg) {
-    if (!mOsdName.empty()) {
-        sendSetOsdName(msg.destination, msg.initiator, mOsdName.c_str(), mOsdName.length());
-    }
-}
-
-void HdmiCecHandler::handleGiveDeviceVendorID(const cec_message_t& msg) {
-    sendDeviceVendorId(msg.destination, msg.initiator);
-}
-
-void HdmiCecHandler::handleGetCECVersion(const cec_message_t& msg) {
-    int version;
-    mDevice->get_version(mDevice, &version);
-    sendCecVersion(msg.destination, msg.initiator, version);
-}
-
-void HdmiCecHandler::handleGetMenuLanguage(const cec_message_t& msg) {
-    sendSetMenuLanguage(msg.destination, msg.initiator);
-}
-
-//------------------------------------------------------------------------------
-
-#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
-        var = env->GetMethodID(clazz, methodName, methodDescriptor); \
-        LOG_FATAL_IF(! var, "Unable to find method " methodName);
-
-static jlong nativeInit(JNIEnv* env, jclass clazz, jobject callbacksObj) {
-    int err;
-    hw_module_t* module;
-    err = hw_get_module(HDMI_CEC_HARDWARE_MODULE_ID, const_cast<const hw_module_t **>(&module));
-    if (err != 0) {
-        ALOGE("Error acquiring hardware module: %d", err);
-        return 0;
-    }
-    hw_device_t* device;
-    err = module->methods->open(module, HDMI_CEC_HARDWARE_INTERFACE, &device);
-    if (err != 0) {
-        ALOGE("Error opening hardware module: %d", err);
-        return 0;
-    }
-    HdmiCecHandler *handler = new HdmiCecHandler(reinterpret_cast<hdmi_cec_device *>(device),
-            env->NewGlobalRef(callbacksObj));
-    handler->initialize();
-
-    GET_METHOD_ID(gHdmiCecServiceClassInfo.handleMessage, clazz,
-            "handleMessage", "(III[B)V");
-    GET_METHOD_ID(gHdmiCecServiceClassInfo.handleHotplug, clazz,
-            "handleHotplug", "(Z)V");
-    GET_METHOD_ID(gHdmiCecServiceClassInfo.getActiveSource, clazz,
-            "getActiveSource", "()I");
-    GET_METHOD_ID(gHdmiCecServiceClassInfo.getLanguage, clazz,
-            "getLanguage", "(I)Ljava/lang/String;");
-
-    return reinterpret_cast<jlong>(handler);
-}
-
-static void nativeSendMessage(JNIEnv* env, jclass clazz, jlong handlerPtr, jint deviceType,
-        jint dstAddr, jint opcode, jbyteArray params) {
-    HdmiCecHandler *handler = reinterpret_cast<HdmiCecHandler *>(handlerPtr);
-    cec_logical_address_t srcAddr = handler->getLogicalAddress(
-            static_cast<cec_device_type_t>(deviceType));
-    jsize len = env->GetArrayLength(params);
-    ScopedByteArrayRO paramsPtr(env, params);
-    cec_message_t message;
-    message.initiator = srcAddr;
-    message.destination = static_cast<cec_logical_address_t>(dstAddr);
-    message.length = min(len + 1, CEC_MESSAGE_BODY_MAX_LENGTH);
-    message.body[0] = opcode;
-    std::memcpy(message.body + 1, paramsPtr.get(), message.length - 1);
-    handler->sendCecMessage(message);
-}
-
-static jint nativeAllocateLogicalAddress(JNIEnv* env, jclass clazz, jlong handlerPtr,
-        jint deviceType) {
-    HdmiCecHandler *handler = reinterpret_cast<HdmiCecHandler *>(handlerPtr);
-    return handler->initLogicalDevice(static_cast<cec_device_type_t>(deviceType));
-}
-
-static void nativeRemoveLogicalAddress(JNIEnv* env, jclass clazz, jlong handlerPtr,
-       jint deviceType) {
-    HdmiCecHandler *handler = reinterpret_cast<HdmiCecHandler *>(handlerPtr);
-    return handler->releaseLogicalDevice(static_cast<cec_device_type_t>(deviceType));
-}
-
-static jint nativeGetPhysicalAddress(JNIEnv* env, jclass clazz, jlong handlerPtr) {
-    HdmiCecHandler *handler = reinterpret_cast<HdmiCecHandler *>(handlerPtr);
-    return handler->getPhysicalAddress();
-}
-
-static void nativeSetOsdName(JNIEnv* env, jclass clazz, jlong handlerPtr, jbyteArray name) {
-    HdmiCecHandler *handler = reinterpret_cast<HdmiCecHandler *>(handlerPtr);
-    jsize len = env->GetArrayLength(name);
-    if (len > 0) {
-        ScopedByteArrayRO namePtr(env, name);
-        handler->setOsdName(reinterpret_cast<const char *>(namePtr.get()), len);
-    }
-}
-
-static JNINativeMethod sMethods[] = {
-    /* name, signature, funcPtr */
-    { "nativeInit", "(Lcom/android/server/hdmi/HdmiCecService;)J",
-            (void *)nativeInit },
-    { "nativeSendMessage", "(JIII[B)V",
-            (void *)nativeSendMessage },
-    { "nativeAllocateLogicalAddress", "(JI)I",
-            (void *)nativeAllocateLogicalAddress },
-    { "nativeRemoveLogicalAddress", "(JI)V",
-            (void *)nativeRemoveLogicalAddress },
-    { "nativeGetPhysicalAddress", "(J)I",
-            (void *)nativeGetPhysicalAddress },
-    { "nativeSetOsdName", "(J[B)V",
-            (void *)nativeSetOsdName },
-};
-
-#define CLASS_PATH "com/android/server/hdmi/HdmiCecService"
-
-int register_android_server_hdmi_HdmiCecService(JNIEnv* env) {
-    int res = jniRegisterNativeMethods(env, CLASS_PATH, sMethods, NELEM(sMethods));
-    LOG_FATAL_IF(res < 0, "Unable to register native methods.");
-    return 0;
-}
-
-}  /* namespace android */
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index bfa8286..a302104 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -39,7 +39,6 @@
 int register_android_server_connectivity_Vpn(JNIEnv* env);
 int register_android_server_dreams_McuHal(JNIEnv* env);
 int register_android_server_hdmi_HdmiCecController(JNIEnv* env);
-int register_android_server_hdmi_HdmiCecService(JNIEnv* env);
 int register_android_server_hdmi_HdmiMhlController(JNIEnv* env);
 int register_android_server_tv_TvInputHal(JNIEnv* env);
 };
@@ -76,8 +75,6 @@
     register_android_server_dreams_McuHal(env);
     register_android_server_BatteryStatsService(env);
     register_android_server_hdmi_HdmiCecController(env);
-    // TODO: remove this once replaces HdmiCecService with HdmiControlService.
-    register_android_server_hdmi_HdmiCecService(env);
     register_android_server_hdmi_HdmiMhlController(env);
     register_android_server_tv_TvInputHal(env);
 
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index e8b7b69..2aa1220 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -129,8 +129,6 @@
             "com.android.server.wifi.passpoint.PasspointService";
     private static final String WIFI_P2P_SERVICE_CLASS =
             "com.android.server.wifi.p2p.WifiP2pService";
-    private static final String HDMI_CEC_SERVICE_CLASS =
-            "com.android.server.hdmi.HdmiCecService";
     private static final String ETHERNET_SERVICE_CLASS =
             "com.android.server.ethernet.EthernetService";
     private static final String TASK_SERVICE_CLASS =
@@ -954,12 +952,6 @@
             }
 
             try {
-                mSystemServiceManager.startService(HDMI_CEC_SERVICE_CLASS);
-            } catch (Throwable e) {
-                reportWtf("starting HdmiCec Service", e);
-            }
-
-            try {
                 mSystemServiceManager.startService(HdmiControlService.class);
             } catch (Throwable e) {
                 reportWtf("starting HdmiControlService", e);
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index 12d5389..2028ff4 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -1457,9 +1457,9 @@
                         if (AaptConfig::isSameExcept(config, mconfig, ResTable_config::CONFIG_DENSITY)) {
                             // See if there is a better density resource
                             if (mconfig.density < bestDensity &&
-                                    mconfig.density > preferredDensity &&
+                                    mconfig.density >= preferredDensity &&
                                     bestDensity > preferredDensity) {
-                                // This density is between our best density and
+                                // This density is our preferred density, or between our best density and
                                 // the preferred density, therefore it is better.
                                 bestDensity = mconfig.density;
                             } else if (mconfig.density > bestDensity &&