diff -urN Original_4.4.4_r1/frameworks/av/.git/HEAD AndroidSource/frameworks/av/.git/HEAD
--- Original_4.4.4_r1/frameworks/av/.git/HEAD	2016-01-29 15:12:26.947488000 +0900
+++ AndroidSource/frameworks/av/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-66809dc49bec6cb6345c74d48d319c2a63c17ac6
Binary files Original_4.4.4_r1/frameworks/av/.git/index and AndroidSource/frameworks/av/.git/index differ
diff -urN Original_4.4.4_r1/frameworks/base/Android.mk AndroidSource/frameworks/base/Android.mk
--- Original_4.4.4_r1/frameworks/base/Android.mk	2016-01-29 15:12:27.311488000 +0900
+++ AndroidSource/frameworks/base/Android.mk	2016-03-04 14:12:40.000000000 +0900
@@ -52,6 +52,9 @@
 ## across process boundaries.
 ##
 ## READ ME: ########################################################
+
+	## ADDED END BY JH at 180th
+
 LOCAL_SRC_FILES += \
 	core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl \
 	core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl \
@@ -161,6 +164,7 @@
 	core/java/android/os/IUpdateLock.aidl \
 	core/java/android/os/IUserManager.aidl \
 	core/java/android/os/IVibratorService.aidl \
+	core/java/android/service/distribute/IDistributedComputingService.aidl \
 	core/java/android/service/notification/INotificationListener.aidl \
 	core/java/android/print/ILayoutResultCallback.aidl \
 	core/java/android/print/IPrinterDiscoveryObserver.aidl \
@@ -176,6 +180,9 @@
 	core/java/android/printservice/IPrintServiceClient.aidl \
 	core/java/android/service/dreams/IDreamManager.aidl \
 	core/java/android/service/dreams/IDreamService.aidl \
+	core/java/android/service/collaboroid/IGeneralMessageListener.aidl \
+	core/java/android/service/devicemanager/IDeviceManager.aidl \
+	core/java/android/service/remote/IRemoteService.aidl \
 	core/java/android/service/wallpaper/IWallpaperConnection.aidl \
 	core/java/android/service/wallpaper/IWallpaperEngine.aidl \
 	core/java/android/service/wallpaper/IWallpaperService.aidl \
diff -urN Original_4.4.4_r1/frameworks/base/api/current.txt AndroidSource/frameworks/base/api/current.txt
--- Original_4.4.4_r1/frameworks/base/api/current.txt	2016-01-29 15:12:27.367488000 +0900
+++ AndroidSource/frameworks/base/api/current.txt	2016-09-26 18:38:20.743663713 +0900
@@ -5978,13 +5978,16 @@
     field public static final java.lang.String BLUETOOTH_SERVICE = "bluetooth";
     field public static final java.lang.String CAPTIONING_SERVICE = "captioning";
     field public static final java.lang.String CLIPBOARD_SERVICE = "clipboard";
+    field public static final java.lang.String COLLABOROID = "collaboroid";
     field public static final java.lang.String CONNECTIVITY_SERVICE = "connectivity";
     field public static final java.lang.String CONSUMER_IR_SERVICE = "consumer_ir";
     field public static final int CONTEXT_IGNORE_SECURITY = 2; // 0x2
     field public static final int CONTEXT_INCLUDE_CODE = 1; // 0x1
     field public static final int CONTEXT_RESTRICTED = 4; // 0x4
+    field public static final java.lang.String DEVICE_MANAGEMENT_SERVICE = "devicemanagement";
     field public static final java.lang.String DEVICE_POLICY_SERVICE = "device_policy";
     field public static final java.lang.String DISPLAY_SERVICE = "display";
+    field public static final java.lang.String DISTRIBUTED_COMPUTING_SERVICE = "distribute";
     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 INPUT_METHOD_SERVICE = "input_method";
@@ -6004,6 +6007,7 @@
     field public static final java.lang.String NSD_SERVICE = "servicediscovery";
     field public static final java.lang.String POWER_SERVICE = "power";
     field public static final java.lang.String PRINT_SERVICE = "print";
+    field public static final java.lang.String REMOTE_SERVICE = "remote";
     field public static final java.lang.String SEARCH_SERVICE = "search";
     field public static final java.lang.String SENSOR_SERVICE = "sensor";
     field public static final java.lang.String STORAGE_SERVICE = "storage";
@@ -10735,6 +10739,7 @@
     field public static final int TYPE_PRESSURE = 6; // 0x6
     field public static final int TYPE_PROXIMITY = 8; // 0x8
     field public static final int TYPE_RELATIVE_HUMIDITY = 12; // 0xc
+    field public static final int TYPE_REMOTE_SENSOR = 21; // 0x15
     field public static final int TYPE_ROTATION_VECTOR = 11; // 0xb
     field public static final int TYPE_SIGNIFICANT_MOTION = 17; // 0x11
     field public static final int TYPE_STEP_COUNTER = 19; // 0x13
@@ -10745,6 +10750,7 @@
   public class SensorEvent {
     field public int accuracy;
     field public android.hardware.Sensor sensor;
+    field public int sourceDevice;
     field public long timestamp;
     field public final float[] values;
   }
@@ -11597,6 +11603,7 @@
     field public static final java.lang.String NETWORK_PROVIDER = "network";
     field public static final java.lang.String PASSIVE_PROVIDER = "passive";
     field public static final java.lang.String PROVIDERS_CHANGED_ACTION = "android.location.PROVIDERS_CHANGED";
+    field public static final java.lang.String REMOTE_PROVIDER = "remote";
   }
 
   public class LocationProvider {
@@ -12541,6 +12548,7 @@
     method public void addTimedTextSource(java.io.FileDescriptor, java.lang.String) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
     method public void addTimedTextSource(java.io.FileDescriptor, long, long, java.lang.String) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
     method public void attachAuxEffect(int);
+    method public void closing_all_serversockets();
     method public static android.media.MediaPlayer create(android.content.Context, android.net.Uri);
     method public static android.media.MediaPlayer create(android.content.Context, android.net.Uri, android.view.SurfaceHolder);
     method public static android.media.MediaPlayer create(android.content.Context, int);
@@ -12564,6 +12572,7 @@
     method public void setAudioStreamType(int);
     method public void setAuxEffectSendLevel(float);
     method public void setDataSource(android.content.Context, android.net.Uri) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
+    method public void setDataSource(android.content.Context, android.net.Uri, boolean) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
     method public void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
     method public void setDataSource(java.lang.String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
     method public void setDataSource(java.io.FileDescriptor) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
@@ -12606,6 +12615,8 @@
     field public static final java.lang.String MEDIA_MIMETYPE_TEXT_SUBRIP = "application/x-subrip";
     field public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT = 1; // 0x1
     field public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = 2; // 0x2
+    field public android.content.Context mContext;
+    field public android.media.MediaExtractor mMediaExtractor;
   }
 
   public static abstract interface MediaPlayer.OnBufferingUpdateListener {
@@ -21072,6 +21083,8 @@
     field public static final java.lang.String AUTO_TIME = "auto_time";
     field public static final java.lang.String AUTO_TIME_ZONE = "auto_time_zone";
     field public static final java.lang.String BLUETOOTH_ON = "bluetooth_on";
+    field public static final java.lang.String COLLABOROID_DEVICE_NAME = "collaboroid_device_name";
+    field public static final java.lang.String COLLABOROID_ON = "collaboroid_on";
     field public static final android.net.Uri CONTENT_URI;
     field public static final java.lang.String DATA_ROAMING = "data_roaming";
     field public static final java.lang.String DEBUG_APP = "debug_app";
@@ -21085,9 +21098,13 @@
     field public static final java.lang.String RADIO_CELL = "cell";
     field public static final java.lang.String RADIO_NFC = "nfc";
     field public static final java.lang.String RADIO_WIFI = "wifi";
+    field public static final java.lang.String REMOTE_REQUEST_CLIENT_ON = "remote_request_client_on";
+    field public static final java.lang.String REMOTE_REQUEST_SERVER_ON = "remote_request_server_on";
     field public static final java.lang.String SHOW_PROCESSES = "show_processes";
     field public static final java.lang.String STAY_ON_WHILE_PLUGGED_IN = "stay_on_while_plugged_in";
+    field public static final java.lang.String SYSTEM_SERVICE_ON = "system_service_on";
     field public static final java.lang.String SYS_PROP_SETTING_VERSION = "sys.settings_global_version";
+    field public static final java.lang.String TASK_EXECUTOR_ON = "task_executor_on";
     field public static final java.lang.String TRANSITION_ANIMATION_SCALE = "transition_animation_scale";
     field public static final java.lang.String USB_MASS_STORAGE_ENABLED = "usb_mass_storage_enabled";
     field public static final java.lang.String USE_GOOGLE_MAIL = "use_google_mail";
@@ -21790,7 +21807,7 @@
   }
 
   public class BaseObj {
-    method public synchronized void destroy();
+    method public void destroy();
     method public java.lang.String getName();
     method public void setName(java.lang.String);
   }
@@ -22657,6 +22674,140 @@
 
 }
 
+package android.service.collaboroid {
+
+  public class CollaboRoidManager {
+    ctor public CollaboRoidManager(android.content.Context);
+    method public void setCollaboRoidEnabled(boolean);
+    field public static final java.lang.String COLLABOROID_STATE_CHANGED_ACTION = "android.service.collaboroid.COLLABOROID_STATE_CHANGED";
+    field public static final int COLLABOROID_STATE_DISABLED = 1; // 0x1
+    field public static final int COLLABOROID_STATE_DISABLING = 0; // 0x0
+    field public static final int COLLABOROID_STATE_ENABLED = 3; // 0x3
+    field public static final int COLLABOROID_STATE_ENABLING = 2; // 0x2
+    field public static final int COLLABOROID_STATE_UNKNOWN = 4; // 0x4
+    field public static final java.lang.String EXTRA_COLLABOROID_STATE = "collaboroid_state";
+  }
+
+  public abstract interface IGeneralMessageListener implements android.os.IInterface {
+    method public abstract void onMessageReceived(java.lang.String) throws android.os.RemoteException;
+  }
+
+  public static abstract class IGeneralMessageListener.Stub extends android.os.Binder implements android.service.collaboroid.IGeneralMessageListener {
+    ctor public IGeneralMessageListener.Stub();
+    method public android.os.IBinder asBinder();
+    method public static android.service.collaboroid.IGeneralMessageListener asInterface(android.os.IBinder);
+    method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
+  }
+
+}
+
+package android.service.devicemanager {
+
+  public class Device implements android.os.Parcelable {
+    ctor public Device(java.lang.String, java.lang.String, java.lang.String, int, int);
+    ctor public Device();
+    method public int describeContents();
+    method public void initDevice();
+    method public void setAllowedResources(int[]);
+    method public void setAskedResources(int[]);
+    method public void updateDevice(java.lang.String, java.lang.String, java.lang.String, int, int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final int RESOURCE_TYPE_AUDIO = 5; // 0x5
+    field public static final int RESOURCE_TYPE_KEY = 1; // 0x1
+    field public static final int RESOURCE_TYPE_LOCATION = 3; // 0x3
+    field public static final int RESOURCE_TYPE_SENSOR = 2; // 0x2
+    field public static final int RESOURCE_TYPE_SIZE = 7; // 0x7
+    field public static final int RESOURCE_TYPE_TOUCH = 0; // 0x0
+    field public static final int RESOURCE_TYPE_VIBRATOR = 6; // 0x6
+    field public static final int RESOURCE_TYPE_VIDEO = 4; // 0x4
+    field public static final java.lang.String[] ResourceNames;
+    field public final int SYSTEM_SERVICE_LIST;
+    field public final int TASK_EXECUTOR_LIST;
+    field public int[] allowedResources;
+    field public int[] askedResources;
+    field public java.lang.String deviceName;
+    field public java.lang.String idleCpu;
+    field public java.lang.String ipaddress;
+    field public int isSystemServiceOn;
+    field public int isTaskExecutorOn;
+  }
+
+  public class DeviceList {
+    ctor public DeviceList();
+    method public static java.util.HashMap<java.lang.String, android.service.devicemanager.Device> getDevices();
+    method public static void setDevices(java.util.HashMap<java.lang.String, android.service.devicemanager.Device>);
+  }
+
+  public class DeviceManager {
+    ctor public DeviceManager(android.service.devicemanager.IDeviceManager);
+    ctor public DeviceManager(android.content.Context);
+    ctor public DeviceManager();
+    method public void allowResources(java.lang.String, int[]);
+    method public void askResources(java.util.List<android.service.devicemanager.Device>);
+    method public void constructCluster(java.util.List<android.service.devicemanager.Device>);
+    method public android.service.devicemanager.Device getDevice(java.lang.String);
+    method public java.util.List<android.service.devicemanager.Device> getDeviceList(int);
+    method public int getNumofConfiguredDevices();
+    method public java.lang.String[] getSystemServiceOnServerList();
+    method public java.lang.String[] getTaskExecutorOnServerList();
+    method public java.lang.String recommendDevice(java.util.List<android.service.devicemanager.Device>);
+  }
+
+  public abstract interface IDeviceManager implements android.os.IInterface {
+    method public abstract void allowResources(java.lang.String, int[]) throws android.os.RemoteException;
+    method public abstract void askResources(java.util.List<android.service.devicemanager.Device>) throws android.os.RemoteException;
+    method public abstract void constructCluster(java.util.List<android.service.devicemanager.Device>) throws android.os.RemoteException;
+    method public abstract android.service.devicemanager.Device getDevice(java.lang.String) throws android.os.RemoteException;
+    method public abstract java.util.List<android.service.devicemanager.Device> getDeviceList(int) throws android.os.RemoteException;
+    method public abstract int getNumofConfiguredDevices() throws android.os.RemoteException;
+    method public abstract java.lang.String[] getSystemServiceOnServerList() throws android.os.RemoteException;
+    method public abstract java.lang.String[] getTaskExecutorOnServerList() throws android.os.RemoteException;
+    method public abstract void initDevices() throws android.os.RemoteException;
+    method public abstract boolean isAllowedForResource(java.lang.String, int) throws android.os.RemoteException;
+    method public abstract java.lang.String recommendDevice(java.util.List<android.service.devicemanager.Device>) throws android.os.RemoteException;
+    method public abstract void showRequestDialog(java.lang.String, java.lang.String, int[]) throws android.os.RemoteException;
+  }
+
+  public static abstract class IDeviceManager.Stub extends android.os.Binder implements android.service.devicemanager.IDeviceManager {
+    ctor public IDeviceManager.Stub();
+    method public android.os.IBinder asBinder();
+    method public static android.service.devicemanager.IDeviceManager asInterface(android.os.IBinder);
+    method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
+  }
+
+}
+
+package android.service.distribute {
+
+  public class Distributor {
+    ctor public Distributor(android.service.distribute.IDistributedComputingService);
+    ctor public Distributor();
+    ctor public Distributor(android.content.Context);
+    method public void startJobManager(java.lang.String);
+    method public void startTaskExecutor();
+    method public int sum(int, int);
+    method public void testOperation();
+  }
+
+  public abstract interface IDistributedComputingService implements android.os.IInterface {
+    method public abstract void startJobManager(java.lang.String) throws android.os.RemoteException;
+    method public abstract void startTaskExecutor() throws android.os.RemoteException;
+    method public abstract void stopJobManager() throws android.os.RemoteException;
+    method public abstract void stopTaskExecutor() throws android.os.RemoteException;
+    method public abstract int sum(int, int) throws android.os.RemoteException;
+    method public abstract void testOperation() throws android.os.RemoteException;
+  }
+
+  public static abstract class IDistributedComputingService.Stub extends android.os.Binder implements android.service.distribute.IDistributedComputingService {
+    ctor public IDistributedComputingService.Stub();
+    method public android.os.IBinder asBinder();
+    method public static android.service.distribute.IDistributedComputingService asInterface(android.os.IBinder);
+    method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
+  }
+
+}
+
 package android.service.dreams {
 
   public class DreamService extends android.app.Service implements android.view.Window.Callback {
@@ -22737,6 +22888,156 @@
 
 }
 
+package android.service.remote {
+
+  public class AppendingObjectOutputStream extends java.io.ObjectOutputStream {
+    ctor public AppendingObjectOutputStream(java.io.OutputStream) throws java.io.IOException;
+  }
+
+  public abstract interface IRemoteService implements android.os.IInterface {
+    method public abstract void addSensorHandle(int, int) throws android.os.RemoteException;
+    method public abstract boolean connectToServer(java.lang.String) throws android.os.RemoteException;
+    method public abstract void disconnectToServer() throws android.os.RemoteException;
+    method public abstract java.util.List<java.lang.String> getClientIPs() throws android.os.RemoteException;
+    method public abstract java.util.List<java.lang.String> getServerIPs() throws android.os.RemoteException;
+    method public abstract int getVideoPlayers() throws android.os.RemoteException;
+    method public abstract void initConnections() throws android.os.RemoteException;
+    method public abstract boolean isAllowedForResource(java.lang.String, java.lang.String, int[]) throws android.os.RemoteException;
+    method public abstract boolean isServerOn() throws android.os.RemoteException;
+    method public abstract void launchDummyApp() throws android.os.RemoteException;
+    method public abstract void playMusic() throws android.os.RemoteException;
+    method public abstract void printServerIPs() throws android.os.RemoteException;
+    method public abstract void registerListener(android.service.collaboroid.IGeneralMessageListener) throws android.os.RemoteException;
+    method public abstract void removeSensorHandle(int) throws android.os.RemoteException;
+    method public abstract void requestMotionEvents() throws android.os.RemoteException;
+    method public abstract boolean respondAllowedResources(java.lang.String, int[]) throws android.os.RemoteException;
+    method public abstract void sendAllMusic(int, byte[], long) throws android.os.RemoteException;
+    method public abstract void sendAllrequest(android.service.remote.RemoteRequest) throws android.os.RemoteException;
+    method public abstract void sendAllrequestVib(android.service.remote.RemoteRequest) throws android.os.RemoteException;
+    method public abstract void sendKeyEvent(android.view.KeyEvent) throws android.os.RemoteException;
+    method public abstract void sendLocation(android.location.Location) throws android.os.RemoteException;
+    method public abstract void sendMotionEvent(android.view.MotionEvent) throws android.os.RemoteException;
+    method public abstract void sendMusicData(int, byte[], long) throws android.os.RemoteException;
+    method public abstract boolean sendRequest(android.service.remote.RemoteRequest) throws android.os.RemoteException;
+    method public abstract boolean sendResourceRequests(java.util.List<android.service.devicemanager.Device>) throws android.os.RemoteException;
+    method public abstract void sendSensorEvent(int, int, float[], int, long) throws android.os.RemoteException;
+    method public abstract void sendVideoSignal(int) throws android.os.RemoteException;
+    method public abstract void setConfiguration() throws android.os.RemoteException;
+    method public abstract void setEnabled(boolean) throws android.os.RemoteException;
+    method public abstract boolean startServer() throws android.os.RemoteException;
+    method public abstract boolean stopServer() throws android.os.RemoteException;
+    method public abstract void testKey() throws android.os.RemoteException;
+    method public abstract void testLocation() throws android.os.RemoteException;
+    method public abstract void testMusic() throws android.os.RemoteException;
+    method public abstract void testOperation() throws android.os.RemoteException;
+    method public abstract void testSensor() throws android.os.RemoteException;
+    method public abstract void testTouch() throws android.os.RemoteException;
+    method public abstract void testVibrate() throws android.os.RemoteException;
+    method public abstract void testVideo() throws android.os.RemoteException;
+    method public abstract void unregisterListener(android.service.collaboroid.IGeneralMessageListener) throws android.os.RemoteException;
+  }
+
+  public static abstract class IRemoteService.Stub extends android.os.Binder implements android.service.remote.IRemoteService {
+    ctor public IRemoteService.Stub();
+    method public android.os.IBinder asBinder();
+    method public static android.service.remote.IRemoteService asInterface(android.os.IBinder);
+    method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
+  }
+
+  public class RemoteRequest implements android.os.Parcelable java.io.Serializable {
+    ctor public RemoteRequest();
+    ctor public RemoteRequest(java.lang.String, java.lang.String, java.util.ArrayList<java.lang.Object>);
+    ctor public RemoteRequest(android.os.Parcel);
+    method public int describeContents();
+    method public java.lang.String getMethod();
+    method public java.util.ArrayList<java.lang.Object> getPara();
+    method public java.lang.String getType();
+    method public void set(java.lang.String, java.lang.String, java.util.ArrayList<java.lang.Object>);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
+  public static class RemoteRequest.RemoteKeyEvent implements java.io.Serializable {
+    ctor public RemoteRequest.RemoteKeyEvent(int, int, int);
+    ctor public RemoteRequest.RemoteKeyEvent(android.os.Parcel);
+    method public int getAction();
+    method public int getCode();
+    method public int getSource();
+  }
+
+  public class RemoteRequest2 implements android.os.Parcelable java.io.Serializable {
+    ctor public RemoteRequest2();
+    ctor public RemoteRequest2(java.lang.String, java.lang.String, java.util.ArrayList<java.lang.Object>);
+    ctor public RemoteRequest2(android.os.Parcel);
+    method public int describeContents();
+    method public java.lang.String getMethod();
+    method public java.util.ArrayList<java.lang.Object> getPara();
+    method public java.lang.String getType();
+    method public void set(java.lang.String, java.lang.String, java.util.ArrayList<java.lang.Object>);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
+  public class RemoteServiceManager {
+    ctor public RemoteServiceManager(android.service.remote.IRemoteService);
+    ctor public RemoteServiceManager();
+    ctor public RemoteServiceManager(android.content.Context);
+    method public void connectToServer(java.lang.String);
+    method public void disconnectToServer();
+    method public void launchDummyApp();
+    method public void printServerIPs();
+    method public void requestMotionEvents();
+    method public void sendAllMusic(int, byte[], long);
+    method public void sendAllrequest(android.service.remote.RemoteRequest);
+    method public void sendMusicData(int, byte[], long);
+    method public boolean sendRequest(android.service.remote.RemoteRequest);
+    method public void setConfiguration();
+    method public void setEnabled(boolean);
+    method public void startServer();
+    method public void stopServer();
+    method public void testKey();
+    method public void testLocation();
+    method public void testMusic();
+    method public void testOperation();
+    method public void testSensor();
+    method public void testTouch();
+    method public void testVibrate();
+    method public void testVideo();
+  }
+
+  public class SdPackage implements java.io.Serializable {
+    ctor public SdPackage(int, byte[], long);
+    ctor public SdPackage(java.lang.String, int, int, int, long, byte[]);
+    method public int getBitrate();
+    method public int getChannels();
+    method public long getDuration();
+    method public java.lang.String getMime();
+    method public long getPresentationTime();
+    method public byte[] getSampleData();
+    method public int getSampleRate();
+    method public int getSampleSize();
+    method public byte[] get_csd0();
+  }
+
+  public class vData implements java.io.Serializable {
+    ctor public vData();
+    ctor public vData(int, byte[], long);
+    method public int getHeight();
+    method public java.lang.String getMime();
+    method public long getPresentationTime();
+    method public byte[] getSampleData();
+    method public int getSampleSize();
+    method public int getWidth();
+    method public byte[] get_csd0();
+    method public byte[] get_csd1();
+    method public void setMediaFormat(java.lang.String, int, int, byte[], byte[]);
+    field public long presentationTime;
+    field public byte[] sampleData;
+    field public int sampleSize;
+  }
+
+}
+
 package android.service.textservice {
 
   public abstract class SpellCheckerService extends android.app.Service {
@@ -27146,6 +27447,7 @@
     method public final float getSize();
     method public final float getSize(int);
     method public final int getSource();
+    method public final int getSourceDevice();
     method public final float getToolMajor();
     method public final float getToolMajor(int);
     method public final float getToolMinor();
@@ -27195,6 +27497,7 @@
     field public static final deprecated int ACTION_POINTER_ID_SHIFT = 8; // 0x8
     field public static final int ACTION_POINTER_INDEX_MASK = 65280; // 0xff00
     field public static final int ACTION_POINTER_INDEX_SHIFT = 8; // 0x8
+    field public static final int ACTION_POINTER_MASK = 65535; // 0xffff
     field public static final int ACTION_POINTER_UP = 6; // 0x6
     field public static final int ACTION_SCROLL = 8; // 0x8
     field public static final int ACTION_UP = 1; // 0x1
@@ -27252,6 +27555,8 @@
     field public static final int EDGE_TOP = 1; // 0x1
     field public static final int FLAG_WINDOW_IS_OBSCURED = 1; // 0x1
     field public static final int INVALID_POINTER_ID = -1; // 0xffffffff
+    field public static final int SOURCE_DEVICE_MASK = -16777216; // 0xff000000
+    field public static final int SOURCE_DEVICE_SHIFT = 24; // 0x18
     field public static final int TOOL_TYPE_ERASER = 4; // 0x4
     field public static final int TOOL_TYPE_FINGER = 1; // 0x1
     field public static final int TOOL_TYPE_MOUSE = 3; // 0x3
diff -urN Original_4.4.4_r1/frameworks/base/core/java/android/app/Activity.java AndroidSource/frameworks/base/core/java/android/app/Activity.java
--- Original_4.4.4_r1/frameworks/base/core/java/android/app/Activity.java	2016-01-29 15:12:27.375488000 +0900
+++ AndroidSource/frameworks/base/core/java/android/app/Activity.java	2016-09-23 16:10:17.181173579 +0900
@@ -18,6 +18,7 @@
 
 import android.util.ArrayMap;
 import android.util.SuperNotCalledException;
+
 import com.android.internal.app.ActionBarImpl;
 import com.android.internal.policy.PolicyManager;
 
@@ -49,8 +50,10 @@
 import android.os.Looper;
 import android.os.Parcelable;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.StrictMode;
 import android.os.UserHandle;
+import android.service.remote.IRemoteService;
 import android.text.Selection;
 import android.text.SpannableStringBuilder;
 import android.text.TextUtils;
@@ -699,6 +702,9 @@
     private SearchManager mSearchManager;
     private MenuInflater mMenuInflater;
 
+    // ADDED BY JH
+    private final IRemoteService mRemoteService = IRemoteService.Stub.asInterface(ServiceManager.getService(Context.REMOTE_SERVICE)); 
+
     static final class NonConfigurationInstances {
         Object activity;
         HashMap<String, Object> children;
@@ -2415,6 +2421,24 @@
     public boolean dispatchKeyEvent(KeyEvent event) {
         onUserInteraction();
         Window win = getWindow();
+        
+        // ADDED BY DCSLAB
+        if(android.provider.Settings.Global.getInt(getContentResolver(), "collaboroid_on", 0)>0){
+            if(event.getAction()==KeyEvent.ACTION_DOWN){
+                Log.d("KeyLatency", "KeyLatency - client" + event.getSource());
+            }
+            try
+            {
+                mRemoteService.sendKeyEvent(event);
+            }
+            catch (RemoteException e)
+            {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+        // ADDED BY DCSLAB
+        
         if (win.superDispatchKeyEvent(event)) {
             return true;
         }
@@ -2452,6 +2476,26 @@
      * @return boolean Return true if this event was consumed.
      */
     public boolean dispatchTouchEvent(MotionEvent ev) {
+        // ADDED BY JH
+        try
+        {
+            if (ev.getSourceDevice() == 0
+                    && (android.provider.Settings.Global.getInt(getContentResolver(),
+                            "collaboroid_on", 0) > 0))
+            {
+//                Log.d("TouchLatency", "motion start!");
+                mRemoteService.sendMotionEvent(ev);
+            }
+        }
+        catch (RemoteException e)
+        {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        // ADDED BY JH
+
+
+
         if (ev.getAction() == MotionEvent.ACTION_DOWN) {
             onUserInteraction();
         }
diff -urN Original_4.4.4_r1/frameworks/base/core/java/android/app/ContextImpl.java AndroidSource/frameworks/base/core/java/android/app/ContextImpl.java
--- Original_4.4.4_r1/frameworks/base/core/java/android/app/ContextImpl.java	2016-01-29 15:12:27.379488000 +0900
+++ AndroidSource/frameworks/base/core/java/android/app/ContextImpl.java	2016-03-02 19:22:11.000000000 +0900
@@ -17,6 +17,7 @@
 package android.app;
 
 import android.os.Build;
+
 import com.android.internal.policy.PolicyManager;
 import com.android.internal.util.Preconditions;
 
@@ -94,6 +95,9 @@
 import android.os.UserManager;
 import android.os.storage.IMountService;
 import android.os.storage.StorageManager;
+import android.service.remote.RemoteServiceManager;
+import android.service.collaboroid.CollaboRoidManager;
+import android.service.devicemanager.DeviceManager;
 import android.print.IPrintManager;
 import android.print.PrintManager;
 import android.telephony.TelephonyManager;
@@ -595,6 +599,26 @@
             public Object createService(ContextImpl ctx) {
                 return new ConsumerIrManager(ctx);
             }});
+        
+        // ADDED FOR COLLABOROID
+        registerService(COLLABOROID, new ServiceFetcher(){
+            public Object createService(ContextImpl ctx){
+                return new CollaboRoidManager(ctx);
+            }
+        });
+        
+        registerService(REMOTE_SERVICE, new ServiceFetcher(){
+            public Object createService(ContextImpl ctx){
+                return new RemoteServiceManager(ctx);
+            }
+        });
+        
+        registerService(DEVICE_MANAGEMENT_SERVICE, new ServiceFetcher(){
+            public Object createService(ContextImpl ctx){
+                return new DeviceManager(ctx);
+            }
+        });
+        // ADDED FOR COLLABOROID
     }
 
     static ContextImpl getImpl(Context context) {
diff -urN Original_4.4.4_r1/frameworks/base/core/java/android/content/Context.java AndroidSource/frameworks/base/core/java/android/content/Context.java
--- Original_4.4.4_r1/frameworks/base/core/java/android/content/Context.java	2016-01-29 15:12:27.395488000 +0900
+++ AndroidSource/frameworks/base/core/java/android/content/Context.java	2016-03-02 19:26:16.000000000 +0900
@@ -2933,4 +2933,11 @@
     public boolean isRestricted() {
         return false;
     }
+
+	// ADDED FOR COLLABOROID
+    public static final String COLLABOROID = "collaboroid";
+    public static final String REMOTE_SERVICE = "remote";
+    public static final String DEVICE_MANAGEMENT_SERVICE = "devicemanagement";
+    public static final String DISTRIBUTED_COMPUTING_SERVICE = "distribute";
+    // ADDED FOR COLLABOROID
 }
diff -urN Original_4.4.4_r1/frameworks/base/core/java/android/hardware/SensorEvent.java AndroidSource/frameworks/base/core/java/android/hardware/SensorEvent.java
--- Original_4.4.4_r1/frameworks/base/core/java/android/hardware/SensorEvent.java	2016-01-29 15:12:27.411488000 +0900
+++ AndroidSource/frameworks/base/core/java/android/hardware/SensorEvent.java	2015-10-19 13:54:46.000000000 +0900
@@ -501,7 +501,22 @@
      */
     public long timestamp;
 
+    /**
+     * ADDED BY JH
+     * The source where sensor events comes
+     */
+    public int sourceDevice;
+    
     SensorEvent(int valueSize) {
         values = new float[valueSize];
     }
+    
+    /*public SensorEvent(float[] v, int acc, long ts, int sd)
+    {
+    	values = v;
+    	sensor = new Sensor("RemoteSensor", Sensor.TYPE_REMOTE_SENSOR, Sensor.TYPE_REMOTE_SENSOR);
+    	accuracy = acc;
+    	timestamp = ts;
+    	sourceDevice = sd;
+    }*/
 }
diff -urN Original_4.4.4_r1/frameworks/base/core/java/android/hardware/Sensor.java AndroidSource/frameworks/base/core/java/android/hardware/Sensor.java
--- Original_4.4.4_r1/frameworks/base/core/java/android/hardware/Sensor.java	2016-01-29 15:12:27.411488000 +0900
+++ AndroidSource/frameworks/base/core/java/android/hardware/Sensor.java	2015-09-30 13:32:06.000000000 +0900
@@ -222,6 +222,12 @@
     public static final int TYPE_GEOMAGNETIC_ROTATION_VECTOR = 20;
 
     /**
+     * ADDED BY JH
+     * 
+    */
+    public static final int TYPE_REMOTE_SENSOR = 21;
+    
+    /**
      * A constant describing all sensor types.
      */
     public static final int TYPE_ALL = -1;
@@ -324,6 +330,14 @@
 
     Sensor() {
     }
+    
+    // ADDED BY JH
+    Sensor(String name, int handle, int type)
+    {
+    	mName = name;
+    	mHandle = handle;
+    	mType = type;
+    }
 
     /**
      * @return name string of the sensor.
diff -urN Original_4.4.4_r1/frameworks/base/core/java/android/hardware/SystemSensorManager.java AndroidSource/frameworks/base/core/java/android/hardware/SystemSensorManager.java
--- Original_4.4.4_r1/frameworks/base/core/java/android/hardware/SystemSensorManager.java	2016-01-29 15:12:27.411488000 +0900
+++ AndroidSource/frameworks/base/core/java/android/hardware/SystemSensorManager.java	2016-09-23 16:52:20.421092185 +0900
@@ -16,20 +16,23 @@
 
 package android.hardware;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
 import android.content.Context;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.MessageQueue;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.service.remote.IRemoteService;
 import android.util.Log;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
 import dalvik.system.CloseGuard;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
 /**
  * Sensor manager implementation that communicates with the built-in
  * system sensors.
@@ -53,12 +56,21 @@
 
     // Looper associated with the context in which this instance was created.
     private final Looper mMainLooper;
-    private final int mTargetSdkLevel;
-
+    final int mTargetSdkLevel;
+    private final Context mContext;
+    
+    // ADDED BY JH
+    private static IRemoteService mRemoteService;
+    private static SensorEventListener mRemoteSensorListener;
+    
     /** {@hide} */
     public SystemSensorManager(Context context, Looper mainLooper) {
-        mMainLooper = mainLooper;
+    	mMainLooper = mainLooper;
+        mContext = context;
         mTargetSdkLevel = context.getApplicationInfo().targetSdkVersion;
+        mRemoteService = IRemoteService.Stub.asInterface(ServiceManager
+				.getService(Context.REMOTE_SERVICE));
+        
         synchronized(sSensorModuleLock) {
             if (!sSensorModuleInitialized) {
                 sSensorModuleInitialized = true;
@@ -76,12 +88,34 @@
                         //        ", handle=" + sensor.getHandle());
                         fullList.add(sensor);
                         sHandleToSensor.append(sensor.getHandle(), sensor);
+                        
+                        /*try
+						{
+							mRemoteService.addSensorHandle(sensor.getType(), sensor.getHandle());
+						} 
+                        catch (RemoteException e)
+						{
+							// TODO Auto-generated catch block
+							e.printStackTrace();
+						}*/
+                        
+                        Log.d(TAG, "init- type: " + sensor.getType() + "handle: " + sensor.getHandle());
                     }
                 } while (i>0);
+                
+                Sensor sensor = new Sensor("RemoteSensor", Sensor.TYPE_REMOTE_SENSOR, Sensor.TYPE_REMOTE_SENSOR);
+                fullList.add(sensor);
+                sHandleToSensor.append(sensor.getHandle(), sensor);
+                
+                Log.d(TAG, "init- type: " + sensor.getType() + "handle: " + sensor.getHandle());
             }
         }
     }
 
+    /*SensorEventListener getRemoteListener()
+    {
+    	return mRemoteSensorListener;
+    }*/
 
     /** @hide */
     @Override
@@ -94,41 +128,125 @@
     @Override
     protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
             int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) {
-        if (listener == null || sensor == null) {
+    	if (listener == null || sensor == null) {
             Log.e(TAG, "sensor or listener is null");
             return false;
         }
-        // Trigger Sensors should use the requestTriggerSensor call.
+    	
+    	// Trigger Sensors should use the requestTriggerSensor call.
         if (Sensor.getReportingMode(sensor) == Sensor.REPORTING_MODE_ONE_SHOT) {
             Log.e(TAG, "Trigger Sensors should use the requestTriggerSensor.");
             return false;
         }
+        
         if (maxBatchReportLatencyUs < 0 || delayUs < 0) {
             Log.e(TAG, "maxBatchReportLatencyUs and delayUs should be non-negative");
             return false;
         }
-
+        
         // Invariants to preserve:
         // - one Looper per SensorEventListener
         // - one Looper per SensorEventQueue
         // We map SensorEventListener to a SensorEventQueue, which holds the looper
         synchronized (mSensorListeners) {
             SensorEventQueue queue = mSensorListeners.get(listener);
-            if (queue == null) {
+            
+            Log.d(TAG, mSensorListeners.toString());
+            
+            //if((queue == null) && (sensor.getType() == Sensor.TYPE_REMOTE_SENSOR))
+            	
+            /*if(sensor.getType() == Sensor.TYPE_REMOTE_SENSOR)
+            {
+            	mRemoteSensorListener = listener;
+            	return true;
+            }*/
+            
+            try
+			{
+            	if(mRemoteService == null)
+            	{
+            		Log.d(TAG, "type: " + sensor.getType() + " handle: " + sensor.getHandle());
+            		return false;
+            	}
+				mRemoteService.addSensorHandle(sensor.getType(), sensor.getHandle());
+				Log.d(TAG, "Hello: " + sensor.getType());
+				//RemoteSensorListener = listener;
+				
+				/*Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
+                queue = new SensorEventQueue(listener, looper, this);
+                
+                if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags)) {
+	                queue.dispose();
+	                return false;
+	            }*/
+            }
+			catch (RemoteException e)
+			{
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+            
+            if (queue == null) 
+            {
                 Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
                 queue = new SensorEventQueue(listener, looper, this);
+                
                 if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags)) {
-                    queue.dispose();
-                    return false;
-                }
-                mSensorListeners.put(listener, queue);
+	                queue.dispose();
+	                return false;
+	            }
+                
+                /*Log.d(TAG, "6: " + sensor.getType() + ", " + sensor.getHandle());
+                
+                // add handle in RemoteRequestHandler - ADDED BY JH
+                try
+    			{
+                	if(mRemoteService == null)
+                		Log.d(TAG, "type: " + sensor.getType() + " handle: " + sensor.getHandle());
+    				mRemoteService.addSensorHandle(sensor.getType(), sensor.getHandle());
+    				
+    				if(sensor.getType() == Sensor.TYPE_REMOTE_SENSOR)
+    				{
+    					Log.d(TAG, "7: " + sensor.getType() + ", " + sensor.getHandle());
+    					mRemoteService.setRemoteSensorOn(true);
+    					RemoteSensorListener = listener;
+    				}
+    			}
+    			catch (RemoteException e)
+    			{
+    				// TODO Auto-generated catch block
+    				e.printStackTrace();
+    			}*/
+                
                 return true;
-            } else {
+            } 
+            else 
+            {
+            	// add handle in RemoteRequestHandler
+                /*try
+    			{
+                	if(mRemoteService == null)
+                		Log.d(TAG, "type: " + sensor.getType() + " handle: " + sensor.getHandle());
+    				mRemoteService.addSensorHandle(sensor.getType(), sensor.getHandle());
+    				
+    				if(sensor.getType() == Sensor.TYPE_REMOTE_SENSOR)
+    				{
+    					Log.d(TAG, "8: " + sensor.getType() + ", " + sensor.getHandle());
+    					mRemoteService.setRemoteSensorOn(true);
+    					RemoteSensorListener = listener;
+    				}
+    			}
+    			catch (RemoteException e)
+    			{
+    				// TODO Auto-generated catch block
+    				e.printStackTrace();
+    			}*/
+                
                 return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags);
             }
         }
     }
-
+    
     /** @hide */
     @Override
     protected void unregisterListenerImpl(SensorEventListener listener, Sensor sensor) {
@@ -136,8 +254,16 @@
         if (sensor != null && Sensor.getReportingMode(sensor) == Sensor.REPORTING_MODE_ONE_SHOT) {
             return;
         }
+        
+        
 
         synchronized (mSensorListeners) {
+        	if(sensor != null && sensor.getType() == Sensor.TYPE_REMOTE_SENSOR)
+            {
+            		mRemoteSensorListener = null;
+                	return;
+            }
+        	
             SensorEventQueue queue = mSensorListeners.get(listener);
             if (queue != null) {
                 boolean result;
@@ -150,6 +276,25 @@
                     mSensorListeners.remove(listener);
                     queue.dispose();
                 }
+                
+                // ADDED BY JH
+                try
+    			{
+                	if(mRemoteService == null)
+                		Log.d(TAG, "type: " + sensor.getType() + " handle: " + sensor.getHandle());
+    				mRemoteService.removeSensorHandle(sensor.getType());
+    				
+    				/*if(sensor.getType() == Sensor.TYPE_REMOTE_SENSOR)
+    				{
+    					//mRemoteService.setRemoteSensorOn(false);
+    					RemoteSensorListener = null;
+    				}*/
+    			}
+    			catch (RemoteException e)
+    			{
+    				// TODO Auto-generated catch block
+    				e.printStackTrace();
+    			}
             }
         }
     }
@@ -224,6 +369,11 @@
     private static abstract class BaseEventQueue {
         private native int nativeInitBaseEventQueue(BaseEventQueue eventQ, MessageQueue msgQ,
                 float[] scratch);
+        
+        // ADDED BY JH
+        //private native int nativeInitRemoteBaseEventQueue(BaseEventQueue eventQ, MessageQueue msgQ,
+        //        float[] scratch);
+        
         private static native int nativeEnableSensor(int eventQ, int handle, int rateUs,
                 int maxBatchReportLatencyUs, int reservedFlags);
         private static native int nativeDisableSensor(int eventQ, int handle);
@@ -242,6 +392,12 @@
             mCloseGuard.open("dispose");
             mManager = manager;
         }
+        
+        /*BaseEventQueue(Looper looper, SystemSensorManager manager, boolean isRemote) {
+            nSensorEventQueue = nativeInitRemoteBaseEventQueue(this, looper.getQueue(), mScratch);
+            mCloseGuard.open("dispose");
+            mManager = manager;
+        }*/
 
         public void dispose() {
             dispose(false);
@@ -256,10 +412,17 @@
             // Get ready to receive events before calling enable.
             mActiveSensors.put(handle, true);
             addSensorEvent(sensor);
+            Log.d(TAG, "addSensor: " + sensor.getName());
+            
+            // ADDED BY JH
+            /*if(sensor.getType() == Sensor.TYPE_REMOTE_SENSOR)
+            	return true;*/
             if (enableSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags) != 0) {
                 // Try continuous mode if batching fails.
+            	Log.d(TAG, "addSensor - enableSensor");
                 if (maxBatchReportLatencyUs == 0 ||
                     maxBatchReportLatencyUs > 0 && enableSensor(sensor, delayUs, 0, 0) != 0) {
+                	Log.d(TAG, "addSensor - enableSensor2: " + maxBatchReportLatencyUs);
                   removeSensor(sensor, false);
                   return false;
                 }
@@ -290,6 +453,18 @@
                 if (disable) disableSensor(sensor);
                 mActiveSensors.put(sensor.getHandle(), false);
                 removeSensorEvent(sensor);
+                
+                // remove handle in RemoteRequestHandler
+                try
+    			{
+    				mRemoteService.removeSensorHandle(sensor.getType());
+    			}
+    			catch (RemoteException e)
+    			{
+    				// TODO Auto-generated catch block
+    				e.printStackTrace();
+    			}
+                
                 return true;
             }
             return false;
@@ -331,6 +506,7 @@
                 Sensor sensor, int rateUs, int maxBatchReportLatencyUs, int reservedFlags) {
             if (nSensorEventQueue == 0) throw new NullPointerException();
             if (sensor == null) throw new NullPointerException();
+            
             return nativeEnableSensor(nSensorEventQueue, sensor.getHandle(), rateUs,
                     maxBatchReportLatencyUs, reservedFlags);
         }
@@ -338,28 +514,30 @@
         private int disableSensor(Sensor sensor) {
             if (nSensorEventQueue == 0) throw new NullPointerException();
             if (sensor == null) throw new NullPointerException();
+            
             return nativeDisableSensor(nSensorEventQueue, sensor.getHandle());
         }
         protected abstract void dispatchSensorEvent(int handle, float[] values, int accuracy,
-                long timestamp);
+                long timestamp, int sourceDevice);
         protected abstract void dispatchFlushCompleteEvent(int handle);
 
         protected abstract void addSensorEvent(Sensor sensor);
         protected abstract void removeSensorEvent(Sensor sensor);
     }
 
-    static final class SensorEventQueue extends BaseEventQueue {
+    public static final class SensorEventQueue extends BaseEventQueue {
         private final SensorEventListener mListener;
         private final SparseArray<SensorEvent> mSensorsEvents = new SparseArray<SensorEvent>();
-
+        
         public SensorEventQueue(SensorEventListener listener, Looper looper,
-                SystemSensorManager manager) {
-            super(looper, manager);
+                SystemSensorManager systemSensorManager) {
+            super(looper, systemSensorManager);
             mListener = listener;
         }
-
+        
         @Override
         public void addSensorEvent(Sensor sensor) {
+        	Log.d(TAG, "addSensorEvent(Sensor): " + sensor.getName());
             SensorEvent t = new SensorEvent(Sensor.getMaxLengthValuesArray(sensor,
                     mManager.mTargetSdkLevel));
             synchronized (mSensorsEvents) {
@@ -378,9 +556,10 @@
         @SuppressWarnings("unused")
         @Override
         protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy,
-                long timestamp) {
-            final Sensor sensor = sHandleToSensor.get(handle);
-            SensorEvent t = null;
+                long timestamp, int sourceDevice) {
+        	
+        	final Sensor sensor = sHandleToSensor.get(handle);
+        	SensorEvent t = null;
             synchronized (mSensorsEvents) {
                 t = mSensorsEvents.get(handle);
             }
@@ -390,34 +569,63 @@
                 // the queue waiting to be delivered. Ignore.
                 return;
             }
+            
             // Copy from the values array.
             System.arraycopy(values, 0, t.values, 0, t.values.length);
             t.timestamp = timestamp;
             t.accuracy = inAccuracy;
             t.sensor = sensor;
+            t.sourceDevice = sourceDevice;
+            
+            // ADDED FOR COLLABOROID
+            try
+			{
+            	if(sensor.getType() == Sensor.TYPE_ORIENTATION || sensor.getType() == Sensor.TYPE_PROXIMITY)
+            	{
+            		Log.d("SensorStart", "sensor start!  ");
+            		mRemoteService.sendSensorEvent(t.sensor.getType(), handle, values, inAccuracy, timestamp);
+            	}
+            }
+			catch (RemoteException e)
+			{
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+            
             switch (t.sensor.getType()) {
-                // Only report accuracy for sensors that support it.
-                case Sensor.TYPE_MAGNETIC_FIELD:
-                case Sensor.TYPE_ORIENTATION:
-                    // call onAccuracyChanged() only if the value changes
-                    final int accuracy = mSensorAccuracies.get(handle);
-                    if ((t.accuracy >= 0) && (accuracy != t.accuracy)) {
-                        mSensorAccuracies.put(handle, t.accuracy);
-                        mListener.onAccuracyChanged(t.sensor, t.accuracy);
-                    }
-                    break;
-                default:
-                    // For other sensors, just report the accuracy once
-                    if (mFirstEvent.get(handle) == false) {
-                        mFirstEvent.put(handle, true);
-                        mListener.onAccuracyChanged(
-                                t.sensor, SENSOR_STATUS_ACCURACY_HIGH);
-                    }
-                    break;
+            // Only report accuracy for sensors that support it.
+            case Sensor.TYPE_MAGNETIC_FIELD:
+            case Sensor.TYPE_ORIENTATION:
+                // call onAccuracyChanged() only if the value changes
+                final int accuracy = mSensorAccuracies.get(handle);
+                if ((t.accuracy >= 0) && (accuracy != t.accuracy)) {
+                    mSensorAccuracies.put(handle, t.accuracy);
+                    mListener.onAccuracyChanged(t.sensor, t.accuracy);
+                }
+                break;
+            default:
+                // For other sensors, just report the accuracy once
+                if (mFirstEvent.get(handle) == false) {
+                    mFirstEvent.put(handle, true);
+                    mListener.onAccuracyChanged(
+                            t.sensor, SENSOR_STATUS_ACCURACY_HIGH);
+                }
+                break;
+        	}
+            // ADDED BY JH
+            /*if(t.sourceDevice != 0)
+            {
+            	//t.sensor = sHandleToSensor.get(Sensor.TYPE_REMOTE_SENSOR);
+            	Log.d(TAG, "type::::: "+t.sensor.getType());
+            	t.sensor = new Sensor("RemoteSensor", handle, Sensor.TYPE_REMOTE_SENSOR);
+            	//SystemSensorManager.mRemoteSensorListener.onSensorChanged(t);
+                //RemoteSensorListener.onSensorChanged(t);
+            	mListener.onSensorChanged(t);
             }
+            else      */      
             mListener.onSensorChanged(t);
         }
-
+        
         @SuppressWarnings("unused")
         protected void dispatchFlushCompleteEvent(int handle) {
             if (mListener instanceof SensorEventListener2) {
@@ -433,13 +641,14 @@
         private final SparseArray<TriggerEvent> mTriggerEvents = new SparseArray<TriggerEvent>();
 
         public TriggerEventQueue(TriggerEventListener listener, Looper looper,
-                SystemSensorManager manager) {
-            super(looper, manager);
+        		SystemSensorManager systemSensorManager) {
+            super(looper, systemSensorManager);
             mListener = listener;
         }
 
         @Override
         public void addSensorEvent(Sensor sensor) {
+        	Log.d(TAG, "addSensorEvent(Trigger): " + sensor.getName());
             TriggerEvent t = new TriggerEvent(Sensor.getMaxLengthValuesArray(sensor,
                     mManager.mTargetSdkLevel));
             synchronized (mTriggerEvents) {
@@ -458,8 +667,9 @@
         @SuppressWarnings("unused")
         @Override
         protected void dispatchSensorEvent(int handle, float[] values, int accuracy,
-                long timestamp) {
+                long timestamp, int sourceDevice) {
             final Sensor sensor = sHandleToSensor.get(handle);
+            Log.d(TAG, "dispatchSensorEvent(Trigger): " + sensor.getName());
             TriggerEvent t = null;
             synchronized (mTriggerEvents) {
                 t = mTriggerEvents.get(handle);
@@ -485,4 +695,4 @@
         protected void dispatchFlushCompleteEvent(int handle) {
         }
     }
-}
+}
\ No newline at end of file
diff -urN Original_4.4.4_r1/frameworks/base/core/java/android/os/SystemVibrator.java AndroidSource/frameworks/base/core/java/android/os/SystemVibrator.java
--- Original_4.4.4_r1/frameworks/base/core/java/android/os/SystemVibrator.java	2016-01-29 15:12:27.431488000 +0900
+++ AndroidSource/frameworks/base/core/java/android/os/SystemVibrator.java	2016-09-26 17:12:48.515829267 +0900
@@ -18,8 +18,12 @@
 
 import android.app.ActivityThread;
 import android.content.Context;
+import android.service.remote.IRemoteService;
+import android.service.remote.RemoteRequest;
 import android.util.Log;
 
+import java.util.ArrayList;
+
 /**
  * Vibrator implementation that controls the main system vibrator.
  *
@@ -32,16 +36,24 @@
     private final IVibratorService mService;
     private final Binder mToken = new Binder();
 
+    private IRemoteService mRemoteService; 
+    
+    
     public SystemVibrator() {
         mPackageName = ActivityThread.currentPackageName();
         mService = IVibratorService.Stub.asInterface(
                 ServiceManager.getService("vibrator"));
+        mRemoteService = IRemoteService.Stub.asInterface(ServiceManager
+                .getService(Context.REMOTE_SERVICE));
+        
     }
 
     public SystemVibrator(Context context) {
         mPackageName = context.getOpPackageName();
         mService = IVibratorService.Stub.asInterface(
                 ServiceManager.getService("vibrator"));
+        mRemoteService = IRemoteService.Stub.asInterface(ServiceManager
+                .getService(Context.REMOTE_SERVICE));
     }
 
     @Override
@@ -81,6 +93,20 @@
         } catch (RemoteException e) {
             Log.w(TAG, "Failed to vibrate.", e);
         }
+        
+        
+        
+        ArrayList<Object> para = new ArrayList<Object>();
+        para.add(milliseconds);
+        
+        RemoteRequest request = new RemoteRequest("systemCall", "vibrate", para);
+        try {
+            mRemoteService.sendAllrequestVib(request);
+        } catch (RemoteException e) {
+            // TODO Auto-generated catch block
+//            e.printStackTrace();
+        }
+        
     }
 
     /**
@@ -104,6 +130,9 @@
         } else {
             throw new ArrayIndexOutOfBoundsException();
         }
+        
+
+        
     }
 
     @Override
diff -urN Original_4.4.4_r1/frameworks/base/core/java/android/provider/Settings.java AndroidSource/frameworks/base/core/java/android/provider/Settings.java
--- Original_4.4.4_r1/frameworks/base/core/java/android/provider/Settings.java	2016-01-29 15:12:27.439488000 +0900
+++ AndroidSource/frameworks/base/core/java/android/provider/Settings.java	2016-06-20 16:56:35.000000000 +0900
@@ -1101,6 +1101,7 @@
             MOVED_TO_GLOBAL.add(Settings.Global.SMS_SHORT_CODES_UPDATE_METADATA_URL);
             MOVED_TO_GLOBAL.add(Settings.Global.CERT_PIN_UPDATE_CONTENT_URL);
             MOVED_TO_GLOBAL.add(Settings.Global.CERT_PIN_UPDATE_METADATA_URL);
+
         }
 
         /** @hide */
@@ -2860,6 +2861,15 @@
             MOVED_TO_GLOBAL.add(Settings.Global.SET_GLOBAL_HTTP_PROXY);
             MOVED_TO_GLOBAL.add(Settings.Global.DEFAULT_DNS_SERVER);
             MOVED_TO_GLOBAL.add(Settings.Global.PREFERRED_NETWORK_MODE);
+            
+            // ADDED FOR COLLABOROID
+            MOVED_TO_GLOBAL.add(Settings.Global.REMOTE_REQUEST_SERVER_ON);
+            MOVED_TO_GLOBAL.add(Settings.Global.REMOTE_REQUEST_CLIENT_ON);
+            MOVED_TO_GLOBAL.add(Settings.Global.COLLABOROID_ON);
+            MOVED_TO_GLOBAL.add(Settings.Global.SYSTEM_SERVICE_ON);
+            MOVED_TO_GLOBAL.add(Settings.Global.TASK_EXECUTOR_ON);
+            MOVED_TO_GLOBAL.add(Settings.Global.COLLABOROID_DEVICE_NAME);
+            // ADDED FOR COLLABOROID
         }
 
         /** @hide */
@@ -5935,6 +5945,18 @@
          */
         public static final String LOW_BATTERY_SOUND_TIMEOUT = "low_battery_sound_timeout";
 
+        // ADDED BY DCSLAB
+        public static final String REMOTE_REQUEST_SERVER_ON = "remote_request_server_on";
+        public static final String REMOTE_REQUEST_CLIENT_ON = "remote_request_client_on";
+
+        public static final String COLLABOROID_ON = "collaboroid_on";
+        
+        public static final String SYSTEM_SERVICE_ON = "system_service_on";
+        public static final String TASK_EXECUTOR_ON = "task_executor_on";
+        
+        public static final String COLLABOROID_DEVICE_NAME = "collaboroid_device_name";
+        
+
         /**
          * Settings to backup. This is here so that it's in the same place as the settings
          * keys and easy to update.
diff -urN Original_4.4.4_r1/frameworks/base/core/java/android/service/collaboroid/CollaboRoidManager.java AndroidSource/frameworks/base/core/java/android/service/collaboroid/CollaboRoidManager.java
--- Original_4.4.4_r1/frameworks/base/core/java/android/service/collaboroid/CollaboRoidManager.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/core/java/android/service/collaboroid/CollaboRoidManager.java	2016-06-23 18:41:16.000000000 +0900
@@ -0,0 +1,72 @@
+package android.service.collaboroid;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.service.devicemanager.IDeviceManager;
+import android.service.remote.IRemoteService;
+
+public class CollaboRoidManager 
+{
+	public static final String EXTRA_COLLABOROID_STATE = "collaboroid_state";
+	
+	public static final String COLLABOROID_STATE_CHANGED_ACTION = "android.service.collaboroid.COLLABOROID_STATE_CHANGED";
+	
+	public static final int COLLABOROID_STATE_DISABLING = 0;
+	public static final int COLLABOROID_STATE_DISABLED = 1;
+	public static final int COLLABOROID_STATE_ENABLING = 2;
+	public static final int COLLABOROID_STATE_ENABLED = 3;
+	public static final int COLLABOROID_STATE_UNKNOWN = 4;
+	
+	private IDeviceManager mDeviceService;
+	private IRemoteService mRemoteService;
+	private Context mContext;
+	
+	public CollaboRoidManager(Context context)
+	{
+		// TODO Auto-generated constructor stub
+		mContext = context;
+		mDeviceService = IDeviceManager.Stub.asInterface(ServiceManager.getService(Context.DEVICE_MANAGEMENT_SERVICE)); 
+		mRemoteService = IRemoteService.Stub.asInterface(ServiceManager.getService(Context.REMOTE_SERVICE));
+	}
+	
+	public void setCollaboRoidEnabled(boolean enabled)
+	{
+		try
+		{
+			if(enabled)
+			{
+				setCollaboRoidState(COLLABOROID_STATE_ENABLING);
+				mDeviceService.getDeviceList(0);
+				mRemoteService.startServer();
+				Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.COLLABOROID_ON, 1);
+				setCollaboRoidState(COLLABOROID_STATE_ENABLED);
+			}
+			else
+			{
+				// disconnects to all devices
+				setCollaboRoidState(COLLABOROID_STATE_DISABLING);
+				mRemoteService.stopServer();
+				mRemoteService.initConnections();
+				mDeviceService.initDevices();
+				Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.COLLABOROID_ON, 0);
+				setCollaboRoidState(COLLABOROID_STATE_DISABLED);
+			}
+		}
+		catch(RemoteException re)
+		{
+			re.printStackTrace();
+		}
+	}
+	
+	private void setCollaboRoidState(int state)
+	{
+		final Intent intent = new Intent(CollaboRoidManager.COLLABOROID_STATE_CHANGED_ACTION);
+		intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+		intent.putExtra(CollaboRoidManager.EXTRA_COLLABOROID_STATE, state);
+		mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+	}
+}
diff -urN Original_4.4.4_r1/frameworks/base/core/java/android/service/collaboroid/IGeneralMessageListener.aidl AndroidSource/frameworks/base/core/java/android/service/collaboroid/IGeneralMessageListener.aidl
--- Original_4.4.4_r1/frameworks/base/core/java/android/service/collaboroid/IGeneralMessageListener.aidl	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/core/java/android/service/collaboroid/IGeneralMessageListener.aidl	2016-03-04 14:09:26.000000000 +0900
@@ -0,0 +1,6 @@
+package android.service.collaboroid;
+
+oneway interface IGeneralMessageListener
+{
+	void onMessageReceived(String message);
+}
\ No newline at end of file
diff -urN Original_4.4.4_r1/frameworks/base/core/java/android/service/devicemanager/Device.aidl AndroidSource/frameworks/base/core/java/android/service/devicemanager/Device.aidl
--- Original_4.4.4_r1/frameworks/base/core/java/android/service/devicemanager/Device.aidl	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/core/java/android/service/devicemanager/Device.aidl	2016-01-11 19:24:34.000000000 +0900
@@ -0,0 +1,3 @@
+package android.service.devicemanager;
+
+parcelable Device;
\ No newline at end of file
diff -urN Original_4.4.4_r1/frameworks/base/core/java/android/service/devicemanager/Device.java AndroidSource/frameworks/base/core/java/android/service/devicemanager/Device.java
--- Original_4.4.4_r1/frameworks/base/core/java/android/service/devicemanager/Device.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/core/java/android/service/devicemanager/Device.java	2016-06-21 17:49:09.000000000 +0900
@@ -0,0 +1,119 @@
+package android.service.devicemanager;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class Device implements Parcelable
+{
+	public static final int RESOURCE_TYPE_TOUCH = 0;
+	public static final int RESOURCE_TYPE_KEY = 1;
+	public static final int RESOURCE_TYPE_SENSOR = 2;
+	public static final int RESOURCE_TYPE_LOCATION = 3;
+	public static final int RESOURCE_TYPE_VIDEO = 4;
+	public static final int RESOURCE_TYPE_AUDIO = 5;
+	public static final int RESOURCE_TYPE_VIBRATOR = 6;	
+	
+	public static final int RESOURCE_TYPE_SIZE = 7;
+	
+	public static final String[] ResourceNames = {"Touch", "Key", "Sensor", "Location", "Video", "Audio", "Vibrator"};
+	
+	public final int SYSTEM_SERVICE_LIST = 1;
+    public final int TASK_EXECUTOR_LIST = 2;
+    
+	public String ipaddress;
+	public String idleCpu;
+	public String deviceName;
+	public int isSystemServiceOn = -1;
+	public int isTaskExecutorOn = -1;
+	
+    public int[] askedResources;
+    public int[] allowedResources;
+	
+	public Device(String ipaddress, String idleCpu, String name, int isSystemServiceOn, int isTaskExecutorOn) {
+	    updateDevice(ipaddress, idleCpu, name, isSystemServiceOn, isTaskExecutorOn);
+//		this.ipaddress = ipaddress;
+//		this.idleCpu = idleCpu;
+//		this.isSystemServiceOn = isSystemServiceOn;
+//		this.isTaskExecutorOn = isTaskExecutorOn;
+	}
+	
+	public Device() {
+		// TODO Auto-generated constructor stub
+		initDevice();
+	}
+
+	public void initDevice(){
+	    this.ipaddress = "";
+        this.idleCpu = "";
+        this.deviceName = "";
+        this.isSystemServiceOn = -1;
+        this.isTaskExecutorOn = -1;
+        
+        this.askedResources = new int[RESOURCE_TYPE_SIZE];
+        this.allowedResources = new int[RESOURCE_TYPE_SIZE];
+	}
+	
+	public String toString() {
+        String result = "ipAddress: " + this.ipaddress
+                + "idleCPU: " + this.idleCpu
+                + "SystemServerOn? " + Integer.toString(isSystemServiceOn)
+                + "TaskExecutorOn? " + Integer.toString(isTaskExecutorOn) + "\n";
+        return result;
+	}
+	
+	public void updateDevice(String ipaddress, String idleCpu, String name, int isSystemServiceOn, int isTaskExecutorOn){
+		initDevice();
+		this.ipaddress = ipaddress;
+		this.idleCpu = idleCpu;
+		this.deviceName = name;
+        this.isSystemServiceOn = isSystemServiceOn;
+        this.isTaskExecutorOn = isTaskExecutorOn;
+	}
+	
+	public void setAllowedResources(int[] resources)
+	{
+		allowedResources = resources;
+	}
+	
+	public void setAskedResources(int[] resources)
+	{
+		askedResources = resources;
+	}
+
+	@Override
+	public int describeContents() {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public void writeToParcel(Parcel dest, int flags) {
+		// TODO Auto-generated method stub
+		dest.writeString(ipaddress);
+		dest.writeString(idleCpu);
+		dest.writeString(deviceName);
+		dest.writeInt(isSystemServiceOn);
+		dest.writeInt(isTaskExecutorOn);
+		dest.writeIntArray(askedResources);
+		dest.writeIntArray(allowedResources);
+	}
+	public static final Creator<Device> CREATOR = new Creator<Device>() {
+		public Device createFromParcel(Parcel in) {
+			Device device = new Device();
+			device.ipaddress = in.readString();
+			device.idleCpu = in.readString();
+			device.deviceName = in.readString();
+			device.isSystemServiceOn = in.readInt();
+			device.isTaskExecutorOn = in.readInt();
+			device.askedResources = in.createIntArray();
+			device.allowedResources = in.createIntArray();
+			
+			return device;
+		}
+
+		public Device[] newArray(int size) {
+			return new Device[size];
+		}
+	};
+
+}
diff -urN Original_4.4.4_r1/frameworks/base/core/java/android/service/devicemanager/DeviceList.java AndroidSource/frameworks/base/core/java/android/service/devicemanager/DeviceList.java
--- Original_4.4.4_r1/frameworks/base/core/java/android/service/devicemanager/DeviceList.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/core/java/android/service/devicemanager/DeviceList.java	2016-01-11 19:31:35.000000000 +0900
@@ -0,0 +1,18 @@
+package android.service.devicemanager;
+
+import java.util.HashMap;
+
+public class DeviceList 
+{
+	private static HashMap<String, Device> devices = new HashMap<String, Device>();
+
+    public static HashMap<String, Device> getDevices() {
+		return devices;
+	}
+
+	public static void setDevices(HashMap<String, Device> devices) {
+		DeviceList.devices = devices;
+	}
+	
+
+}
diff -urN Original_4.4.4_r1/frameworks/base/core/java/android/service/devicemanager/DeviceManager.java AndroidSource/frameworks/base/core/java/android/service/devicemanager/DeviceManager.java
--- Original_4.4.4_r1/frameworks/base/core/java/android/service/devicemanager/DeviceManager.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/core/java/android/service/devicemanager/DeviceManager.java	2016-06-22 11:31:03.000000000 +0900
@@ -0,0 +1,125 @@
+package android.service.devicemanager;
+
+import java.util.List;
+
+import android.content.Context;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.service.remote.IRemoteService;
+import android.util.Log;
+
+public class DeviceManager {
+	private final IDeviceManager mService;
+
+	public DeviceManager(IDeviceManager service) {
+		mService = service;
+	}
+	
+	public DeviceManager(Context ctx) {
+		mService = IDeviceManager.Stub.asInterface(ServiceManager.getService(Context.DEVICE_MANAGEMENT_SERVICE));
+	}
+	
+	public DeviceManager() {
+		mService = IDeviceManager.Stub.asInterface(ServiceManager.getService(Context.DEVICE_MANAGEMENT_SERVICE));
+	}
+
+	public String recommendDevice(List<Device> peerlist) {
+		try {
+			return mService.recommendDevice(peerlist);
+		} catch (RemoteException e) {
+            e.printStackTrace();
+		}
+		return null;
+
+	}
+
+	public String[] getSystemServiceOnServerList(){
+	    try{
+	        return mService.getSystemServiceOnServerList();
+	    } catch(RemoteException e){
+	        e.printStackTrace();
+	    }
+	    return null;
+	}
+	
+	public String[] getTaskExecutorOnServerList(){
+        try{
+            return mService.getTaskExecutorOnServerList();
+        } catch(RemoteException e){
+            e.printStackTrace();
+        }
+        return null;
+    }
+	
+	public List<Device> getDeviceList(int kind) {
+		try {
+			return mService.getDeviceList(kind);
+		} catch (RemoteException e) {
+		    e.printStackTrace();
+		}
+		return null;
+
+	}
+	
+	public void constructCluster(List<Device> devicelist)
+	{
+		try
+		{
+			Log.d("DeviceManager", "in construct!");
+			mService.constructCluster(devicelist);
+		}
+		catch(RemoteException e)
+		{
+			e.printStackTrace();
+		}
+	}
+	
+	public int getNumofConfiguredDevices()
+	{
+		try
+		{
+			return mService.getNumofConfiguredDevices();
+		}
+		catch(RemoteException e)
+		{
+			e.printStackTrace();
+		}
+		return 0;
+	}
+	
+    public Device getDevice(String name)
+    {
+		try
+		{
+			return mService.getDevice(name);
+		}
+		catch(RemoteException e)
+		{
+			e.printStackTrace();
+		}
+		return null;
+	}
+    
+    public void askResources(List<Device> devicelist) {
+    	try
+		{
+			mService.askResources(devicelist);
+		}
+		catch(RemoteException e)
+		{
+			e.printStackTrace();
+		}
+    }
+    
+    public void allowResources(String deviceName, int[] allowedResources)
+    {
+    	try
+		{
+			mService.allowResources(deviceName, allowedResources);
+		}
+		catch(RemoteException e)
+		{
+			e.printStackTrace();
+		}
+    }
+}
diff -urN Original_4.4.4_r1/frameworks/base/core/java/android/service/devicemanager/IDeviceManager.aidl AndroidSource/frameworks/base/core/java/android/service/devicemanager/IDeviceManager.aidl
--- Original_4.4.4_r1/frameworks/base/core/java/android/service/devicemanager/IDeviceManager.aidl	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/core/java/android/service/devicemanager/IDeviceManager.aidl	2016-06-23 18:38:57.000000000 +0900
@@ -0,0 +1,21 @@
+package android.service.devicemanager;
+
+import android.service.devicemanager.Device;
+
+interface IDeviceManager {
+	void initDevices();
+	String recommendDevice(in List<Device> devicelist); 
+	List<Device> getDeviceList(int kind);
+	String[] getSystemServiceOnServerList();
+	String[] getTaskExecutorOnServerList();
+	
+	int getNumofConfiguredDevices();
+    Device getDevice(String name);
+    void constructCluster(in List<Device> devicelist);
+    
+    void askResources(in List<Device> devicelist);
+    void allowResources(String deviceName, in int[] allowedResources);
+    void showRequestDialog(String deviceName, String deviceIP, in int[] askedResources);
+	
+	boolean isAllowedForResource(String device, int resource);
+}
diff -urN Original_4.4.4_r1/frameworks/base/core/java/android/service/distribute/Distributor.java AndroidSource/frameworks/base/core/java/android/service/distribute/Distributor.java
--- Original_4.4.4_r1/frameworks/base/core/java/android/service/distribute/Distributor.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/core/java/android/service/distribute/Distributor.java	2015-01-27 15:39:24.000000000 +0900
@@ -0,0 +1,69 @@
+package android.service.distribute;
+
+import android.content.Context;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+
+public class Distributor 
+{
+	private final IDistributedComputingService mService;
+	
+	public Distributor(IDistributedComputingService service)
+	{
+		mService = service;
+	}
+	
+	public Distributor()
+	{
+		mService = IDistributedComputingService.Stub.asInterface(ServiceManager.getService("distributedcomputing"));
+	}
+	
+	public Distributor(Context context)
+	{
+		// TODO Auto-generated constructor stub
+		mService = IDistributedComputingService.Stub.asInterface(ServiceManager.getService("distributedcomputing"));
+	}
+	
+	public void startJobManager(String ip)
+	{
+		try {
+			mService.startJobManager(ip);
+		} catch (RemoteException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+	public void startTaskExecutor()
+	{
+		try {
+			mService.startTaskExecutor();
+		} catch (RemoteException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+	public void testOperation()
+	{
+		try {
+			mService.testOperation();
+		} catch (RemoteException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+	public int sum(int start, int end)
+	{
+		try 
+		{
+			return mService.sum(start, end);
+		} 
+		catch (RemoteException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return 0;
+	}
+}
diff -urN Original_4.4.4_r1/frameworks/base/core/java/android/service/distribute/IDistributedComputingService.aidl AndroidSource/frameworks/base/core/java/android/service/distribute/IDistributedComputingService.aidl
--- Original_4.4.4_r1/frameworks/base/core/java/android/service/distribute/IDistributedComputingService.aidl	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/core/java/android/service/distribute/IDistributedComputingService.aidl	2015-01-27 21:56:54.000000000 +0900
@@ -0,0 +1,14 @@
+package android.service.distribute;
+
+interface IDistributedComputingService
+{
+	void startJobManager(String ip);
+	void stopJobManager();
+	
+	void startTaskExecutor();
+	void stopTaskExecutor();
+	
+	int sum(int start, int end);
+	
+	void testOperation();
+}
\ No newline at end of file
diff -urN Original_4.4.4_r1/frameworks/base/core/java/android/service/remote/AppendingObjectOutputStream.java AndroidSource/frameworks/base/core/java/android/service/remote/AppendingObjectOutputStream.java
--- Original_4.4.4_r1/frameworks/base/core/java/android/service/remote/AppendingObjectOutputStream.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/core/java/android/service/remote/AppendingObjectOutputStream.java	2015-10-27 11:41:12.000000000 +0900
@@ -0,0 +1,22 @@
+package android.service.remote;
+
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+
+public class AppendingObjectOutputStream extends ObjectOutputStream {
+
+	public AppendingObjectOutputStream(OutputStream output) throws IOException {
+		super(output);
+		// TODO Auto-generated constructor stub
+	}
+
+	@Override
+	protected void writeStreamHeader() throws IOException {
+		// do not write a header, but reset:
+		// this line added after another question
+		// showed a problem with the original
+		reset();
+	}
+
+}
\ No newline at end of file
diff -urN Original_4.4.4_r1/frameworks/base/core/java/android/service/remote/IRemoteService.aidl AndroidSource/frameworks/base/core/java/android/service/remote/IRemoteService.aidl
--- Original_4.4.4_r1/frameworks/base/core/java/android/service/remote/IRemoteService.aidl	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/core/java/android/service/remote/IRemoteService.aidl	2016-09-26 17:18:41.927817867 +0900
@@ -0,0 +1,80 @@
+package android.service.remote;
+
+import android.service.remote.RemoteRequest;
+
+import android.service.devicemanager.Device;
+
+import android.service.collaboroid.IGeneralMessageListener;
+
+import android.view.MotionEvent;
+import android.view.KeyEvent;
+import android.location.Location;
+
+
+interface IRemoteService
+{
+	boolean startServer();
+	boolean stopServer();
+	
+	void setConfiguration();
+	void setEnabled(boolean isEnabled);
+	
+	boolean isServerOn();
+	
+//	void connectToServer();
+	boolean connectToServer(String ip);
+	void disconnectToServer();
+	void initConnections();
+	List<String> getClientIPs();
+	List<String> getServerIPs();
+	void printServerIPs();
+	void sendAllMusic(int sampleSize, in byte[] to_send, long presentationTime);
+	void sendAllrequest(in RemoteRequest request);
+	
+	boolean sendResourceRequests(in List<Device> requestDeviceList);
+	boolean isAllowedForResource(String deviceName, String deviceIP, in int[] resources);
+	boolean respondAllowedResources(String deviceIP, in int[] resources);
+	
+	boolean sendRequest(in RemoteRequest request);
+//	void sendSensorRequest(in SensorEventQueue2 queue);
+	void sendAllrequestVib(in RemoteRequest request);
+
+	// for MotionEvent
+	void sendMotionEvent(in MotionEvent event);
+	
+	// for KeyEvent
+	void sendKeyEvent(in KeyEvent event);
+	
+	// for SensorEvent
+//	boolean setRemoteSensorOn(boolean flag, SensorEventListener listener);
+	void addSensorHandle(int type, int handle);
+	void removeSensorHandle(int type);
+	void sendSensorEvent(int type, int sensor, in float[] values, int accuracy, long timestamp);
+	
+	// for API
+	void playMusic();
+	
+	// for evaluations
+	void testOperation();
+	void testVibrate();
+	void testMusic();
+	void testVideo();
+	void testTouch();
+	void testKey();
+	void testSensor();
+	void testLocation();
+	void requestMotionEvents();
+	void launchDummyApp();	
+
+	void sendMusicData(int sampleSize, in byte[] to_send, long presentationTime);
+	
+	int getVideoPlayers();
+	void sendVideoSignal(int vport);
+	
+	void sendLocation(in Location location);
+	
+//	Object sendRountTripRequest(in RemoteRequest request);
+
+	void registerListener(IGeneralMessageListener listener);
+	void unregisterListener(IGeneralMessageListener listener);
+}
diff -urN Original_4.4.4_r1/frameworks/base/core/java/android/service/remote/RemoteRequest2.java AndroidSource/frameworks/base/core/java/android/service/remote/RemoteRequest2.java
--- Original_4.4.4_r1/frameworks/base/core/java/android/service/remote/RemoteRequest2.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/core/java/android/service/remote/RemoteRequest2.java	2016-02-22 17:17:46.000000000 +0900
@@ -0,0 +1,97 @@
+package android.service.remote;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class RemoteRequest2 implements Serializable, Parcelable
+{
+	private static final long serialVersionUID = 1L;
+	private String type;
+	private String method;
+	private ArrayList<Object> parameters;
+	
+	public RemoteRequest2()
+    {
+		parameters = new ArrayList<Object>();
+    }
+	
+	public RemoteRequest2(String type, String method, ArrayList<Object> parameters)
+    {
+		this.type = type;
+    	this.method = method;
+    	this.parameters = parameters;
+    }
+	
+	public RemoteRequest2(Parcel in) 
+	{
+		this.type = in.readString();
+		this.method = in.readString();
+		//this.parameters = in.readArrayList(null);
+		//this.parameters = in.readArrayList(Object.class.getClassLoader());
+		this.parameters = (ArrayList<Object>)in.readSerializable();		
+	}
+	
+	public static final Parcelable.Creator<RemoteRequest> CREATOR = new Parcelable.Creator<RemoteRequest>()
+	{
+		@Override
+		public RemoteRequest[] newArray(int size)
+		{
+			// TODO Auto-generated method stub
+			return new RemoteRequest[size];
+		}
+
+		@Override
+		public RemoteRequest createFromParcel(Parcel in)
+		{
+			// TODO Auto-generated method stub
+			return new RemoteRequest(in);
+		}
+	};
+
+	@Override
+	public int describeContents()
+	{
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public void writeToParcel(Parcel dest, int flags)
+	{
+		dest.writeString(this.type);
+		dest.writeString(this.method);
+		// dest.writeList(parameters);
+		dest.writeSerializable(this.parameters);
+	}
+
+	public void set(String type, String method, ArrayList<Object> parameters)
+	{
+    	this.type = type;
+    	this.method = method;
+    	this.parameters = parameters;
+    }
+	
+	public String getType()
+	{
+		return type;
+	}
+	
+	public String getMethod()
+	{
+		return method;
+	}
+	
+	public ArrayList<Object> getPara()
+	{
+		return parameters;
+	}
+
+	public String toString()
+	{
+		return "type: " + type + "\nmethod: " + method + "\npara: " + parameters.toString();
+	}
+	
+}
\ No newline at end of file
diff -urN Original_4.4.4_r1/frameworks/base/core/java/android/service/remote/RemoteRequest.aidl AndroidSource/frameworks/base/core/java/android/service/remote/RemoteRequest.aidl
--- Original_4.4.4_r1/frameworks/base/core/java/android/service/remote/RemoteRequest.aidl	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/core/java/android/service/remote/RemoteRequest.aidl	2014-12-27 02:19:52.000000000 +0900
@@ -0,0 +1,3 @@
+package android.service.remote;
+
+parcelable RemoteRequest;
\ No newline at end of file
diff -urN Original_4.4.4_r1/frameworks/base/core/java/android/service/remote/RemoteRequest.java AndroidSource/frameworks/base/core/java/android/service/remote/RemoteRequest.java
--- Original_4.4.4_r1/frameworks/base/core/java/android/service/remote/RemoteRequest.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/core/java/android/service/remote/RemoteRequest.java	2016-02-22 19:54:33.000000000 +0900
@@ -0,0 +1,166 @@
+package android.service.remote;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class RemoteRequest implements Serializable, Parcelable
+{
+	private static final long serialVersionUID = 1L;
+	private String type;
+	private String method;
+	private ArrayList<Object> parameters;
+	
+	public RemoteRequest()
+    {
+		parameters = new ArrayList<Object>();
+    }
+	
+	public RemoteRequest(String type, String method, ArrayList<Object> parameters)
+    {
+		this.type = type;
+    	this.method = method;
+    	this.parameters = parameters;
+    }
+	
+	public RemoteRequest(Parcel in) 
+	{
+		this.type = in.readString();
+		this.method = in.readString();
+		//this.parameters = in.readArrayList(null);
+		//this.parameters = in.readArrayList(Object.class.getClassLoader());
+		this.parameters = (ArrayList<Object>)in.readSerializable();		
+	}
+	
+	public static final Parcelable.Creator<RemoteRequest> CREATOR = new Parcelable.Creator<RemoteRequest>()
+	{
+		@Override
+		public RemoteRequest[] newArray(int size)
+		{
+			// TODO Auto-generated method stub
+			return new RemoteRequest[size];
+		}
+
+		@Override
+		public RemoteRequest createFromParcel(Parcel in)
+		{
+			// TODO Auto-generated method stub
+			return new RemoteRequest(in);
+		}
+	};
+
+	@Override
+	public int describeContents()
+	{
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public void writeToParcel(Parcel dest, int flags)
+	{
+		dest.writeString(this.type);
+		dest.writeString(this.method);
+		// dest.writeList(parameters);
+		dest.writeSerializable(this.parameters);
+	}
+
+	public void set(String type, String method, ArrayList<Object> parameters)
+	{
+    	this.type = type;
+    	this.method = method;
+    	this.parameters = parameters;
+    }
+	
+	public String getType()
+	{
+		return type;
+	}
+	
+	public String getMethod()
+	{
+		return method;
+	}
+	
+	public ArrayList<Object> getPara()
+	{
+		return parameters;
+	}
+
+	public String toString()
+	{
+		return "type: " + type + "\nmethod: " + method + "\npara: " + parameters.toString();
+	}
+	
+	public static class RemoteKeyEvent implements Serializable
+	{
+		private static final long serialVersionUID = 1L;
+
+		private int action;
+		private int code;
+		private int source;
+		
+		public RemoteKeyEvent(int action, int code, int source)
+		{
+			this.action = action;
+			this.code = code;
+			this.source = source;
+		}
+		
+		public RemoteKeyEvent(Parcel in) 
+		{
+			this.action = in.readInt();
+			this.code = in.readInt();
+			this.source = in.readInt();
+		}
+		
+		/*public static final Parcelable.Creator<RemoteKeyEvent> CREATOR = new Parcelable.Creator<RemoteKeyEvent>()
+		{
+			@Override
+			public RemoteKeyEvent[] newArray(int size)
+			{
+				// TODO Auto-generated method stub
+				return new RemoteKeyEvent[size];
+			}
+
+			@Override
+			public RemoteKeyEvent createFromParcel(Parcel in)
+			{
+				// TODO Auto-generated method stub
+				return new RemoteKeyEvent(in);
+			}
+		};
+
+		@Override
+		public int describeContents() {
+			// TODO Auto-generated method stub
+			return 0;
+		}
+
+		@Override
+		public void writeToParcel(Parcel dest, int flags) {
+			// TODO Auto-generated method stub
+			dest.writeInt(this.action);
+			dest.writeInt(this.code);
+			dest.writeInt(this.source);
+		}*/
+		
+		public int getAction()
+		{
+			return action;
+		}
+		
+		public int getCode()
+		{
+			return code;
+		}
+		
+		public int getSource()
+		{
+			return source;
+		}
+	}
+	
+}
\ No newline at end of file
diff -urN Original_4.4.4_r1/frameworks/base/core/java/android/service/remote/RemoteServiceManager.java AndroidSource/frameworks/base/core/java/android/service/remote/RemoteServiceManager.java
--- Original_4.4.4_r1/frameworks/base/core/java/android/service/remote/RemoteServiceManager.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/core/java/android/service/remote/RemoteServiceManager.java	2016-03-02 20:34:06.000000000 +0900
@@ -0,0 +1,319 @@
+package android.service.remote;
+
+import android.content.Context;
+import android.location.Location;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+
+public class RemoteServiceManager 
+{
+	private final IRemoteService mService;
+	
+	public RemoteServiceManager(IRemoteService service)
+	{
+		mService = service;
+	}
+	
+	public RemoteServiceManager()
+	{
+		mService = IRemoteService.Stub.asInterface(ServiceManager.getService(Context.REMOTE_SERVICE));
+	}
+	
+	public RemoteServiceManager(Context context)
+	{
+		// TODO Auto-generated constructor stub
+		mService = IRemoteService.Stub.asInterface(ServiceManager.getService(Context.REMOTE_SERVICE));
+	}
+	
+	/*public RemoteRequestManager()
+	{
+		mService
+	}*/
+	
+	public void startServer()
+	{
+		try
+		{
+			mService.startServer();
+		}
+		catch (RemoteException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+	public void stopServer()
+	{
+		try
+		{
+			mService.stopServer();
+		}
+		catch (RemoteException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+	public void setConfiguration()
+	{
+		try
+		{
+			mService.setConfiguration();
+		}
+		catch (RemoteException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+	public void setEnabled(boolean isEnabled)
+	{
+		try
+		{
+			mService.setEnabled(isEnabled);
+		}
+		catch (RemoteException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+	public void connectToServer(String ip)
+	{
+		try
+		{
+			mService.connectToServer(ip);
+		}
+		catch (RemoteException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+	public void disconnectToServer()
+	{
+		try
+		{
+			mService.disconnectToServer();
+		}
+		catch (RemoteException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+	public boolean sendRequest(RemoteRequest request)
+	{
+		Log.d("RemoteRequestManager", "sendRequest!!!!");
+		try
+		{
+			return mService.sendRequest(request);
+		}
+		catch (RemoteException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return false;
+	}
+	
+	public void testOperation()
+	{
+		try
+		{
+			mService.testOperation();
+		}
+		catch (RemoteException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+	public void sendMusicData(int sampleSize, byte[] to_send, long presentationTime){
+		try{
+			mService.sendMusicData(sampleSize, to_send, presentationTime);
+		}
+		catch (RemoteException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}	
+
+	}
+	
+	public void sendAllMusic(int sampleSize, byte[] to_send, long presentationTime){
+        try{
+            mService.sendMusicData(sampleSize, to_send, presentationTime);
+        }
+        catch (RemoteException e)
+        {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }   
+
+    }
+	
+	   public void sendAllrequest(RemoteRequest request){
+	        try{
+	            mService.sendAllrequest(request);
+	        }
+	        catch (RemoteException e)
+	        {
+	            // TODO Auto-generated catch block
+	            e.printStackTrace();
+	        }   
+
+	    }
+	
+	/*public void sendLocation(Location location){
+		try{
+			mService.sendLocation(location);
+		}
+		catch (RemoteException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}	
+
+	}*/
+
+	public void testVibrate()
+	{
+		// TODO Auto-generated method stub
+		try
+		{
+			mService.testVibrate();
+		}
+		catch (RemoteException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+	public void testMusic()
+	{
+		// TODO Auto-generated method stub
+		try
+		{
+			mService.testMusic();
+		}
+		catch (RemoteException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+	public void testVideo()
+	{
+		// TODO Auto-generated method stub
+		try
+		{
+			mService.testVideo();
+		}
+		catch (RemoteException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+	public void testTouch()
+	{
+		// TODO Auto-generated method stub
+		try
+		{
+			mService.testTouch();
+		}
+		catch (RemoteException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+	public void testKey()
+	{
+		// TODO Auto-generated method stub
+		try
+		{
+			mService.testKey();
+		}
+		catch (RemoteException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+	public void testSensor()
+	{
+		// TODO Auto-generated method stub
+		try
+		{
+			mService.testSensor();
+		}
+		catch (RemoteException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+	public void testLocation()
+	{
+		// TODO Auto-generated method stub
+		try
+		{
+			mService.testLocation();
+		}
+		catch (RemoteException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+	public void requestMotionEvents(){
+        // TODO Auto-generated method stub
+        try
+        {
+            mService.requestMotionEvents();
+        }
+        catch (RemoteException e)
+        {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+	}
+	
+	public void launchDummyApp(){
+	    try
+        {
+            mService.launchDummyApp();
+        }
+        catch (RemoteException e)
+        {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+	}
+	
+	public void printServerIPs(){
+	    try{
+	        mService.printServerIPs();
+	    }catch (RemoteException e){
+	        e.printStackTrace();
+	    }
+	}
+	
+}
diff -urN Original_4.4.4_r1/frameworks/base/core/java/android/service/remote/SdPackage.java AndroidSource/frameworks/base/core/java/android/service/remote/SdPackage.java
--- Original_4.4.4_r1/frameworks/base/core/java/android/service/remote/SdPackage.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/core/java/android/service/remote/SdPackage.java	2015-10-27 11:41:12.000000000 +0900
@@ -0,0 +1,79 @@
+package android.service.remote;
+
+import java.io.Serializable;
+
+
+
+public class SdPackage implements Serializable{
+
+	private int sampleSize = 0;
+	private byte[] sampleData;
+	private long presentationTime = 0;
+	private String mime = "audio/mpeg";
+	private int bitrate = 0;
+	private int channels = 0;
+	private int sampleRate = 0;
+	private long duration = 0;
+	private byte[] csd0;
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	
+	public SdPackage(int sampleSize, byte[] sampleData, long presentationTime){
+		this.sampleSize = sampleSize;
+		this.sampleData = sampleData;
+		this.presentationTime = presentationTime; 
+	}
+	
+	public SdPackage(String _mime, int _bitrate, int _channels, int _sampleRate, long _duration, byte[] _csd0){
+		this.mime = _mime;
+		this.bitrate = _bitrate;
+		this.channels = _channels;
+		this.sampleRate = _sampleRate;
+		this.duration = _duration;
+		this.csd0 = _csd0;
+	}
+	
+	public String getMime(){
+		return this.mime;
+	}
+	
+	public int getBitrate(){
+		return this.bitrate;
+	}
+	
+	public int getChannels(){
+		return this.channels;
+	}
+	
+	public int getSampleRate(){
+		return this.sampleRate;
+	}
+
+	public int getSampleSize(){
+		return this.sampleSize;
+	}
+	
+	public long getDuration(){
+		return this.duration;
+	}
+	
+	public byte[] get_csd0(){
+		return this.csd0;
+	}
+	
+	public byte[] getSampleData(){
+		return this.sampleData;
+	}
+	
+	public long getPresentationTime(){
+		return this.presentationTime;
+	}
+	
+	@Override
+	public String toString(){
+		 return this.sampleSize+" is sampleSize,  " + this.sampleData + " is sampleData,  " + this.presentationTime + " is prest. time"; 
+	}
+	
+}
diff -urN Original_4.4.4_r1/frameworks/base/core/java/android/service/remote/vData.java AndroidSource/frameworks/base/core/java/android/service/remote/vData.java
--- Original_4.4.4_r1/frameworks/base/core/java/android/service/remote/vData.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/core/java/android/service/remote/vData.java	2015-10-27 11:41:12.000000000 +0900
@@ -0,0 +1,112 @@
+package android.service.remote;
+
+import java.io.Serializable;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class vData implements Serializable{
+
+	private String mime = "video/avc";
+	private int width = 0;
+	private int height = 0;
+	private byte[] csd0 = null;
+	private byte[] csd1 = null;
+	
+	public int sampleSize = 0;
+	public byte[] sampleData;
+	public long presentationTime = 0;
+	
+	private static final long serialVersionUID = 1L;
+	
+	/**
+	 * 
+	 */
+	public vData(){
+		
+	}
+	
+	/**
+	 * 
+	 */
+	public vData(int _sampleSize, byte[] _sampleData, long _presentationTime){
+		sampleSize = _sampleSize;
+		sampleData = _sampleData;
+		presentationTime = _presentationTime;
+	}
+	
+	
+	/**
+	 * 
+	 */
+	public void setMediaFormat(String _mime, int _width, int _height, byte[] _csd0, byte[] _csd1){
+		mime = _mime;
+		width = _width;
+		height = _height;
+		csd0 = _csd0;
+		csd1 = _csd1;
+	}
+
+	/**
+	 * 
+	 */
+	public int getSampleSize(){
+		return sampleSize;
+	}
+
+	/**
+	 * 
+	 */
+	public byte[] getSampleData(){
+		return sampleData;
+	}
+
+	/**
+	 * 
+	 */
+	public long getPresentationTime(){
+		return presentationTime;
+	}	
+	/**
+	 * 
+	 */
+	public String getMime(){
+		return mime;
+	}
+	
+	/**
+	 * 
+	 */
+	public int getWidth(){
+		return width;
+	}
+	
+	/**
+	 * 
+	 */
+	public int getHeight(){
+		return height;
+	}
+
+	/**
+	 * 
+	 */
+	public byte[] get_csd0(){
+		return csd0;
+	}
+
+	/**
+	 * 
+	 */
+	public byte[] get_csd1(){
+		return csd1;
+	}
+
+	
+	@Override
+	public String toString() {
+		return sampleSize + " is sampleSize,  " + sampleData
+				+ " is sampleData,  " + presentationTime + " is prest. time";
+	}
+	
+}
diff -urN Original_4.4.4_r1/frameworks/base/core/java/android/view/MotionEvent.java AndroidSource/frameworks/base/core/java/android/view/MotionEvent.java
--- Original_4.4.4_r1/frameworks/base/core/java/android/view/MotionEvent.java	2016-01-29 15:12:27.459488000 +0900
+++ AndroidSource/frameworks/base/core/java/android/view/MotionEvent.java	2015-12-07 16:52:20.000000000 +0900
@@ -20,6 +20,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.SystemClock;
+import android.util.Log;
 import android.util.SparseArray;
 
 /**
@@ -321,6 +322,14 @@
      */
     public static final int ACTION_POINTER_INDEX_SHIFT = 8;
 
+    // ADDED BY JH
+    public static final int SOURCE_DEVICE_MASK = 0xff000000;
+    public static final int SOURCE_DEVICE_SHIFT = 24;
+    public static final int ACTION_POINTER_MASK = 0xffff;
+    // ADDED BY JH
+    
+    
+    
     /**
      * @deprecated Use {@link #ACTION_POINTER_INDEX_MASK} to retrieve the
      * data index associated with {@link #ACTION_POINTER_DOWN}.
@@ -1314,6 +1323,9 @@
     private int mNativePtr;
 
     private MotionEvent mNext;
+    
+    // ADDED BY JH
+    private int mTest;
 
     private static native int nativeInitialize(int nativePtr,
             int deviceId, int source, int action, int flags, int edgeFlags,
@@ -1321,6 +1333,15 @@
             float xOffset, float yOffset, float xPrecision, float yPrecision,
             long downTimeNanos, long eventTimeNanos,
             int pointerCount, PointerProperties[] pointerIds, PointerCoords[] pointerCoords);
+    
+    // ADDED BY JH
+    /*private static native int nativeInitialize(int nativePtr,
+            int deviceId, int source, int sourceDevice, int action, int flags, int edgeFlags,
+            int metaState, int buttonState,
+            float xOffset, float yOffset, float xPrecision, float yPrecision,
+            long downTimeNanos, long eventTimeNanos,
+            int pointerCount, PointerProperties[] pointerIds, PointerCoords[] pointerCoords);*/
+    
     private static native int nativeCopy(int destNativePtr, int sourceNativePtr,
             boolean keepHistory);
     private static native void nativeDispose(int nativePtr);
@@ -1368,6 +1389,10 @@
 
     private static native int nativeReadFromParcel(int nativePtr, Parcel parcel);
     private static native void nativeWriteToParcel(int nativePtr, Parcel parcel);
+    
+    // ADDED BY JH
+    //private static native void nativeSetSourceDevice(int nativePtr, int sourceDevice);
+    //private static native int nativeGetSourceDevice(int nativePtr);
 
     private MotionEvent() {
     }
@@ -1434,7 +1459,9 @@
             int edgeFlags, int source, int flags) {
         MotionEvent ev = obtain();
         ev.mNativePtr = nativeInitialize(ev.mNativePtr,
-                deviceId, source, action, flags, edgeFlags, metaState, buttonState,
+                deviceId, source,
+                //0, 
+                action, flags, edgeFlags, metaState, buttonState,
                 0, 0, xPrecision, yPrecision,
                 downTime * NS_PER_MS, eventTime * NS_PER_MS,
                 pointerCount, pointerProperties, pointerCoords);
@@ -1535,14 +1562,16 @@
             pc[0].size = size;
 
             ev.mNativePtr = nativeInitialize(ev.mNativePtr,
-                    deviceId, InputDevice.SOURCE_UNKNOWN, action, 0, edgeFlags, metaState, 0,
+                    deviceId, InputDevice.SOURCE_UNKNOWN, 
+                    //0, 
+                    action, 0, edgeFlags, metaState, 0,
                     0, 0, xPrecision, yPrecision,
                     downTime * NS_PER_MS, eventTime * NS_PER_MS,
                     1, pp, pc);
             return ev;
         }
     }
-
+    
     /**
      * Create a new MotionEvent, filling in all of the basic values that
      * define the motion.
@@ -1604,7 +1633,65 @@
         return obtain(downTime, eventTime, action, x, y, 1.0f, 1.0f,
                 metaState, 1.0f, 1.0f, 0, 0);
     }
+    
+    // ADDED BY JH
+    /*static public MotionEvent obtain(long downTime, long eventTime, int action,
+            float x, float y, int metaState, int source, int sourceDevice) {
+    	
+    	MotionEvent ev = obtain();
+    	
+        synchronized (gSharedTempLock) {
+            ensureSharedTempPointerCapacity(1);
+            final PointerProperties[] pp = gSharedTempPointerProperties;
+            pp[0].clear();
+            pp[0].id = 0;
+
+            final PointerCoords pc[] = gSharedTempPointerCoords;
+            pc[0].clear();
+            pc[0].x = x;
+            pc[0].y = y;
+            pc[0].pressure = 1.0f;
+            pc[0].size = 1.0f;
 
+            Log.d("MOTIONEVENT", "sourceDevice: " + sourceDevice);
+            
+            ev.mNativePtr = nativeInitialize(ev.mNativePtr,
+                    0, source, sourceDevice, action, 0, 0, metaState, 0,
+                    0, 0, 1.0f, 1.0f,
+                    downTime * NS_PER_MS, eventTime * NS_PER_MS,
+                    1, pp, pc);
+            
+            return ev;
+        }
+    }*/
+    
+    /*static public MotionEvent obtain(long downTime, long eventTime, int action,
+            float x, float y, int metaState, int source, int test) {
+    	
+    	MotionEvent ev = obtain();
+        synchronized (gSharedTempLock) {
+            ensureSharedTempPointerCapacity(1);
+            final PointerProperties[] pp = gSharedTempPointerProperties;
+            pp[0].clear();
+            pp[0].id = 0;
+
+            final PointerCoords pc[] = gSharedTempPointerCoords;
+            pc[0].clear();
+            pc[0].x = x;
+            pc[0].y = y;
+            pc[0].pressure = 1.0f;
+            pc[0].size = 1.0f;
+
+            ev.mNativePtr = nativeInitialize(ev.mNativePtr,
+                    0, action, source, 10, 0, metaState, 0,
+                    0, 0, 1.0f, 1.0f,
+                    downTime * NS_PER_MS, eventTime * NS_PER_MS,
+                    1, pp, pc);
+            return ev;
+        }
+    }*/
+    // ADDED BY JH
+    
     /**
      * Create a new MotionEvent, copying from an existing one.
      */
@@ -1689,6 +1776,22 @@
     public final void setSource(int source) {
         nativeSetSource(mNativePtr, source);
     }
+    
+    // ADDED BY JH
+    /*public final void setSourceDevice(int sourceDevice) {
+    	Log.d("MOTIONEVENT", "JAVAsourceDevice-set:" + sourceDevice);
+        nativeSetSourceDevice(mNativePtr, sourceDevice);
+    }*/
+    
+    public final int getSourceDevice() {
+        //return nativeGetSourceDevice(mNativePtr);
+        //original
+//    	return (nativeGetAction(mNativePtr) & SOURCE_DEVICE_MASK) >> SOURCE_DEVICE_SHIFT;
+        //original end
+            return (nativeGetMetaState(mNativePtr) & SOURCE_DEVICE_MASK) >> SOURCE_DEVICE_SHIFT;    
+    }
+    
+    // ADDED BY JH
 
     /**
      * Return the kind of action being performed.
@@ -1698,7 +1801,7 @@
      * the combination of {@link #ACTION_POINTER_DOWN} with a shifted pointer index.
      */
     public final int getAction() {
-        return nativeGetAction(mNativePtr);
+        return nativeGetAction(mNativePtr) & ACTION_POINTER_MASK;
     }
 
     /**
@@ -2164,7 +2267,7 @@
      * @see KeyEvent#getMetaState()
      */
     public final int getMetaState() {
-        return nativeGetMetaState(mNativePtr);
+        return nativeGetMetaState(mNativePtr) & 0x00ffffff;
     }
 
     /**
@@ -2866,6 +2969,7 @@
             }
             ev.mNativePtr = nativeInitialize(ev.mNativePtr,
                     nativeGetDeviceId(mNativePtr), nativeGetSource(mNativePtr),
+                    //nativeGetSourceDevice(mNativePtr),
                     nativeGetAction(mNativePtr), nativeGetFlags(mNativePtr),
                     nativeGetEdgeFlags(mNativePtr), nativeGetMetaState(mNativePtr),
                     nativeGetButtonState(mNativePtr),
@@ -2959,6 +3063,7 @@
                 if (h == 0) {
                     ev.mNativePtr = nativeInitialize(ev.mNativePtr,
                             nativeGetDeviceId(mNativePtr), nativeGetSource(mNativePtr),
+                            //nativeGetSourceDevice(mNativePtr),
                             newAction, nativeGetFlags(mNativePtr),
                             nativeGetEdgeFlags(mNativePtr), nativeGetMetaState(mNativePtr),
                             nativeGetButtonState(mNativePtr),
diff -urN Original_4.4.4_r1/frameworks/base/core/jni/android_hardware_SensorManager.cpp AndroidSource/frameworks/base/core/jni/android_hardware_SensorManager.cpp
--- Original_4.4.4_r1/frameworks/base/core/jni/android_hardware_SensorManager.cpp	2016-01-29 15:12:27.507488000 +0900
+++ AndroidSource/frameworks/base/core/jni/android_hardware_SensorManager.cpp	2015-10-19 13:59:58.000000000 +0900
@@ -105,6 +105,7 @@
     return size_t(next) < count ? next : 0;
 }
 
+
 //----------------------------------------------------------------------------
 
 class Receiver : public LooperCallback {
@@ -170,7 +171,8 @@
                                         buffer[i].sensor,
                                         mScratch,
                                         buffer[i].vector.status,
-                                        buffer[i].timestamp);
+                                        buffer[i].timestamp,
+                                        buffer[i].reserved0);
                 }
 
                 if (env->ExceptionCheck()) {
@@ -284,11 +286,10 @@
 
     GET_METHOD_ID(gBaseEventQueueClassInfo.dispatchSensorEvent,
             gBaseEventQueueClassInfo.clazz,
-            "dispatchSensorEvent", "(I[FIJ)V");
+            "dispatchSensorEvent", "(I[FIJI)V");
 
     GET_METHOD_ID(gBaseEventQueueClassInfo.dispatchFlushCompleteEvent,
                   gBaseEventQueueClassInfo.clazz,
                   "dispatchFlushCompleteEvent", "(I)V");
-
     return 0;
 }
diff -urN Original_4.4.4_r1/frameworks/base/core/jni/android_view_InputEventSender.cpp AndroidSource/frameworks/base/core/jni/android_view_InputEventSender.cpp
--- Original_4.4.4_r1/frameworks/base/core/jni/android_view_InputEventSender.cpp	2016-01-29 15:12:27.515488000 +0900
+++ AndroidSource/frameworks/base/core/jni/android_view_InputEventSender.cpp	2015-08-04 09:32:44.000000000 +0900
@@ -134,7 +134,9 @@
     for (size_t i = 0; i <= event->getHistorySize(); i++) {
         publishedSeq = mNextPublishedSeq++;
         status_t status = mInputPublisher.publishMotionEvent(publishedSeq,
-                event->getDeviceId(), event->getSource(), event->getAction(), event->getFlags(),
+                event->getDeviceId(), event->getSource(),
+                //event->getSourceDevice(),
+                event->getAction(), event->getFlags(),
                 event->getEdgeFlags(), event->getMetaState(), event->getButtonState(),
                 event->getXOffset(), event->getYOffset(),
                 event->getXPrecision(), event->getYPrecision(),
diff -urN Original_4.4.4_r1/frameworks/base/core/jni/android_view_MotionEvent.cpp AndroidSource/frameworks/base/core/jni/android_view_MotionEvent.cpp
--- Original_4.4.4_r1/frameworks/base/core/jni/android_view_MotionEvent.cpp	2016-01-29 15:12:27.515488000 +0900
+++ AndroidSource/frameworks/base/core/jni/android_view_MotionEvent.cpp	2015-08-04 09:32:18.000000000 +0900
@@ -386,6 +386,60 @@
     return 0;
 }
 
+// ADDED BY JH
+/*static jint android_view_MotionEvent_nativeInitialize(JNIEnv* env, jclass clazz,
+        jint nativePtr,
+        jint deviceId, jint source, jint sourceDevice, jint action, jint flags, jint edgeFlags,
+        jint metaState, jint buttonState,
+        jfloat xOffset, jfloat yOffset, jfloat xPrecision, jfloat yPrecision,
+        jlong downTimeNanos, jlong eventTimeNanos,
+        jint pointerCount, jobjectArray pointerPropertiesObjArray,
+        jobjectArray pointerCoordsObjArray) {
+    if (!validatePointerCount(env, pointerCount)
+            || !validatePointerPropertiesArray(env, pointerPropertiesObjArray, pointerCount)
+            || !validatePointerCoordsObjArray(env, pointerCoordsObjArray, pointerCount)) {
+        return 0;
+    }
+
+    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+    if (!event) {
+        event = new MotionEvent();
+    }
+
+    PointerProperties pointerProperties[pointerCount];
+    PointerCoords rawPointerCoords[pointerCount];
+
+    for (jint i = 0; i < pointerCount; i++) {
+        jobject pointerPropertiesObj = env->GetObjectArrayElement(pointerPropertiesObjArray, i);
+        if (!pointerPropertiesObj) {
+            goto Error;
+        }
+        pointerPropertiesToNative(env, pointerPropertiesObj, &pointerProperties[i]);
+        env->DeleteLocalRef(pointerPropertiesObj);
+
+        jobject pointerCoordsObj = env->GetObjectArrayElement(pointerCoordsObjArray, i);
+        if (!pointerCoordsObj) {
+            jniThrowNullPointerException(env, "pointerCoords");
+            goto Error;
+        }
+        pointerCoordsToNative(env, pointerCoordsObj, xOffset, yOffset, &rawPointerCoords[i]);
+        env->DeleteLocalRef(pointerCoordsObj);
+    }
+
+    ALOGD("JNI-nativeinit: %d", sourceDevice);
+    event->initialize(deviceId, source, sourceDevice, action, flags, edgeFlags, metaState, buttonState,
+            xOffset, yOffset, xPrecision, yPrecision,
+            downTimeNanos, eventTimeNanos, pointerCount, pointerProperties, rawPointerCoords);
+
+    return reinterpret_cast<jint>(event);
+
+Error:
+    if (!nativePtr) {
+        delete event;
+    }
+    return 0;
+}*/
+
 static jint android_view_MotionEvent_nativeCopy(JNIEnv* env, jclass clazz,
         jint destNativePtr, jint sourceNativePtr, jboolean keepHistory) {
     MotionEvent* destEvent = reinterpret_cast<MotionEvent*>(destNativePtr);
@@ -453,6 +507,22 @@
     return event->getAction();
 }
 
+// ADDED BY JH
+/*static jint android_view_MotionEvent_nativeGetSourceDevice(JNIEnv* env, jclass clazz,
+        jint nativePtr) {
+    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+    ALOGD("JNIsourceDevice-get: %d", event->getSourceDevice());
+    return event->getSourceDevice();
+}
+
+static void android_view_MotionEvent_nativeSetSourceDevice(JNIEnv* env, jclass clazz,
+        jint nativePtr, jint sourceDevice) {
+    MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+    event->setSourceDevice(sourceDevice);
+    ALOGD("JNIsourceDevice-set: %d", sourceDevice);
+}*/
+// ADDED BY JH
+
 static void android_view_MotionEvent_nativeSetAction(JNIEnv* env, jclass clazz,
         jint nativePtr, jint action) {
     MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
@@ -732,6 +802,10 @@
             "(IIIIIIIIFFFFJJI[Landroid/view/MotionEvent$PointerProperties;"
                     "[Landroid/view/MotionEvent$PointerCoords;)I",
             (void*)android_view_MotionEvent_nativeInitialize },
+	/*{ "nativeInitialize",
+			"(IIIIIIIIIFFFFJJI[Landroid/view/MotionEvent$PointerProperties;"
+					"[Landroid/view/MotionEvent$PointerCoords;)I",
+			(void*)android_view_MotionEvent_nativeInitialize },*/
     { "nativeCopy",
             "(IIZ)I",
             (void*)android_view_MotionEvent_nativeCopy },
@@ -750,6 +824,12 @@
     { "nativeSetSource",
             "(II)I",
             (void*)android_view_MotionEvent_nativeSetSource },
+/*	{ "nativeGetSourceDevice",
+			"(I)I",
+			(void*)android_view_MotionEvent_nativeGetSourceDevice },
+	{ "nativeSetSourceDevice",
+			"(II)V",
+			(void*)android_view_MotionEvent_nativeSetSourceDevice },*/
     { "nativeGetAction",
             "(I)I",
             (void*)android_view_MotionEvent_nativeGetAction },
diff -urN Original_4.4.4_r1/frameworks/base/core/res/res/values/config.xml AndroidSource/frameworks/base/core/res/res/values/config.xml
--- Original_4.4.4_r1/frameworks/base/core/res/res/values/config.xml	2016-01-29 15:12:28.427488000 +0900
+++ AndroidSource/frameworks/base/core/res/res/values/config.xml	2015-11-25 17:06:03.000000000 +0900
@@ -655,7 +655,7 @@
     <!-- Screen brightness used to dim the screen when the user activity
          timeout expires.  May be less than the minimum allowed brightness setting
          that can be set by the user. -->
-    <integer name="config_screenBrightnessDim">10</integer>
+    <integer name="config_screenBrightnessDim">1800</integer>
 
     <!-- Array of output values for LCD backlight corresponding to the LUX values
          in the config_autoBrightnessLevels array.  This array should have size one greater
diff -urN Original_4.4.4_r1/frameworks/base/.git/HEAD AndroidSource/frameworks/base/.git/HEAD
--- Original_4.4.4_r1/frameworks/base/.git/HEAD	2016-01-29 15:12:27.279488000 +0900
+++ AndroidSource/frameworks/base/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-63ade05d76785975fc3292ca030abbaa1dda8891
Binary files Original_4.4.4_r1/frameworks/base/.git/index and AndroidSource/frameworks/base/.git/index differ
diff -urN Original_4.4.4_r1/frameworks/base/location/java/android/location/ILocationManager.aidl AndroidSource/frameworks/base/location/java/android/location/ILocationManager.aidl
--- Original_4.4.4_r1/frameworks/base/location/java/android/location/ILocationManager.aidl	2016-01-29 15:12:31.431488000 +0900
+++ AndroidSource/frameworks/base/location/java/android/location/ILocationManager.aidl	2015-08-17 19:25:51.000000000 +0900
@@ -76,6 +76,9 @@
     void clearTestProviderEnabled(String provider);
     void setTestProviderStatus(String provider, int status, in Bundle extras, long updateTime);
     void clearTestProviderStatus(String provider);
+    
+    // ADDED BY JH
+    void setRemoteProviderEnabled(boolean enabled);
 
     boolean sendExtraCommand(String provider, String command, inout Bundle extras);
 
diff -urN Original_4.4.4_r1/frameworks/base/location/java/android/location/LocationManager.java AndroidSource/frameworks/base/location/java/android/location/LocationManager.java
--- Original_4.4.4_r1/frameworks/base/location/java/android/location/LocationManager.java	2016-01-29 15:12:31.431488000 +0900
+++ AndroidSource/frameworks/base/location/java/android/location/LocationManager.java	2015-11-28 06:14:04.000000000 +0900
@@ -114,6 +114,14 @@
      * @hide
      */
     public static final String FUSED_PROVIDER = "fused";
+    
+    /**
+     * ADDED BY JH
+     * 
+     * This provider gets locations from other devices.
+     * 
+     */
+    public static final String REMOTE_PROVIDER = "remote";
 
     /**
      * Key used for the Bundle extra holding a boolean indicating whether
@@ -449,6 +457,15 @@
         checkProvider(provider);
         checkListener(listener);
 
+        if(provider.equalsIgnoreCase(REMOTE_PROVIDER)){
+            try {
+                mService.setRemoteProviderEnabled(true);
+            } catch (RemoteException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+        
         LocationRequest request = LocationRequest.createFromDeprecatedProvider(
                 provider, minTime, minDistance, false);
         requestLocationUpdates(request, listener, null, null);
diff -urN Original_4.4.4_r1/frameworks/base/media/java/android/media/MediaPlayer.java AndroidSource/frameworks/base/media/java/android/media/MediaPlayer.java
--- Original_4.4.4_r1/frameworks/base/media/java/android/media/MediaPlayer.java	2016-01-29 15:12:31.439488000 +0900
+++ AndroidSource/frameworks/base/media/java/android/media/MediaPlayer.java	2016-09-26 18:37:06.839666097 +0900
@@ -16,548 +16,609 @@
 
 package android.media;
 
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.lang.ref.WeakReference;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.URI;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Scanner;
+import java.util.Set;
+import java.util.Vector;
+import java.util.concurrent.ExecutionException;
+
+import android.service.remote.AppendingObjectOutputStream;
+import android.service.remote.IRemoteService;
+import android.service.remote.vData;
+import android.service.remote.SdPackage;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.res.AssetFileDescriptor;
+import android.graphics.SurfaceTexture;
 import android.net.Proxy;
 import android.net.ProxyProperties;
 import android.net.Uri;
+import android.os.AsyncTask;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Message;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.ParcelFileDescriptor;
-import android.os.Process;
 import android.os.PowerManager;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.service.remote.RemoteRequest;
 import android.util.Log;
+import android.util.SparseArray;
 import android.view.Surface;
 import android.view.SurfaceHolder;
-import android.graphics.Bitmap;
-import android.graphics.SurfaceTexture;
-import android.media.AudioManager;
-import android.media.MediaFormat;
-import android.media.MediaTimeProvider;
-import android.media.MediaTimeProvider.OnMediaTimeListener;
-import android.media.SubtitleController;
-import android.media.SubtitleData;
-
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.Runnable;
-import java.net.InetSocketAddress;
-import java.util.Map;
-import java.util.Scanner;
-import java.util.Set;
-import java.util.Vector;
-import java.lang.ref.WeakReference;
 
 /**
- * MediaPlayer class can be used to control playback
- * of audio/video files and streams. An example on how to use the methods in
- * this class can be found in {@link android.widget.VideoView}.
- *
- * <p>Topics covered here are:
+ * MediaPlayer class can be used to control playback of audio/video files and
+ * streams. An example on how to use the methods in this class can be found in
+ * {@link android.widget.VideoView}.
+ * <p>
+ * Topics covered here are:
  * <ol>
  * <li><a href="#StateDiagram">State Diagram</a>
  * <li><a href="#Valid_and_Invalid_States">Valid and Invalid States</a>
  * <li><a href="#Permissions">Permissions</a>
  * <li><a href="#Callbacks">Register informational and error callbacks</a>
  * </ol>
- *
  * <div class="special reference">
  * <h3>Developer Guides</h3>
- * <p>For more information about how to use MediaPlayer, read the
- * <a href="{@docRoot}guide/topics/media/mediaplayer.html">Media Playback</a> developer guide.</p>
- * </div>
- *
- * <a name="StateDiagram"></a>
- * <h3>State Diagram</h3>
- *
- * <p>Playback control of audio/video files and streams is managed as a state
+ * <p>
+ * For more information about how to use MediaPlayer, read the <a
+ * href="{@docRoot}guide/topics/media/mediaplayer.html">Media Playback</a>
+ * developer guide.
+ * </p>
+ * </div> <a name="StateDiagram"></a> <h3>State Diagram</h3>
+ * <p>
+ * Playback control of audio/video files and streams is managed as a state
  * machine. The following diagram shows the life cycle and the states of a
- * MediaPlayer object driven by the supported playback control operations.
- * The ovals represent the states a MediaPlayer object may reside
- * in. The arcs represent the playback control operations that drive the object
- * state transition. There are two types of arcs. The arcs with a single arrow
- * head represent synchronous method calls, while those with
- * a double arrow head represent asynchronous method calls.</p>
- *
- * <p><img src="../../../images/mediaplayer_state_diagram.gif"
- *         alt="MediaPlayer State diagram"
- *         border="0" /></p>
- *
- * <p>From this state diagram, one can see that a MediaPlayer object has the
- *    following states:</p>
+ * MediaPlayer object driven by the supported playback control operations. The
+ * ovals represent the states a MediaPlayer object may reside in. The arcs
+ * represent the playback control operations that drive the object state
+ * transition. There are two types of arcs. The arcs with a single arrow head
+ * represent synchronous method calls, while those with a double arrow head
+ * represent asynchronous method calls.
+ * </p>
+ * <p>
+ * <img src="../../../images/mediaplayer_state_diagram.gif"
+ * alt="MediaPlayer State diagram" border="0" />
+ * </p>
+ * <p>
+ * From this state diagram, one can see that a MediaPlayer object has the
+ * following states:
+ * </p>
+ * <ul>
+ * <li>When a MediaPlayer object is just created using <code>new</code> or after
+ * {@link #reset()} is called, it is in the <em>Idle</em> state; and after
+ * {@link #release()} is called, it is in the <em>End</em> state. Between these
+ * two states is the life cycle of the MediaPlayer object.
+ * <ul>
+ * <li>There is a subtle but important difference between a newly constructed
+ * MediaPlayer object and the MediaPlayer object after {@link #reset()} is
+ * called. It is a programming error to invoke methods such as
+ * {@link #getCurrentPosition()}, {@link #getDuration()},
+ * {@link #getVideoHeight()}, {@link #getVideoWidth()},
+ * {@link #setAudioStreamType(int)}, {@link #setLooping(boolean)},
+ * {@link #setVolume(float, float)}, {@link #pause()}, {@link #start()},
+ * {@link #stop()}, {@link #seekTo(int)}, {@link #prepare()} or
+ * {@link #prepareAsync()} in the <em>Idle</em> state for both cases. If any of
+ * these methods is called right after a MediaPlayer object is constructed, the
+ * user supplied callback method OnErrorListener.onError() won't be called by
+ * the internal player engine and the object state remains unchanged; but if
+ * these methods are called right after {@link #reset()}, the user supplied
+ * callback method OnErrorListener.onError() will be invoked by the internal
+ * player engine and the object will be transfered to the <em>Error</em> state.</li>
+ * <li>It is also recommended that once a MediaPlayer object is no longer being
+ * used, call {@link #release()} immediately so that resources used by the
+ * internal player engine associated with the MediaPlayer object can be released
+ * immediately. Resource may include singleton resources such as hardware
+ * acceleration components and failure to call {@link #release()} may cause
+ * subsequent instances of MediaPlayer objects to fallback to software
+ * implementations or fail altogether. Once the MediaPlayer object is in the
+ * <em>End</em> state, it can no longer be used and there is no way to bring it
+ * back to any other state.</li>
+ * <li>Furthermore, the MediaPlayer objects created using <code>new</code> is in
+ * the <em>Idle</em> state, while those created with one of the overloaded
+ * convenient <code>create</code> methods are <em>NOT</em> in the <em>Idle</em>
+ * state. In fact, the objects are in the <em>Prepared</em> state if the
+ * creation using <code>create</code> method is successful.</li>
+ * </ul>
+ * </li>
+ * <li>In general, some playback control operation may fail due to various
+ * reasons, such as unsupported audio/video format, poorly interleaved
+ * audio/video, resolution too high, streaming timeout, and the like. Thus,
+ * error reporting and recovery is an important concern under these
+ * circumstances. Sometimes, due to programming errors, invoking a playback
+ * control operation in an invalid state may also occur. Under all these error
+ * conditions, the internal player engine invokes a user supplied
+ * OnErrorListener.onError() method if an OnErrorListener has been registered
+ * beforehand via
+ * {@link #setOnErrorListener(android.media.MediaPlayer.OnErrorListener)}.
+ * <ul>
+ * <li>It is important to note that once an error occurs, the MediaPlayer object
+ * enters the <em>Error</em> state (except as noted above), even if an error
+ * listener has not been registered by the application.</li>
+ * <li>In order to reuse a MediaPlayer object that is in the <em>
+ *         Error</em> state and recover from the error, {@link #reset()} can be
+ * called to restore the object to its <em>Idle</em> state.</li>
+ * <li>It is good programming practice to have your application register a
+ * OnErrorListener to look out for error notifications from the internal player
+ * engine.</li>
+ * <li>IllegalStateException is thrown to prevent programming errors such as
+ * calling {@link #prepare()}, {@link #prepareAsync()}, or one of the overloaded
+ * <code>setDataSource
+ *         </code> methods in an invalid state.</li>
+ * </ul>
+ * </li>
+ * <li>Calling {@link #setDataSource(FileDescriptor)}, or
+ * {@link #setDataSource(String)}, or {@link #setDataSource(Context, Uri)}, or
+ * {@link #setDataSource(FileDescriptor, long, long)} transfers a MediaPlayer
+ * object in the <em>Idle</em> state to the <em>Initialized</em> state.
+ * <ul>
+ * <li>An IllegalStateException is thrown if setDataSource() is called in any
+ * other state.</li>
+ * <li>It is good programming practice to always look out for
+ * <code>IllegalArgumentException</code> and <code>IOException</code> that may
+ * be thrown from the overloaded <code>setDataSource</code> methods.</li>
+ * </ul>
+ * </li>
+ * <li>A MediaPlayer object must first enter the <em>Prepared</em> state before
+ * playback can be started.
+ * <ul>
+ * <li>There are two ways (synchronous vs. asynchronous) that the
+ * <em>Prepared</em> state can be reached: either a call to {@link #prepare()}
+ * (synchronous) which transfers the object to the <em>Prepared</em> state once
+ * the method call returns, or a call to {@link #prepareAsync()} (asynchronous)
+ * which first transfers the object to the <em>Preparing</em> state after the
+ * call returns (which occurs almost right way) while the internal player engine
+ * continues working on the rest of preparation work until the preparation work
+ * completes. When the preparation completes or when {@link #prepare()} call
+ * returns, the internal player engine then calls a user supplied callback
+ * method, onPrepared() of the OnPreparedListener interface, if an
+ * OnPreparedListener is registered beforehand via
+ * {@link #setOnPreparedListener(android.media.MediaPlayer.OnPreparedListener)}.
+ * </li>
+ * <li>It is important to note that the <em>Preparing</em> state is a transient
+ * state, and the behavior of calling any method with side effect while a
+ * MediaPlayer object is in the <em>Preparing</em> state is undefined.</li>
+ * <li>An IllegalStateException is thrown if {@link #prepare()} or
+ * {@link #prepareAsync()} is called in any other state.</li>
+ * <li>While in the <em>Prepared</em> state, properties such as audio/sound
+ * volume, screenOnWhilePlaying, looping can be adjusted by invoking the
+ * corresponding set methods.</li>
+ * </ul>
+ * </li>
+ * <li>To start the playback, {@link #start()} must be called. After
+ * {@link #start()} returns successfully, the MediaPlayer object is in the
+ * <em>Started</em> state. {@link #isPlaying()} can be called to test whether
+ * the MediaPlayer object is in the <em>Started</em> state.
  * <ul>
- *     <li>When a MediaPlayer object is just created using <code>new</code> or
- *         after {@link #reset()} is called, it is in the <em>Idle</em> state; and after
- *         {@link #release()} is called, it is in the <em>End</em> state. Between these
- *         two states is the life cycle of the MediaPlayer object.
- *         <ul>
- *         <li>There is a subtle but important difference between a newly constructed
- *         MediaPlayer object and the MediaPlayer object after {@link #reset()}
- *         is called. It is a programming error to invoke methods such
- *         as {@link #getCurrentPosition()},
- *         {@link #getDuration()}, {@link #getVideoHeight()},
- *         {@link #getVideoWidth()}, {@link #setAudioStreamType(int)},
- *         {@link #setLooping(boolean)},
- *         {@link #setVolume(float, float)}, {@link #pause()}, {@link #start()},
- *         {@link #stop()}, {@link #seekTo(int)}, {@link #prepare()} or
- *         {@link #prepareAsync()} in the <em>Idle</em> state for both cases. If any of these
- *         methods is called right after a MediaPlayer object is constructed,
- *         the user supplied callback method OnErrorListener.onError() won't be
- *         called by the internal player engine and the object state remains
- *         unchanged; but if these methods are called right after {@link #reset()},
- *         the user supplied callback method OnErrorListener.onError() will be
- *         invoked by the internal player engine and the object will be
- *         transfered to the <em>Error</em> state. </li>
- *         <li>It is also recommended that once
- *         a MediaPlayer object is no longer being used, call {@link #release()} immediately
- *         so that resources used by the internal player engine associated with the
- *         MediaPlayer object can be released immediately. Resource may include
- *         singleton resources such as hardware acceleration components and
- *         failure to call {@link #release()} may cause subsequent instances of
- *         MediaPlayer objects to fallback to software implementations or fail
- *         altogether. Once the MediaPlayer
- *         object is in the <em>End</em> state, it can no longer be used and
- *         there is no way to bring it back to any other state. </li>
- *         <li>Furthermore,
- *         the MediaPlayer objects created using <code>new</code> is in the
- *         <em>Idle</em> state, while those created with one
- *         of the overloaded convenient <code>create</code> methods are <em>NOT</em>
- *         in the <em>Idle</em> state. In fact, the objects are in the <em>Prepared</em>
- *         state if the creation using <code>create</code> method is successful.
- *         </li>
- *         </ul>
- *         </li>
- *     <li>In general, some playback control operation may fail due to various
- *         reasons, such as unsupported audio/video format, poorly interleaved
- *         audio/video, resolution too high, streaming timeout, and the like.
- *         Thus, error reporting and recovery is an important concern under
- *         these circumstances. Sometimes, due to programming errors, invoking a playback
- *         control operation in an invalid state may also occur. Under all these
- *         error conditions, the internal player engine invokes a user supplied
- *         OnErrorListener.onError() method if an OnErrorListener has been
- *         registered beforehand via
- *         {@link #setOnErrorListener(android.media.MediaPlayer.OnErrorListener)}.
- *         <ul>
- *         <li>It is important to note that once an error occurs, the
- *         MediaPlayer object enters the <em>Error</em> state (except as noted
- *         above), even if an error listener has not been registered by the application.</li>
- *         <li>In order to reuse a MediaPlayer object that is in the <em>
- *         Error</em> state and recover from the error,
- *         {@link #reset()} can be called to restore the object to its <em>Idle</em>
- *         state.</li>
- *         <li>It is good programming practice to have your application
- *         register a OnErrorListener to look out for error notifications from
- *         the internal player engine.</li>
- *         <li>IllegalStateException is
- *         thrown to prevent programming errors such as calling {@link #prepare()},
- *         {@link #prepareAsync()}, or one of the overloaded <code>setDataSource
- *         </code> methods in an invalid state. </li>
- *         </ul>
- *         </li>
- *     <li>Calling
- *         {@link #setDataSource(FileDescriptor)}, or
- *         {@link #setDataSource(String)}, or
- *         {@link #setDataSource(Context, Uri)}, or
- *         {@link #setDataSource(FileDescriptor, long, long)} transfers a
- *         MediaPlayer object in the <em>Idle</em> state to the
- *         <em>Initialized</em> state.
- *         <ul>
- *         <li>An IllegalStateException is thrown if
- *         setDataSource() is called in any other state.</li>
- *         <li>It is good programming
- *         practice to always look out for <code>IllegalArgumentException</code>
- *         and <code>IOException</code> that may be thrown from the overloaded
- *         <code>setDataSource</code> methods.</li>
- *         </ul>
- *         </li>
- *     <li>A MediaPlayer object must first enter the <em>Prepared</em> state
- *         before playback can be started.
- *         <ul>
- *         <li>There are two ways (synchronous vs.
- *         asynchronous) that the <em>Prepared</em> state can be reached:
- *         either a call to {@link #prepare()} (synchronous) which
- *         transfers the object to the <em>Prepared</em> state once the method call
- *         returns, or a call to {@link #prepareAsync()} (asynchronous) which
- *         first transfers the object to the <em>Preparing</em> state after the
- *         call returns (which occurs almost right way) while the internal
- *         player engine continues working on the rest of preparation work
- *         until the preparation work completes. When the preparation completes or when {@link #prepare()} call returns,
- *         the internal player engine then calls a user supplied callback method,
- *         onPrepared() of the OnPreparedListener interface, if an
- *         OnPreparedListener is registered beforehand via {@link
- *         #setOnPreparedListener(android.media.MediaPlayer.OnPreparedListener)}.</li>
- *         <li>It is important to note that
- *         the <em>Preparing</em> state is a transient state, and the behavior
- *         of calling any method with side effect while a MediaPlayer object is
- *         in the <em>Preparing</em> state is undefined.</li>
- *         <li>An IllegalStateException is
- *         thrown if {@link #prepare()} or {@link #prepareAsync()} is called in
- *         any other state.</li>
- *         <li>While in the <em>Prepared</em> state, properties
- *         such as audio/sound volume, screenOnWhilePlaying, looping can be
- *         adjusted by invoking the corresponding set methods.</li>
- *         </ul>
- *         </li>
- *     <li>To start the playback, {@link #start()} must be called. After
- *         {@link #start()} returns successfully, the MediaPlayer object is in the
- *         <em>Started</em> state. {@link #isPlaying()} can be called to test
- *         whether the MediaPlayer object is in the <em>Started</em> state.
- *         <ul>
- *         <li>While in the <em>Started</em> state, the internal player engine calls
- *         a user supplied OnBufferingUpdateListener.onBufferingUpdate() callback
- *         method if a OnBufferingUpdateListener has been registered beforehand
- *         via {@link #setOnBufferingUpdateListener(OnBufferingUpdateListener)}.
- *         This callback allows applications to keep track of the buffering status
- *         while streaming audio/video.</li>
- *         <li>Calling {@link #start()} has not effect
- *         on a MediaPlayer object that is already in the <em>Started</em> state.</li>
- *         </ul>
- *         </li>
- *     <li>Playback can be paused and stopped, and the current playback position
- *         can be adjusted. Playback can be paused via {@link #pause()}. When the call to
- *         {@link #pause()} returns, the MediaPlayer object enters the
- *         <em>Paused</em> state. Note that the transition from the <em>Started</em>
- *         state to the <em>Paused</em> state and vice versa happens
- *         asynchronously in the player engine. It may take some time before
- *         the state is updated in calls to {@link #isPlaying()}, and it can be
- *         a number of seconds in the case of streamed content.
- *         <ul>
- *         <li>Calling {@link #start()} to resume playback for a paused
- *         MediaPlayer object, and the resumed playback
- *         position is the same as where it was paused. When the call to
- *         {@link #start()} returns, the paused MediaPlayer object goes back to
- *         the <em>Started</em> state.</li>
- *         <li>Calling {@link #pause()} has no effect on
- *         a MediaPlayer object that is already in the <em>Paused</em> state.</li>
- *         </ul>
- *         </li>
- *     <li>Calling  {@link #stop()} stops playback and causes a
- *         MediaPlayer in the <em>Started</em>, <em>Paused</em>, <em>Prepared
+ * <li>While in the <em>Started</em> state, the internal player engine calls a
+ * user supplied OnBufferingUpdateListener.onBufferingUpdate() callback method
+ * if a OnBufferingUpdateListener has been registered beforehand via
+ * {@link #setOnBufferingUpdateListener(OnBufferingUpdateListener)}. This
+ * callback allows applications to keep track of the buffering status while
+ * streaming audio/video.</li>
+ * <li>Calling {@link #start()} has not effect on a MediaPlayer object that is
+ * already in the <em>Started</em> state.</li>
+ * </ul>
+ * </li>
+ * <li>Playback can be paused and stopped, and the current playback position can
+ * be adjusted. Playback can be paused via {@link #pause()}. When the call to
+ * {@link #pause()} returns, the MediaPlayer object enters the <em>Paused</em>
+ * state. Note that the transition from the <em>Started</em> state to the
+ * <em>Paused</em> state and vice versa happens asynchronously in the player
+ * engine. It may take some time before the state is updated in calls to
+ * {@link #isPlaying()}, and it can be a number of seconds in the case of
+ * streamed content.
+ * <ul>
+ * <li>Calling {@link #start()} to resume playback for a paused MediaPlayer
+ * object, and the resumed playback position is the same as where it was paused.
+ * When the call to {@link #start()} returns, the paused MediaPlayer object goes
+ * back to the <em>Started</em> state.</li>
+ * <li>Calling {@link #pause()} has no effect on a MediaPlayer object that is
+ * already in the <em>Paused</em> state.</li>
+ * </ul>
+ * </li>
+ * <li>Calling {@link #stop()} stops playback and causes a MediaPlayer in the
+ * <em>Started</em>, <em>Paused</em>, <em>Prepared
  *         </em> or <em>PlaybackCompleted</em> state to enter the
- *         <em>Stopped</em> state.
- *         <ul>
- *         <li>Once in the <em>Stopped</em> state, playback cannot be started
- *         until {@link #prepare()} or {@link #prepareAsync()} are called to set
- *         the MediaPlayer object to the <em>Prepared</em> state again.</li>
- *         <li>Calling {@link #stop()} has no effect on a MediaPlayer
- *         object that is already in the <em>Stopped</em> state.</li>
- *         </ul>
- *         </li>
- *     <li>The playback position can be adjusted with a call to
- *         {@link #seekTo(int)}.
- *         <ul>
- *         <li>Although the asynchronuous {@link #seekTo(int)}
- *         call returns right way, the actual seek operation may take a while to
- *         finish, especially for audio/video being streamed. When the actual
- *         seek operation completes, the internal player engine calls a user
- *         supplied OnSeekComplete.onSeekComplete() if an OnSeekCompleteListener
- *         has been registered beforehand via
- *         {@link #setOnSeekCompleteListener(OnSeekCompleteListener)}.</li>
- *         <li>Please
- *         note that {@link #seekTo(int)} can also be called in the other states,
- *         such as <em>Prepared</em>, <em>Paused</em> and <em>PlaybackCompleted
+ * <em>Stopped</em> state.
+ * <ul>
+ * <li>Once in the <em>Stopped</em> state, playback cannot be started until
+ * {@link #prepare()} or {@link #prepareAsync()} are called to set the
+ * MediaPlayer object to the <em>Prepared</em> state again.</li>
+ * <li>Calling {@link #stop()} has no effect on a MediaPlayer object that is
+ * already in the <em>Stopped</em> state.</li>
+ * </ul>
+ * </li>
+ * <li>The playback position can be adjusted with a call to {@link #seekTo(int)}.
+ * <ul>
+ * <li>Although the asynchronuous {@link #seekTo(int)} call returns right way,
+ * the actual seek operation may take a while to finish, especially for
+ * audio/video being streamed. When the actual seek operation completes, the
+ * internal player engine calls a user supplied OnSeekComplete.onSeekComplete()
+ * if an OnSeekCompleteListener has been registered beforehand via
+ * {@link #setOnSeekCompleteListener(OnSeekCompleteListener)}.</li>
+ * <li>Please note that {@link #seekTo(int)} can also be called in the other
+ * states, such as <em>Prepared</em>, <em>Paused</em> and <em>PlaybackCompleted
  *         </em> state.</li>
- *         <li>Furthermore, the actual current playback position
- *         can be retrieved with a call to {@link #getCurrentPosition()}, which
- *         is helpful for applications such as a Music player that need to keep
- *         track of the playback progress.</li>
- *         </ul>
- *         </li>
- *     <li>When the playback reaches the end of stream, the playback completes.
- *         <ul>
- *         <li>If the looping mode was being set to <var>true</var>with
- *         {@link #setLooping(boolean)}, the MediaPlayer object shall remain in
- *         the <em>Started</em> state.</li>
- *         <li>If the looping mode was set to <var>false
- *         </var>, the player engine calls a user supplied callback method,
- *         OnCompletion.onCompletion(), if a OnCompletionListener is registered
- *         beforehand via {@link #setOnCompletionListener(OnCompletionListener)}.
- *         The invoke of the callback signals that the object is now in the <em>
+ * <li>Furthermore, the actual current playback position can be retrieved with a
+ * call to {@link #getCurrentPosition()}, which is helpful for applications such
+ * as a Music player that need to keep track of the playback progress.</li>
+ * </ul>
+ * </li>
+ * <li>When the playback reaches the end of stream, the playback completes.
+ * <ul>
+ * <li>If the looping mode was being set to <var>true</var>with
+ * {@link #setLooping(boolean)}, the MediaPlayer object shall remain in the
+ * <em>Started</em> state.</li>
+ * <li>If the looping mode was set to <var>false </var>, the player engine calls
+ * a user supplied callback method, OnCompletion.onCompletion(), if a
+ * OnCompletionListener is registered beforehand via
+ * {@link #setOnCompletionListener(OnCompletionListener)}. The invoke of the
+ * callback signals that the object is now in the <em>
  *         PlaybackCompleted</em> state.</li>
- *         <li>While in the <em>PlaybackCompleted</em>
- *         state, calling {@link #start()} can restart the playback from the
- *         beginning of the audio/video source.</li>
+ * <li>While in the <em>PlaybackCompleted</em> state, calling {@link #start()}
+ * can restart the playback from the beginning of the audio/video source.</li>
  * </ul>
- *
- *
  * <a name="Valid_and_Invalid_States"></a>
  * <h3>Valid and invalid states</h3>
- *
  * <table border="0" cellspacing="0" cellpadding="0">
- * <tr><td>Method Name </p></td>
- *     <td>Valid Sates </p></td>
- *     <td>Invalid States </p></td>
- *     <td>Comments </p></td></tr>
- * <tr><td>attachAuxEffect </p></td>
- *     <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} </p></td>
- *     <td>{Idle, Error} </p></td>
- *     <td>This method must be called after setDataSource.
- *     Calling it does not change the object state. </p></td></tr>
- * <tr><td>getAudioSessionId </p></td>
- *     <td>any </p></td>
- *     <td>{} </p></td>
- *     <td>This method can be called in any state and calling it does not change
- *         the object state. </p></td></tr>
- * <tr><td>getCurrentPosition </p></td>
- *     <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
- *         PlaybackCompleted} </p></td>
- *     <td>{Error}</p></td>
- *     <td>Successful invoke of this method in a valid state does not change the
- *         state. Calling this method in an invalid state transfers the object
- *         to the <em>Error</em> state. </p></td></tr>
- * <tr><td>getDuration </p></td>
- *     <td>{Prepared, Started, Paused, Stopped, PlaybackCompleted} </p></td>
- *     <td>{Idle, Initialized, Error} </p></td>
- *     <td>Successful invoke of this method in a valid state does not change the
- *         state. Calling this method in an invalid state transfers the object
- *         to the <em>Error</em> state. </p></td></tr>
- * <tr><td>getVideoHeight </p></td>
- *     <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
- *         PlaybackCompleted}</p></td>
- *     <td>{Error}</p></td>
- *     <td>Successful invoke of this method in a valid state does not change the
- *         state. Calling this method in an invalid state transfers the object
- *         to the <em>Error</em> state.  </p></td></tr>
- * <tr><td>getVideoWidth </p></td>
- *     <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
- *         PlaybackCompleted}</p></td>
- *     <td>{Error}</p></td>
- *     <td>Successful invoke of this method in a valid state does not change
- *         the state. Calling this method in an invalid state transfers the
- *         object to the <em>Error</em> state. </p></td></tr>
- * <tr><td>isPlaying </p></td>
- *     <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
- *          PlaybackCompleted}</p></td>
- *     <td>{Error}</p></td>
- *     <td>Successful invoke of this method in a valid state does not change
- *         the state. Calling this method in an invalid state transfers the
- *         object to the <em>Error</em> state. </p></td></tr>
- * <tr><td>pause </p></td>
- *     <td>{Started, Paused, PlaybackCompleted}</p></td>
- *     <td>{Idle, Initialized, Prepared, Stopped, Error}</p></td>
- *     <td>Successful invoke of this method in a valid state transfers the
- *         object to the <em>Paused</em> state. Calling this method in an
- *         invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
- * <tr><td>prepare </p></td>
- *     <td>{Initialized, Stopped} </p></td>
- *     <td>{Idle, Prepared, Started, Paused, PlaybackCompleted, Error} </p></td>
- *     <td>Successful invoke of this method in a valid state transfers the
- *         object to the <em>Prepared</em> state. Calling this method in an
- *         invalid state throws an IllegalStateException.</p></td></tr>
- * <tr><td>prepareAsync </p></td>
- *     <td>{Initialized, Stopped} </p></td>
- *     <td>{Idle, Prepared, Started, Paused, PlaybackCompleted, Error} </p></td>
- *     <td>Successful invoke of this method in a valid state transfers the
- *         object to the <em>Preparing</em> state. Calling this method in an
- *         invalid state throws an IllegalStateException.</p></td></tr>
- * <tr><td>release </p></td>
- *     <td>any </p></td>
- *     <td>{} </p></td>
- *     <td>After {@link #release()}, the object is no longer available. </p></td></tr>
- * <tr><td>reset </p></td>
- *     <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
- *         PlaybackCompleted, Error}</p></td>
- *     <td>{}</p></td>
- *     <td>After {@link #reset()}, the object is like being just created.</p></td></tr>
- * <tr><td>seekTo </p></td>
- *     <td>{Prepared, Started, Paused, PlaybackCompleted} </p></td>
- *     <td>{Idle, Initialized, Stopped, Error}</p></td>
- *     <td>Successful invoke of this method in a valid state does not change
- *         the state. Calling this method in an invalid state transfers the
- *         object to the <em>Error</em> state. </p></td></tr>
- * <tr><td>setAudioSessionId </p></td>
- *     <td>{Idle} </p></td>
- *     <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted,
- *          Error} </p></td>
- *     <td>This method must be called in idle state as the audio session ID must be known before
- *         calling setDataSource. Calling it does not change the object state. </p></td></tr>
- * <tr><td>setAudioStreamType </p></td>
- *     <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
- *          PlaybackCompleted}</p></td>
- *     <td>{Error}</p></td>
- *     <td>Successful invoke of this method does not change the state. In order for the
- *         target audio stream type to become effective, this method must be called before
- *         prepare() or prepareAsync().</p></td></tr>
- * <tr><td>setAuxEffectSendLevel </p></td>
- *     <td>any</p></td>
- *     <td>{} </p></td>
- *     <td>Calling this method does not change the object state. </p></td></tr>
- * <tr><td>setDataSource </p></td>
- *     <td>{Idle} </p></td>
- *     <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted,
- *          Error} </p></td>
- *     <td>Successful invoke of this method in a valid state transfers the
- *         object to the <em>Initialized</em> state. Calling this method in an
- *         invalid state throws an IllegalStateException.</p></td></tr>
- * <tr><td>setDisplay </p></td>
- *     <td>any </p></td>
- *     <td>{} </p></td>
- *     <td>This method can be called in any state and calling it does not change
- *         the object state. </p></td></tr>
- * <tr><td>setSurface </p></td>
- *     <td>any </p></td>
- *     <td>{} </p></td>
- *     <td>This method can be called in any state and calling it does not change
- *         the object state. </p></td></tr>
- * <tr><td>setVideoScalingMode </p></td>
- *     <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} </p></td>
- *     <td>{Idle, Error}</p></td>
- *     <td>Successful invoke of this method does not change the state.</p></td></tr>
- * <tr><td>setLooping </p></td>
- *     <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
- *         PlaybackCompleted}</p></td>
- *     <td>{Error}</p></td>
- *     <td>Successful invoke of this method in a valid state does not change
- *         the state. Calling this method in an
- *         invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
- * <tr><td>isLooping </p></td>
- *     <td>any </p></td>
- *     <td>{} </p></td>
- *     <td>This method can be called in any state and calling it does not change
- *         the object state. </p></td></tr>
- * <tr><td>setOnBufferingUpdateListener </p></td>
- *     <td>any </p></td>
- *     <td>{} </p></td>
- *     <td>This method can be called in any state and calling it does not change
- *         the object state. </p></td></tr>
- * <tr><td>setOnCompletionListener </p></td>
- *     <td>any </p></td>
- *     <td>{} </p></td>
- *     <td>This method can be called in any state and calling it does not change
- *         the object state. </p></td></tr>
- * <tr><td>setOnErrorListener </p></td>
- *     <td>any </p></td>
- *     <td>{} </p></td>
- *     <td>This method can be called in any state and calling it does not change
- *         the object state. </p></td></tr>
- * <tr><td>setOnPreparedListener </p></td>
- *     <td>any </p></td>
- *     <td>{} </p></td>
- *     <td>This method can be called in any state and calling it does not change
- *         the object state. </p></td></tr>
- * <tr><td>setOnSeekCompleteListener </p></td>
- *     <td>any </p></td>
- *     <td>{} </p></td>
- *     <td>This method can be called in any state and calling it does not change
- *         the object state. </p></td></tr>
- * <tr><td>setScreenOnWhilePlaying</></td>
- *     <td>any </p></td>
- *     <td>{} </p></td>
- *     <td>This method can be called in any state and calling it does not change
- *         the object state.  </p></td></tr>
- * <tr><td>setVolume </p></td>
- *     <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
- *          PlaybackCompleted}</p></td>
- *     <td>{Error}</p></td>
- *     <td>Successful invoke of this method does not change the state.
- * <tr><td>setWakeMode </p></td>
- *     <td>any </p></td>
- *     <td>{} </p></td>
- *     <td>This method can be called in any state and calling it does not change
- *         the object state.</p></td></tr>
- * <tr><td>start </p></td>
- *     <td>{Prepared, Started, Paused, PlaybackCompleted}</p></td>
- *     <td>{Idle, Initialized, Stopped, Error}</p></td>
- *     <td>Successful invoke of this method in a valid state transfers the
- *         object to the <em>Started</em> state. Calling this method in an
- *         invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
- * <tr><td>stop </p></td>
- *     <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
- *     <td>{Idle, Initialized, Error}</p></td>
- *     <td>Successful invoke of this method in a valid state transfers the
- *         object to the <em>Stopped</em> state. Calling this method in an
- *         invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
- * <tr><td>getTrackInfo </p></td>
- *     <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
- *     <td>{Idle, Initialized, Error}</p></td>
- *     <td>Successful invoke of this method does not change the state.</p></td></tr>
- * <tr><td>addTimedTextSource </p></td>
- *     <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
- *     <td>{Idle, Initialized, Error}</p></td>
- *     <td>Successful invoke of this method does not change the state.</p></td></tr>
- * <tr><td>selectTrack </p></td>
- *     <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
- *     <td>{Idle, Initialized, Error}</p></td>
- *     <td>Successful invoke of this method does not change the state.</p></td></tr>
- * <tr><td>deselectTrack </p></td>
- *     <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
- *     <td>{Idle, Initialized, Error}</p></td>
- *     <td>Successful invoke of this method does not change the state.</p></td></tr>
- *
+ * <tr>
+ * <td>Method Name </p></td>
+ * <td>Valid Sates </p></td>
+ * <td>Invalid States </p></td>
+ * <td>Comments </p></td>
+ * </tr>
+ * <tr>
+ * <td>attachAuxEffect </p></td>
+ * <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} </p>
+ * </td>
+ * <td>{Idle, Error} </p></td>
+ * <td>This method must be called after setDataSource. Calling it does not
+ * change the object state. </p></td>
+ * </tr>
+ * <tr>
+ * <td>getAudioSessionId </p></td>
+ * <td>any </p></td>
+ * <td>{} </p></td>
+ * <td>This method can be called in any state and calling it does not change the
+ * object state. </p></td>
+ * </tr>
+ * <tr>
+ * <td>getCurrentPosition </p></td>
+ * <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
+ * PlaybackCompleted} </p></td>
+ * <td>{Error}</p></td>
+ * <td>Successful invoke of this method in a valid state does not change the
+ * state. Calling this method in an invalid state transfers the object to the
+ * <em>Error</em> state. </p></td>
+ * </tr>
+ * <tr>
+ * <td>getDuration </p></td>
+ * <td>{Prepared, Started, Paused, Stopped, PlaybackCompleted} </p></td>
+ * <td>{Idle, Initialized, Error} </p></td>
+ * <td>Successful invoke of this method in a valid state does not change the
+ * state. Calling this method in an invalid state transfers the object to the
+ * <em>Error</em> state. </p></td>
+ * </tr>
+ * <tr>
+ * <td>getVideoHeight </p></td>
+ * <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
+ * PlaybackCompleted}</p></td>
+ * <td>{Error}</p></td>
+ * <td>Successful invoke of this method in a valid state does not change the
+ * state. Calling this method in an invalid state transfers the object to the
+ * <em>Error</em> state. </p></td>
+ * </tr>
+ * <tr>
+ * <td>getVideoWidth </p></td>
+ * <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
+ * PlaybackCompleted}</p></td>
+ * <td>{Error}</p></td>
+ * <td>Successful invoke of this method in a valid state does not change the
+ * state. Calling this method in an invalid state transfers the object to the
+ * <em>Error</em> state. </p></td>
+ * </tr>
+ * <tr>
+ * <td>isPlaying </p></td>
+ * <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
+ * PlaybackCompleted}</p></td>
+ * <td>{Error}</p></td>
+ * <td>Successful invoke of this method in a valid state does not change the
+ * state. Calling this method in an invalid state transfers the object to the
+ * <em>Error</em> state. </p></td>
+ * </tr>
+ * <tr>
+ * <td>pause </p></td>
+ * <td>{Started, Paused, PlaybackCompleted}</p></td>
+ * <td>{Idle, Initialized, Prepared, Stopped, Error}</p></td>
+ * <td>Successful invoke of this method in a valid state transfers the object to
+ * the <em>Paused</em> state. Calling this method in an invalid state transfers
+ * the object to the <em>Error</em> state.</p></td>
+ * </tr>
+ * <tr>
+ * <td>prepare </p></td>
+ * <td>{Initialized, Stopped} </p></td>
+ * <td>{Idle, Prepared, Started, Paused, PlaybackCompleted, Error} </p></td>
+ * <td>Successful invoke of this method in a valid state transfers the object to
+ * the <em>Prepared</em> state. Calling this method in an invalid state throws
+ * an IllegalStateException.</p></td>
+ * </tr>
+ * <tr>
+ * <td>prepareAsync </p></td>
+ * <td>{Initialized, Stopped} </p></td>
+ * <td>{Idle, Prepared, Started, Paused, PlaybackCompleted, Error} </p></td>
+ * <td>Successful invoke of this method in a valid state transfers the object to
+ * the <em>Preparing</em> state. Calling this method in an invalid state throws
+ * an IllegalStateException.</p></td>
+ * </tr>
+ * <tr>
+ * <td>release </p></td>
+ * <td>any </p></td>
+ * <td>{} </p></td>
+ * <td>After {@link #release()}, the object is no longer available. </p></td>
+ * </tr>
+ * <tr>
+ * <td>reset </p></td>
+ * <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
+ * PlaybackCompleted, Error}</p></td>
+ * <td>{}</p></td>
+ * <td>After {@link #reset()}, the object is like being just created.</p></td>
+ * </tr>
+ * <tr>
+ * <td>seekTo </p></td>
+ * <td>{Prepared, Started, Paused, PlaybackCompleted} </p></td>
+ * <td>{Idle, Initialized, Stopped, Error}</p></td>
+ * <td>Successful invoke of this method in a valid state does not change the
+ * state. Calling this method in an invalid state transfers the object to the
+ * <em>Error</em> state. </p></td>
+ * </tr>
+ * <tr>
+ * <td>setAudioSessionId </p></td>
+ * <td>{Idle} </p></td>
+ * <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted,
+ * Error} </p></td>
+ * <td>This method must be called in idle state as the audio session ID must be
+ * known before calling setDataSource. Calling it does not change the object
+ * state. </p></td>
+ * </tr>
+ * <tr>
+ * <td>setAudioStreamType </p></td>
+ * <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
+ * PlaybackCompleted}</p></td>
+ * <td>{Error}</p></td>
+ * <td>Successful invoke of this method does not change the state. In order for
+ * the target audio stream type to become effective, this method must be called
+ * before prepare() or prepareAsync().</p></td>
+ * </tr>
+ * <tr>
+ * <td>setAuxEffectSendLevel </p></td>
+ * <td>any</p></td>
+ * <td>{} </p></td>
+ * <td>Calling this method does not change the object state. </p></td>
+ * </tr>
+ * <tr>
+ * <td>setDataSource </p></td>
+ * <td>{Idle} </p></td>
+ * <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted,
+ * Error} </p></td>
+ * <td>Successful invoke of this method in a valid state transfers the object to
+ * the <em>Initialized</em> state. Calling this method in an invalid state
+ * throws an IllegalStateException.</p></td>
+ * </tr>
+ * <tr>
+ * <td>setDisplay </p></td>
+ * <td>any </p></td>
+ * <td>{} </p></td>
+ * <td>This method can be called in any state and calling it does not change the
+ * object state. </p></td>
+ * </tr>
+ * <tr>
+ * <td>setSurface </p></td>
+ * <td>any </p></td>
+ * <td>{} </p></td>
+ * <td>This method can be called in any state and calling it does not change the
+ * object state. </p></td>
+ * </tr>
+ * <tr>
+ * <td>setVideoScalingMode </p></td>
+ * <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} </p>
+ * </td>
+ * <td>{Idle, Error}</p></td>
+ * <td>Successful invoke of this method does not change the state.</p></td>
+ * </tr>
+ * <tr>
+ * <td>setLooping </p></td>
+ * <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
+ * PlaybackCompleted}</p></td>
+ * <td>{Error}</p></td>
+ * <td>Successful invoke of this method in a valid state does not change the
+ * state. Calling this method in an invalid state transfers the object to the
+ * <em>Error</em> state.</p></td>
+ * </tr>
+ * <tr>
+ * <td>isLooping </p></td>
+ * <td>any </p></td>
+ * <td>{} </p></td>
+ * <td>This method can be called in any state and calling it does not change the
+ * object state. </p></td>
+ * </tr>
+ * <tr>
+ * <td>setOnBufferingUpdateListener </p></td>
+ * <td>any </p></td>
+ * <td>{} </p></td>
+ * <td>This method can be called in any state and calling it does not change the
+ * object state. </p></td>
+ * </tr>
+ * <tr>
+ * <td>setOnCompletionListener </p></td>
+ * <td>any </p></td>
+ * <td>{} </p></td>
+ * <td>This method can be called in any state and calling it does not change the
+ * object state. </p></td>
+ * </tr>
+ * <tr>
+ * <td>setOnErrorListener </p></td>
+ * <td>any </p></td>
+ * <td>{} </p></td>
+ * <td>This method can be called in any state and calling it does not change the
+ * object state. </p></td>
+ * </tr>
+ * <tr>
+ * <td>setOnPreparedListener </p></td>
+ * <td>any </p></td>
+ * <td>{} </p></td>
+ * <td>This method can be called in any state and calling it does not change the
+ * object state. </p></td>
+ * </tr>
+ * <tr>
+ * <td>setOnSeekCompleteListener </p></td>
+ * <td>any </p></td>
+ * <td>{} </p></td>
+ * <td>This method can be called in any state and calling it does not change the
+ * object state. </p></td>
+ * </tr>
+ * <tr>
+ * <td>setScreenOnWhilePlaying</></td>
+ * <td>any </p></td>
+ * <td>{} </p></td>
+ * <td>This method can be called in any state and calling it does not change the
+ * object state. </p></td>
+ * </tr>
+ * <tr>
+ * <td>setVolume </p></td>
+ * <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
+ * PlaybackCompleted}</p></td>
+ * <td>{Error}</p></td>
+ * <td>Successful invoke of this method does not change the state.
+ * <tr>
+ * <td>setWakeMode </p></td>
+ * <td>any </p></td>
+ * <td>{} </p></td>
+ * <td>This method can be called in any state and calling it does not change the
+ * object state.</p></td>
+ * </tr>
+ * <tr>
+ * <td>start </p></td>
+ * <td>{Prepared, Started, Paused, PlaybackCompleted}</p></td>
+ * <td>{Idle, Initialized, Stopped, Error}</p></td>
+ * <td>Successful invoke of this method in a valid state transfers the object to
+ * the <em>Started</em> state. Calling this method in an invalid state transfers
+ * the object to the <em>Error</em> state.</p></td>
+ * </tr>
+ * <tr>
+ * <td>stop </p></td>
+ * <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
+ * <td>{Idle, Initialized, Error}</p></td>
+ * <td>Successful invoke of this method in a valid state transfers the object to
+ * the <em>Stopped</em> state. Calling this method in an invalid state transfers
+ * the object to the <em>Error</em> state.</p></td>
+ * </tr>
+ * <tr>
+ * <td>getTrackInfo </p></td>
+ * <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
+ * <td>{Idle, Initialized, Error}</p></td>
+ * <td>Successful invoke of this method does not change the state.</p></td>
+ * </tr>
+ * <tr>
+ * <td>addTimedTextSource </p></td>
+ * <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
+ * <td>{Idle, Initialized, Error}</p></td>
+ * <td>Successful invoke of this method does not change the state.</p></td>
+ * </tr>
+ * <tr>
+ * <td>selectTrack </p></td>
+ * <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
+ * <td>{Idle, Initialized, Error}</p></td>
+ * <td>Successful invoke of this method does not change the state.</p></td>
+ * </tr>
+ * <tr>
+ * <td>deselectTrack </p></td>
+ * <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
+ * <td>{Idle, Initialized, Error}</p></td>
+ * <td>Successful invoke of this method does not change the state.</p></td>
+ * </tr>
  * </table>
- *
  * <a name="Permissions"></a>
  * <h3>Permissions</h3>
- * <p>One may need to declare a corresponding WAKE_LOCK permission {@link
- * android.R.styleable#AndroidManifestUsesPermission &lt;uses-permission&gt;}
- * element.
- *
- * <p>This class requires the {@link android.Manifest.permission#INTERNET} permission
- * when used with network-based content.
- *
- * <a name="Callbacks"></a>
+ * <p>
+ * One may need to declare a corresponding WAKE_LOCK permission
+ * {@link android.R.styleable#AndroidManifestUsesPermission
+ * &lt;uses-permission&gt;} element.
+ * <p>
+ * This class requires the {@link android.Manifest.permission#INTERNET}
+ * permission when used with network-based content. <a name="Callbacks"></a>
  * <h3>Callbacks</h3>
- * <p>Applications may want to register for informational and error
- * events in order to be informed of some internal state update and
- * possible runtime errors during playback or streaming. Registration for
- * these events is done by properly setting the appropriate listeners (via calls
- * to
+ * <p>
+ * Applications may want to register for informational and error events in order
+ * to be informed of some internal state update and possible runtime errors
+ * during playback or streaming. Registration for these events is done by
+ * properly setting the appropriate listeners (via calls to
  * {@link #setOnPreparedListener(OnPreparedListener)}setOnPreparedListener,
- * {@link #setOnVideoSizeChangedListener(OnVideoSizeChangedListener)}setOnVideoSizeChangedListener,
- * {@link #setOnSeekCompleteListener(OnSeekCompleteListener)}setOnSeekCompleteListener,
- * {@link #setOnCompletionListener(OnCompletionListener)}setOnCompletionListener,
- * {@link #setOnBufferingUpdateListener(OnBufferingUpdateListener)}setOnBufferingUpdateListener,
- * {@link #setOnInfoListener(OnInfoListener)}setOnInfoListener,
- * {@link #setOnErrorListener(OnErrorListener)}setOnErrorListener, etc).
- * In order to receive the respective callback
+ * {@link #setOnVideoSizeChangedListener(OnVideoSizeChangedListener)}
+ * setOnVideoSizeChangedListener,
+ * {@link #setOnSeekCompleteListener(OnSeekCompleteListener)}
+ * setOnSeekCompleteListener,
+ * {@link #setOnCompletionListener(OnCompletionListener)}
+ * setOnCompletionListener,
+ * {@link #setOnBufferingUpdateListener(OnBufferingUpdateListener)}
+ * setOnBufferingUpdateListener, {@link #setOnInfoListener(OnInfoListener)}
+ * setOnInfoListener, {@link #setOnErrorListener(OnErrorListener)}
+ * setOnErrorListener, etc). In order to receive the respective callback
  * associated with these listeners, applications are required to create
- * MediaPlayer objects on a thread with its own Looper running (main UI
- * thread by default has a Looper running).
- *
+ * MediaPlayer objects on a thread with its own Looper running (main UI thread
+ * by default has a Looper running).
  */
 public class MediaPlayer implements SubtitleController.Listener
 {
     /**
-       Constant to retrieve only the new metadata since the last
-       call.
-       // FIXME: unhide.
-       // FIXME: add link to getMetadata(boolean, boolean)
-       {@hide}
+     * Constant to retrieve only the new metadata since the last call. // FIXME:
+     * unhide. // FIXME: add link to getMetadata(boolean, boolean) {@hide
+     * }
      */
     public static final boolean METADATA_UPDATE_ONLY = true;
 
     /**
-       Constant to retrieve all the metadata.
-       // FIXME: unhide.
-       // FIXME: add link to getMetadata(boolean, boolean)
-       {@hide}
+     * Constant to retrieve all the metadata. // FIXME: unhide. // FIXME: add
+     * link to getMetadata(boolean, boolean) {@hide}
      */
     public static final boolean METADATA_ALL = false;
 
     /**
-       Constant to enable the metadata filter during retrieval.
-       // FIXME: unhide.
-       // FIXME: add link to getMetadata(boolean, boolean)
-       {@hide}
+     * Constant to enable the metadata filter during retrieval. // FIXME:
+     * unhide. // FIXME: add link to getMetadata(boolean, boolean) {@hide
+     * }
      */
     public static final boolean APPLY_METADATA_FILTER = true;
 
     /**
-       Constant to disable the metadata filter during retrieval.
-       // FIXME: unhide.
-       // FIXME: add link to getMetadata(boolean, boolean)
-       {@hide}
+     * Constant to disable the metadata filter during retrieval. // FIXME:
+     * unhide. // FIXME: add link to getMetadata(boolean, boolean) {@hide
+     * }
      */
     public static final boolean BYPASS_METADATA_FILTER = false;
 
@@ -573,20 +634,27 @@
     private final static String IMEDIA_PLAYER = "android.media.IMediaPlayer";
 
     private int mNativeContext; // accessed by native methods
-    private int mNativeSurfaceTexture;  // accessed by native methods
+    private int mNativeSurfaceTexture; // accessed by native methods
     private int mListenerContext; // accessed by native methods
     private SurfaceHolder mSurfaceHolder;
     private EventHandler mEventHandler;
     private PowerManager.WakeLock mWakeLock = null;
     private boolean mScreenOnWhilePlaying;
     private boolean mStayAwake;
+    private boolean isAudio = false;
+    private Uri mContent;
+    public Context mContext;
+    public MediaExtractor mMediaExtractor;
+    
 
     /**
      * Default constructor. Consider using one of the create() methods for
      * synchronously instantiating a MediaPlayer from a Uri or resource.
-     * <p>When done with the MediaPlayer, you should call  {@link #release()},
-     * to free the resources. If not released, too many MediaPlayer instances may
-     * result in an exception.</p>
+     * <p>
+     * When done with the MediaPlayer, you should call {@link #release()}, to
+     * free the resources. If not released, too many MediaPlayer instances may
+     * result in an exception.
+     * </p>
      */
     public MediaPlayer() {
 
@@ -604,19 +672,21 @@
         mOpenSubtitleSources = new Vector<InputStream>();
         mInbandSubtitleTracks = new SubtitleTrack[0];
 
-        /* Native setup requires a weak reference to our object.
-         * It's easier to create it here than in C++.
+        /*
+         * Native setup requires a weak reference to our object. It's easier to
+         * create it here than in C++.
          */
         native_setup(new WeakReference<MediaPlayer>(this));
     }
 
     /*
-     * Update the MediaPlayer SurfaceTexture.
-     * Call after setting a new display surface.
+     * Update the MediaPlayer SurfaceTexture. Call after setting a new display
+     * surface.
      */
     private native void _setVideoSurface(Surface surface);
 
-    /* Do not change these values (starting with INVOKE_ID) without updating
+    /*
+     * Do not change these values (starting with INVOKE_ID) without updating
      * their counterparts in include/media/mediaplayer.h!
      */
     private static final int INVOKE_ID_GET_TRACK_INFO = 1;
@@ -627,15 +697,13 @@
     private static final int INVOKE_ID_SET_VIDEO_SCALE_MODE = 6;
 
     /**
-     * Create a request parcel which can be routed to the native media
-     * player using {@link #invoke(Parcel, Parcel)}. The Parcel
-     * returned has the proper InterfaceToken set. The caller should
-     * not overwrite that token, i.e it can only append data to the
-     * Parcel.
-     *
-     * @return A parcel suitable to hold a request for the native
-     * player.
-     * {@hide}
+     * Create a request parcel which can be routed to the native media player
+     * using {@link #invoke(Parcel, Parcel)}. The Parcel returned has the proper
+     * InterfaceToken set. The caller should not overwrite that token, i.e it
+     * can only append data to the Parcel.
+     * 
+     * @return A parcel suitable to hold a request for the native player.
+     *         {@hide}
      */
     public Parcel newRequest() {
         Parcel parcel = Parcel.obtain();
@@ -644,18 +712,15 @@
     }
 
     /**
-     * Invoke a generic method on the native player using opaque
-     * parcels for the request and reply. Both payloads' format is a
-     * convention between the java caller and the native player.
-     * Must be called after setDataSource to make sure a native player
-     * exists. On failure, a RuntimeException is thrown.
-     *
-     * @param request Parcel with the data for the extension. The
-     * caller must use {@link #newRequest()} to get one.
-     *
-     * @param reply Output parcel with the data returned by the
-     * native player.
-     * {@hide}
+     * Invoke a generic method on the native player using opaque parcels for the
+     * request and reply. Both payloads' format is a convention between the java
+     * caller and the native player. Must be called after setDataSource to make
+     * sure a native player exists. On failure, a RuntimeException is thrown.
+     * 
+     * @param request Parcel with the data for the extension. The caller must
+     *            use {@link #newRequest()} to get one.
+     * @param reply Output parcel with the data returned by the native player.
+     *            {@hide}
      */
     public void invoke(Parcel request, Parcel reply) {
         int retcode = native_invoke(request, reply);
@@ -666,15 +731,13 @@
     }
 
     /**
-     * Sets the {@link SurfaceHolder} to use for displaying the video
-     * portion of the media.
-     *
-     * Either a surface holder or surface must be set if a display or video sink
-     * is needed.  Not calling this method or {@link #setSurface(Surface)}
-     * when playing back a video will result in only the audio track being played.
-     * A null surface holder or surface will result in only the audio track being
-     * played.
-     *
+     * Sets the {@link SurfaceHolder} to use for displaying the video portion of
+     * the media. Either a surface holder or surface must be set if a display or
+     * video sink is needed. Not calling this method or
+     * {@link #setSurface(Surface)} when playing back a video will result in
+     * only the audio track being played. A null surface holder or surface will
+     * result in only the audio track being played.
+     * 
      * @param sh the SurfaceHolder to use for video display
      */
     public void setDisplay(SurfaceHolder sh) {
@@ -692,20 +755,19 @@
     /**
      * Sets the {@link Surface} to be used as the sink for the video portion of
      * the media. This is similar to {@link #setDisplay(SurfaceHolder)}, but
-     * does not support {@link #setScreenOnWhilePlaying(boolean)}.  Setting a
+     * does not support {@link #setScreenOnWhilePlaying(boolean)}. Setting a
      * Surface will un-set any Surface or SurfaceHolder that was previously set.
-     * A null surface will result in only the audio track being played.
-     *
-     * If the Surface sends frames to a {@link SurfaceTexture}, the timestamps
-     * returned from {@link SurfaceTexture#getTimestamp()} will have an
-     * unspecified zero point.  These timestamps cannot be directly compared
-     * between different media sources, different instances of the same media
-     * source, or multiple runs of the same program.  The timestamp is normally
-     * monotonically increasing and is unaffected by time-of-day adjustments,
-     * but it is reset when the position is set.
-     *
+     * A null surface will result in only the audio track being played. If the
+     * Surface sends frames to a {@link SurfaceTexture}, the timestamps returned
+     * from {@link SurfaceTexture#getTimestamp()} will have an unspecified zero
+     * point. These timestamps cannot be directly compared between different
+     * media sources, different instances of the same media source, or multiple
+     * runs of the same program. The timestamp is normally monotonically
+     * increasing and is unaffected by time-of-day adjustments, but it is reset
+     * when the position is set.
+     * 
      * @param surface The {@link Surface} to be used for the video portion of
-     * the media.
+     *            the media.
      */
     public void setSurface(Surface surface) {
         if (mScreenOnWhilePlaying && surface != null) {
@@ -716,43 +778,45 @@
         updateSurfaceScreenOn();
     }
 
-    /* Do not change these video scaling mode values below without updating
+    /*
+     * Do not change these video scaling mode values below without updating
      * their counterparts in system/window.h! Please do not forget to update
-     * {@link #isVideoScalingModeSupported} when new video scaling modes
-     * are added.
+     * {@link #isVideoScalingModeSupported} when new video scaling modes are
+     * added.
      */
     /**
-     * Specifies a video scaling mode. The content is stretched to the
-     * surface rendering area. When the surface has the same aspect ratio
-     * as the content, the aspect ratio of the content is maintained;
-     * otherwise, the aspect ratio of the content is not maintained when video
-     * is being rendered. Unlike {@link #VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING},
+     * Specifies a video scaling mode. The content is stretched to the surface
+     * rendering area. When the surface has the same aspect ratio as the
+     * content, the aspect ratio of the content is maintained; otherwise, the
+     * aspect ratio of the content is not maintained when video is being
+     * rendered. Unlike {@link #VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING},
      * there is no content cropping with this video scaling mode.
      */
     public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT = 1;
 
     /**
-     * Specifies a video scaling mode. The content is scaled, maintaining
-     * its aspect ratio. The whole surface area is always used. When the
-     * aspect ratio of the content is the same as the surface, no content
-     * is cropped; otherwise, content is cropped to fit the surface.
+     * Specifies a video scaling mode. The content is scaled, maintaining its
+     * aspect ratio. The whole surface area is always used. When the aspect
+     * ratio of the content is the same as the surface, no content is cropped;
+     * otherwise, content is cropped to fit the surface.
      */
     public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = 2;
+
     /**
-     * Sets video scaling mode. To make the target video scaling mode
-     * effective during playback, this method must be called after
-     * data source is set. If not called, the default video
-     * scaling mode is {@link #VIDEO_SCALING_MODE_SCALE_TO_FIT}.
-     *
-     * <p> The supported video scaling modes are:
+     * Sets video scaling mode. To make the target video scaling mode effective
+     * during playback, this method must be called after data source is set. If
+     * not called, the default video scaling mode is
+     * {@link #VIDEO_SCALING_MODE_SCALE_TO_FIT}.
+     * <p>
+     * The supported video scaling modes are:
      * <ul>
      * <li> {@link #VIDEO_SCALING_MODE_SCALE_TO_FIT}
      * <li> {@link #VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING}
      * </ul>
-     *
-     * @param mode target video scaling mode. Most be one of the supported
-     * video scaling modes; otherwise, IllegalArgumentException will be thrown.
-     *
+     * 
+     * @param mode target video scaling mode. Most be one of the supported video
+     *            scaling modes; otherwise, IllegalArgumentException will be
+     *            thrown.
      * @see MediaPlayer#VIDEO_SCALING_MODE_SCALE_TO_FIT
      * @see MediaPlayer#VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING
      */
@@ -775,27 +839,33 @@
     }
 
     /**
-     * Convenience method to create a MediaPlayer for a given Uri.
-     * On success, {@link #prepare()} will already have been called and must not be called again.
-     * <p>When done with the MediaPlayer, you should call  {@link #release()},
-     * to free the resources. If not released, too many MediaPlayer instances will
-     * result in an exception.</p>
-     *
+     * Convenience method to create a MediaPlayer for a given Uri. On success,
+     * {@link #prepare()} will already have been called and must not be called
+     * again.
+     * <p>
+     * When done with the MediaPlayer, you should call {@link #release()}, to
+     * free the resources. If not released, too many MediaPlayer instances will
+     * result in an exception.
+     * </p>
+     * 
      * @param context the Context to use
      * @param uri the Uri from which to get the datasource
      * @return a MediaPlayer object, or null if creation failed
      */
     public static MediaPlayer create(Context context, Uri uri) {
-        return create (context, uri, null);
+        return create(context, uri, null);
     }
 
     /**
-     * Convenience method to create a MediaPlayer for a given Uri.
-     * On success, {@link #prepare()} will already have been called and must not be called again.
-     * <p>When done with the MediaPlayer, you should call  {@link #release()},
-     * to free the resources. If not released, too many MediaPlayer instances will
-     * result in an exception.</p>
-     *
+     * Convenience method to create a MediaPlayer for a given Uri. On success,
+     * {@link #prepare()} will already have been called and must not be called
+     * again.
+     * <p>
+     * When done with the MediaPlayer, you should call {@link #release()}, to
+     * free the resources. If not released, too many MediaPlayer instances will
+     * result in an exception.
+     * </p>
+     * 
      * @param context the Context to use
      * @param uri the Uri from which to get the datasource
      * @param holder the SurfaceHolder to use for displaying the video
@@ -825,24 +895,29 @@
         return null;
     }
 
-    // Note no convenience method to create a MediaPlayer with SurfaceTexture sink.
+    // Note no convenience method to create a MediaPlayer with SurfaceTexture
+    // sink.
 
     /**
-     * Convenience method to create a MediaPlayer for a given resource id.
-     * On success, {@link #prepare()} will already have been called and must not be called again.
-     * <p>When done with the MediaPlayer, you should call  {@link #release()},
-     * to free the resources. If not released, too many MediaPlayer instances will
-     * result in an exception.</p>
-     *
+     * Convenience method to create a MediaPlayer for a given resource id. On
+     * success, {@link #prepare()} will already have been called and must not be
+     * called again.
+     * <p>
+     * When done with the MediaPlayer, you should call {@link #release()}, to
+     * free the resources. If not released, too many MediaPlayer instances will
+     * result in an exception.
+     * </p>
+     * 
      * @param context the Context to use
      * @param resid the raw resource id (<var>R.raw.&lt;something></var>) for
-     *              the resource to use as the datasource
+     *            the resource to use as the datasource
      * @return a MediaPlayer object, or null if creation failed
      */
     public static MediaPlayer create(Context context, int resid) {
         try {
             AssetFileDescriptor afd = context.getResources().openRawResourceFd(resid);
-            if (afd == null) return null;
+            if (afd == null)
+                return null;
 
             MediaPlayer mp = new MediaPlayer();
             mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
@@ -854,7 +929,7 @@
             // fall through
         } catch (IllegalArgumentException ex) {
             Log.d(TAG, "create failed:", ex);
-           // fall through
+            // fall through
         } catch (SecurityException ex) {
             Log.d(TAG, "create failed:", ex);
             // fall through
@@ -864,38 +939,58 @@
 
     /**
      * Sets the data source as a content Uri.
-     *
+     * 
      * @param context the Context to use when resolving the Uri
      * @param uri the Content URI of the data you want to play
      * @throws IllegalStateException if it is called in an invalid state
      */
     public void setDataSource(Context context, Uri uri)
-        throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
+            throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
+        Log.d(TAG, "111 - hc");
         setDataSource(context, uri, null);
     }
 
+    public void setDataSource(Context context, Uri uri, boolean toRemote)
+            throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
+        Log.d(TAG, "888 - hc");
+        
+        setDataSource(context, uri, null);
+    }
+    
     /**
      * Sets the data source as a content Uri.
-     *
+     * 
      * @param context the Context to use when resolving the Uri
      * @param uri the Content URI of the data you want to play
-     * @param headers the headers to be sent together with the request for the data
+     * @param headers the headers to be sent together with the request for the
+     *            data
      * @throws IllegalStateException if it is called in an invalid state
      */
     public void setDataSource(Context context, Uri uri, Map<String, String> headers)
-        throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
+            throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
+        Log.d(TAG, "222 - hc");
         disableProxyListener();
 
         String scheme = uri.getScheme();
-        if(scheme == null || scheme.equals("file")) {
+        if (scheme == null || scheme.equals("file")) {
             setDataSource(uri.getPath());
             return;
         }
-
+        
         AssetFileDescriptor fd = null;
         try {
             ContentResolver resolver = context.getContentResolver();
             fd = resolver.openAssetFileDescriptor(uri, "r");
+            Log.d(TAG, "hc : " + uri.toString());
+            mContext = context;
+            mContent = uri;
+            if (uri.toString().contains("audio")) {
+                isAudio = true;
+                Log.d(TAG, "hc : audio true (should be true), " + isAudio);
+            } else {
+                isAudio = false;
+                Log.d(TAG, "hc : video true (should be false), " + isAudio);
+            }
             if (fd == null) {
                 return;
             }
@@ -904,6 +999,7 @@
             // a full file.
             if (fd.getDeclaredLength() < 0) {
                 setDataSource(fd.getFileDescriptor());
+
             } else {
                 setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getDeclaredLength());
             }
@@ -911,9 +1007,9 @@
         } catch (SecurityException ex) {
         } catch (IOException ex) {
         } finally {
-            if (fd != null) {
-                fd.close();
-            }
+//            if (fd != null) {
+//                fd.close();
+//            }
         }
 
         Log.d(TAG, "Couldn't open file on client side, trying server side");
@@ -928,33 +1024,139 @@
 
     /**
      * Sets the data source (file-path or http/rtsp URL) to use.
-     *
-     * @param path the path of the file, or the http/rtsp URL of the stream you want to play
+     * 
+     * @param path the path of the file, or the http/rtsp URL of the stream you
+     *            want to play
      * @throws IllegalStateException if it is called in an invalid state
-     *
-     * <p>When <code>path</code> refers to a local file, the file may actually be opened by a
-     * process other than the calling application.  This implies that the pathname
-     * should be an absolute path (as any other process runs with unspecified current working
-     * directory), and that the pathname should reference a world-readable file.
-     * As an alternative, the application could first open the file for reading,
-     * and then use the file descriptor form {@link #setDataSource(FileDescriptor)}.
-     */
-    public void setDataSource(String path)
-            throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
+     *             <p>
+     *             When <code>path</code> refers to a local file, the file may
+     *             actually be opened by a process other than the calling
+     *             application. This implies that the pathname should be an
+     *             absolute path (as any other process runs with unspecified
+     *             current working directory), and that the pathname should
+     *             reference a world-readable file. As an alternative, the
+     *             application could first open the file for reading, and then
+     *             use the file descriptor form
+     *             {@link #setDataSource(FileDescriptor)}.
+     */
+
+    public void setDataSource(String path) throws IOException,
+            IllegalArgumentException, SecurityException, IllegalStateException {
+        Log.d(TAG, "333 - hc");
+        /*if (path.substring(path.length() - 3, path.length()).equalsIgnoreCase("mp3")) {
+            // extractor setting
+            MediaExtractor extractor;
+            extractor = new MediaExtractor();
+            try {
+                extractor.setDataSource(path);
+            } catch (IOException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+
+            // format setting
+            MediaFormat format = null;
+            String mime = "";
+            int sampleRate = 0, channels = 0, bitrate = 0;
+            long duration = 0;
+            byte[] buffer = new byte[627];
+            try {
+                format = extractor.getTrackFormat(0);
+                mime = format.getString(MediaFormat.KEY_MIME);
+                sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
+                channels = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
+                // if duration is 0, we are probably playing a live stream
+                duration = format.getLong(MediaFormat.KEY_DURATION);
+                bitrate = format.getInteger(MediaFormat.KEY_BIT_RATE);
+            } catch (Exception e) {
+                Log.e(TAG, "Reading format parameters exception:" + e.getMessage());
+                // don't exit, tolerate this error, we'll fail later if this is
+                // critical
+            }
+            extractor.selectTrack(0);
+
+            // check the format variables
+            Log.d(TAG, "Track info: mime:" + mime + " sampleRate:" + sampleRate
+                    + " channels:" + channels + " bitrate:" + bitrate
+                    + " duration:" + duration);
+            // mService = IRemoteRequestHandler.Stub.asInterface(ServiceManager
+            // .getService(Context.REMOTE_SERVICE));
+            RemoteRequestManager mService = new RemoteRequestManager();
+            ArrayList<Object> parameters = new ArrayList<Object>();
+            parameters.add(0, mime);
+            parameters.add(1, sampleRate);
+            parameters.add(2, channels);
+            parameters.add(3, duration);
+            RemoteRequest mRequest = new RemoteRequest("RemoteMusic", "SettingCodec", parameters);
+
+            mService.sendRequest(mRequest);
+            parameters.clear();
+
+            // feeding
+            ByteBuffer tmp_byteBuffer = null;
+            int sampleSize = 0;
+            boolean flag = true;
+            // try {
+            while (flag) {
+                tmp_byteBuffer = ByteBuffer.wrap(buffer);
+                sampleSize = extractor.readSampleData(tmp_byteBuffer, 0);
+                byte[] to_send = new byte[sampleSize];
+                for (int i = 0; i < to_send.length; i++) {
+                    to_send[i] = tmp_byteBuffer.get(i);
+                }
+                long presentationTime = extractor.getSampleTime();
+
+                mService.sendMusicData(sampleSize, to_send, presentationTime);
+                if (sampleSize <= 0) {
+                    // this is where music file is ended
+                } else {
+                    extractor.advance();
+                }
+                // Log.d(TAG, "File: i sent" + Arrays.toString(to_send));
+                // Thread.sleep(1000);
+            }
+            // } catch (RemoteException e) {
+            // // TODO Auto-generated catch block
+            // e.printStackTrace();
+            // }
+            // Stopping music
+            mRequest = new RemoteRequest("StopMusic", null, null);
+            // try {
+            mService.sendRequest(mRequest);
+            // } catch (RemoteException e) {
+            // // TODO Auto-generated catch block
+            // e.printStackTrace();
+            // } finally{
+            parameters.clear();
+            // }
+
+        }
+        // video
+        else {
+//            RemoteRequestManager mService = new RemoteRequestManager();
+//            RemoteRequest mRequest = new RemoteRequest("video_streaming", "get surface", null);
+//            mService.sendRequest(mRequest);
+////            mVideoFeeder video = new mVideoFeeder(path, 8888);
+////            video.start();
+        }*/
+
         setDataSource(path, null, null);
     }
 
     /**
      * Sets the data source (file-path or http/rtsp URL) to use.
-     *
-     * @param path the path of the file, or the http/rtsp URL of the stream you want to play
-     * @param headers the headers associated with the http request for the stream you want to play
+     * 
+     * @param path the path of the file, or the http/rtsp URL of the stream you
+     *            want to play
+     * @param headers the headers associated with the http request for the
+     *            stream you want to play
      * @throws IllegalStateException if it is called in an invalid state
      * @hide pending API council
      */
     public void setDataSource(String path, Map<String, String> headers)
             throws IOException, IllegalArgumentException, SecurityException, IllegalStateException
     {
+        Log.d(TAG, "444 - hc");
         String[] keys = null;
         String[] values = null;
 
@@ -963,7 +1165,7 @@
             values = new String[headers.size()];
 
             int i = 0;
-            for (Map.Entry<String, String> entry: headers.entrySet()) {
+            for (Map.Entry<String, String> entry : headers.entrySet()) {
                 keys[i] = entry.getKey();
                 values[i] = entry.getValue();
                 ++i;
@@ -974,6 +1176,7 @@
 
     private void setDataSource(String path, String[] keys, String[] values)
             throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
+        Log.d(TAG, "555 - hc");
         disableProxyListener();
 
         final Uri uri = Uri.parse(path);
@@ -982,6 +1185,7 @@
         }
 
         final File file = new File(path);
+
         if (file.exists()) {
             FileInputStream is = new FileInputStream(file);
             FileDescriptor fd = is.getFD();
@@ -993,120 +1197,1315 @@
     }
 
     private native void _setDataSource(
-        String path, String[] keys, String[] values)
-        throws IOException, IllegalArgumentException, SecurityException, IllegalStateException;
+            String path, String[] keys, String[] values)
+            throws IOException, IllegalArgumentException, SecurityException, IllegalStateException;
 
     /**
-     * Sets the data source (FileDescriptor) to use. It is the caller's responsibility
-     * to close the file descriptor. It is safe to do so as soon as this call returns.
-     *
+     * Sets the data source (FileDescriptor) to use. It is the caller's
+     * responsibility to close the file descriptor. It is safe to do so as soon
+     * as this call returns.
+     * 
      * @param fd the FileDescriptor for the file you want to play
      * @throws IllegalStateException if it is called in an invalid state
      */
     public void setDataSource(FileDescriptor fd)
             throws IOException, IllegalArgumentException, IllegalStateException {
+        Log.d(TAG, "666 - hc");
+
         // intentionally less than LONG_MAX
         setDataSource(fd, 0, 0x7ffffffffffffffL);
     }
 
     /**
-     * Sets the data source (FileDescriptor) to use.  The FileDescriptor must be
-     * seekable (N.B. a LocalSocket is not seekable). It is the caller's responsibility
-     * to close the file descriptor. It is safe to do so as soon as this call returns.
-     *
+     * Sets the data source (FileDescriptor) to use. The FileDescriptor must be
+     * seekable (N.B. a LocalSocket is not seekable). It is the caller's
+     * responsibility to close the file descriptor. It is safe to do so as soon
+     * as this call returns.
+     * 
      * @param fd the FileDescriptor for the file you want to play
-     * @param offset the offset into the file where the data to be played starts, in bytes
+     * @param offset the offset into the file where the data to be played
+     *            starts, in bytes
      * @param length the length in bytes of the data to be played
      * @throws IllegalStateException if it is called in an invalid state
      */
     public void setDataSource(FileDescriptor fd, long offset, long length)
             throws IOException, IllegalArgumentException, IllegalStateException {
+
+        Log.d(TAG, "Video set data source (start)");
+        FileDescriptor fd1 = fd;
+        Log.d(TAG, "777 - hc");
+//        Log.d(TAG, "777 - hc, " + fd1.valid() + " and fd? : " + fd2.valid() + "  " + fd1.equals(fd2));
+        Log.d("VideoLatency", "Video loading");
+        Log.d("AudioLatency", "Audio loading");
+
+        IRemoteService mService = IRemoteService.Stub
+                .asInterface(ServiceManager.getService(Context.REMOTE_SERVICE));
+//        try {
+            
+            if (isAudio) {
+                new mAudioGo().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, mContent);
+            }
+            
+            // video
+            else if(!isAudio){
+                Log.d(TAG, "video in, getting remote system service");
+
+                Log.d(TAG, "video and audio thread before start");
+                //init video and request surface provider
+                new mLets().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "");
+                int vport = 31200;
+                
+                ///////////
+                
+                
+                ArrayList<AppendingObjectOutputStream> vList = new ArrayList<AppendingObjectOutputStream>();
+                ArrayList<AppendingObjectOutputStream> aList = new ArrayList<AppendingObjectOutputStream>();
+                Log.d(TAG, "done with setting server");
+                
+                try {
+//                    List<String> serverIPs = mService.getServerIPs();
+                    int numberOfPlayers = mService.getVideoPlayers();
+                    for(int i = 0; i < numberOfPlayers;i++){
+                        
+                        try {
+                            vList.add(new mVideoServerAsync().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, vport).get());
+                            
+                            aList.add(new mAudioServerAsync().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ++vport).get());
+                            
+                            vport++;
+//                            vList.add(getOutputStream(vport));
+//                            
+                        } catch (InterruptedException e) {
+                            // TODO Auto-generated catch block
+                            e.printStackTrace();
+                        } catch (ExecutionException e) {
+                            // TODO Auto-generated catch block
+                            e.printStackTrace();
+                        }
+//                        vport = vport+2;
+//                        new mVideoFeederAsync().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, mContent, vport);
+//                        new mAudioFeederAsync().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, mContent, ++vport);
+//                        vport++;
+                        
+                    }
+                    Log.d(TAG, "vList: " + vList.toString());
+                    Log.d(TAG, "aList: " + aList.toString());
+                new mVideoGoAsync().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, mContent, vList);
+                new mAudioGoAsync().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, mContent, aList);
+//                new mVideoGoAsync().execute(mContent);
+                    
+                } catch (RemoteException e1) {
+                    // TODO Auto-generated catch block
+                    e1.printStackTrace();
+                }
+                
+                Log.d(TAG, "video and audio thread after start");
+
+                Log.d(TAG, "media player exiting");
+            }
+            
+//        } 
+//        catch (RemoteException e) {
+//            // TODO Auto-generated catch block
+//            e.printStackTrace();
+//        }
+
+        Log.d(TAG, "original setdatasource");
+        // original
         disableProxyListener();
         _setDataSource(fd, offset, length);
+        Log.d(TAG, "original setdatasource done");
     }
 
+    
     private native void _setDataSource(FileDescriptor fd, long offset, long length)
             throws IOException, IllegalArgumentException, IllegalStateException;
 
+
+    public void closing_all_serversockets(){
+        ServerSocket ss;
+        try {
+            ss = new ServerSocket();
+            ss.setReuseAddress(true);
+            for(int i=0;i<22320;i++){
+                ss.bind(new InetSocketAddress(i));
+                ss.close();
+            }
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+
+    }
+    
+    private class mAudioGo extends AsyncTask<Object, Void, Void>{
+        
+        MediaExtractor mExtractor;
+        IRemoteService mService = IRemoteService.Stub
+                .asInterface(ServiceManager.getService(Context.REMOTE_SERVICE));
+        @Override
+        protected Void doInBackground(Object... params) {
+            // TODO Auto-generated method stub
+            try {
+                
+                Uri uri = (Uri) params[0];
+                AssetFileDescriptor fd = null;
+                try {
+                    ContentResolver resolver = mContext.getContentResolver();
+                    fd = resolver.openAssetFileDescriptor(uri, "r");
+                } catch (FileNotFoundException e1) {
+                    // TODO Auto-generated catch block
+                    e1.printStackTrace();
+                }
+
+                try {
+                    mExtractor = new MediaExtractor();
+                    mExtractor.setDataSource(fd.getFileDescriptor());
+                } catch (IOException e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+                
+                MediaFormat format = new MediaFormat();
+                String mime = "";
+                int sampleRate = 0, channels = 0;
+                long duration = 0L;
+
+                try {
+                    format = mExtractor.getTrackFormat(0);
+                    mime = format.getString(MediaFormat.KEY_MIME);
+                    sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
+                    channels = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
+                    // if duration is 0, we are probably playing a live stream
+                    duration = format.getLong(MediaFormat.KEY_DURATION);
+                } catch (Exception e) {
+                    Log.e(TAG, "Reading format parameters exception:" + e.getMessage());
+                }
+                mExtractor.selectTrack(0);
+
+                // check the format variables
+                Log.d(TAG, "Track info: mime:" + mime + " sampleRate:" + sampleRate
+                        + " channels:" + channels + " duration:" + duration);
+                // mService =
+                // IRemoteRequestHandler.Stub.asInterface(ServiceManager
+                // .getService(Context.REMOTE_SERVICE));
+
+                ArrayList<Object> parameters = new ArrayList<Object>();
+                parameters.add(0, mime);
+                parameters.add(1, sampleRate);
+                parameters.add(2, channels);
+                parameters.add(3, duration);
+                
+                RemoteRequest mRequest = new RemoteRequest("RemoteMusic",
+                        "SettingCodec", parameters);
+                // try {
+//                mService.sendRequest(mRequest);
+                
+                mService.sendAllrequest(mRequest);
+                // } catch (RemoteException e) {
+                // TODO Auto-generated catch block
+                // e.printStackTrace();
+                // } finally {
+//                parameters.clear();
+                // }
+
+                // feeding
+                ByteBuffer tmp_byteBuffer = null;
+                int sampleSize = 0;
+                boolean flag = true;
+                
+                int forTest = 0;
+                
+                tmp_byteBuffer = ByteBuffer.allocate(1500);
+                // try {
+                while (flag) {
+                    tmp_byteBuffer.clear();
+                    sampleSize = mExtractor.readSampleData(tmp_byteBuffer, 0);
+                    byte[] to_send = new byte[sampleSize];
+                    for (int i = 0; i < to_send.length; i++) {
+                        to_send[i] = tmp_byteBuffer.get(i);
+                    }
+                    long presentationTime = mExtractor.getSampleTime();
+
+                    
+                    
+                    mService.sendAllMusic(sampleSize, to_send, presentationTime);
+//                    mService.sendMusicData(sampleSize, to_send, presentationTime);
+                    if (sampleSize <= 0) {
+                        // this is where music file is ended
+                    } else {
+                        mExtractor.advance();
+                        }
+                    // Log.d(TAG, "File: i sent" + Arrays.toString(to_send));
+                    // Thread.sleep(1000);
+                    forTest++;
+                    if(forTest == 5){
+                        flag = false;
+                    }
+                }
+                // } catch (RemoteException e) {
+                // TODO Auto-generated catch block
+                // e.printStackTrace();
+                // }
+                // Stopping music
+                mRequest = new RemoteRequest("StopMusic", null, null);
+                // try {
+                mService.sendRequest(mRequest);
+                // } catch (RemoteException e) {
+                // TODO Auto-generated catch block
+                // e.printStackTrace();
+                // } finally {
+                parameters.clear();
+                // }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            
+            return null;
+        }
+        
+    }
+    
+    private class mLets extends AsyncTask<Object, Void, Void>{
+
+        IRemoteService mService = IRemoteService.Stub
+                .asInterface(ServiceManager.getService(Context.REMOTE_SERVICE));
+        @Override
+        protected Void doInBackground(Object... params) {
+            // TODO Auto-generated method stub
+            int vport = 31200;
+//            List<String> serverIPs = null;
+//            try {
+//                serverIPs = mService.getServerIPs();
+//            } catch (RemoteException e1) {
+//                // TODO Auto-generated catch block
+//                e1.printStackTrace();
+//            }
+            try{
+                mService.sendVideoSignal(vport);
+            } catch(Exception e){
+                e.printStackTrace();
+            }
+            
+            
+//            for(int i = 0; i < mService.get.size();i++){
+//                ArrayList<Object> vInfo = new ArrayList<Object>();
+//                vInfo.clear();
+//                vInfo.add(0, serverIPs.get(i));
+//                vInfo.add(1, vport);
+//                
+//                RemoteRequest mRequest = new RemoteRequest("video_streaming", "get_surface", vInfo);
+//                Log.d(TAG, "made request to , " + serverIPs.get(i) + " with port :" + vport);
+//                try {
+//                    mService.sendRequest(mRequest);
+//                } catch (RemoteException e) {
+//                    // TODO Auto-generated catch block
+//                    e.printStackTrace();
+////                    continue;
+//                }
+//                vport = vport + 2;
+//            }
+            return null;
+        }
+        
+    }
+    
+    private class mVideoServerAsync extends AsyncTask<Object, Void, AppendingObjectOutputStream>{
+
+        private MediaExtractor mExtractor;
+        AppendingObjectOutputStream output;
+        String path_url = "";
+
+        @Override
+        protected AppendingObjectOutputStream doInBackground(Object... params) {
+            // TODO Auto-generated method stub
+
+            int port = (Integer) params[0];
+
+            ServerSocket serverSocket = null;
+            try {
+                serverSocket = new ServerSocket();
+                serverSocket.setReuseAddress(true);
+                serverSocket.bind(new InetSocketAddress(port));
+//                mExtractor = new MediaExtractor();
+//                mExtractor.setDataSource(fd.getFileDescriptor());
+            } catch (IOException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+
+            try {
+                Log.d(TAG, "Video: the server is ready to feed!! " + port);
+                Socket socket = serverSocket.accept();
+                Log.d(TAG, "Video: the client of streaming video is in!! " + port);
+                // Socket s = new Socket(InetAddress.getLocalHost(), vport);
+                OutputStream os = socket.getOutputStream();
+                ObjectOutputStream toos = new ObjectOutputStream(os);
+                output = new AppendingObjectOutputStream(os);
+            } catch (IOException e){
+                e.printStackTrace();
+            }
+
+            return output;
+        }
+    }
+    
+
+    private class mVideoGoAsync extends AsyncTask<Object, Void, Void>{
+
+        private MediaExtractor mExtractor;
+        AppendingObjectOutputStream output;
+        int port = 22300;
+        String path_url = "";
+
+        @Override
+        protected Void doInBackground(Object... params) {
+            // TODO Auto-generated method stub
+
+            Uri uri = (Uri) params[0];
+            AssetFileDescriptor fd = null;
+            try {
+                ContentResolver resolver = mContext.getContentResolver();
+                fd = resolver.openAssetFileDescriptor(uri, "r");
+            } catch (FileNotFoundException e1) {
+                // TODO Auto-generated catch block
+                e1.printStackTrace();
+            }
+
+            try {
+                mExtractor = new MediaExtractor();
+                mExtractor.setDataSource(fd.getFileDescriptor());
+            } catch (IOException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+
+            try{
+                // Media format
+                ArrayList<AppendingObjectOutputStream> outputList = (ArrayList<AppendingObjectOutputStream>) params[1];
+                for (int i = 0; i < mExtractor.getTrackCount(); i++) {
+                    MediaFormat format = mExtractor.getTrackFormat(i);
+                    String mime = format.getString(MediaFormat.KEY_MIME);
+                    int width = 0, height = 0;
+                    if (mime.startsWith("video/")) {
+                        mExtractor.selectTrack(i);
+                        try {
+                            width = format.getInteger(MediaFormat.KEY_WIDTH);
+                            height = format.getInteger(MediaFormat.KEY_HEIGHT);
+                            // if duration is 0, we are probably playing a live stream
+
+                            Log.d(TAG, "Track info: mime:" + mime
+                                    + " sampleRate:" + width + " channels:"
+                                    + height);
+                        } catch (Exception e) {
+                            Log.e(TAG, "Reading format parameters exception:"
+                                    + e.getMessage());
+                            // don't exit, tolerate this error, we'll fail later if this is critical
+                        }
+                        
+                        for(int j=0;j<outputList.size();j++){
+                            outputList.get(j).writeUTF("connect");
+//                            output.writeUTF("connect");
+                            outputList.get(j).flush();
+                        }
+                        
+                        Log.d(TAG, "Async go: output test is done");
+                        
+                        // getting csd-0
+                        ByteBuffer header_sps = format.getByteBuffer("csd-0");
+                        byte[] b_h_sps = new byte[header_sps.capacity()];
+                        header_sps.get(b_h_sps);
+                        // getting csd-1
+                        ByteBuffer header_pps = format.getByteBuffer("csd-1");
+                        byte[] b_h_pps = new byte[header_pps.capacity()];
+                        header_pps.get(b_h_pps);
+
+                        vData vdata = new vData();
+                        vdata.setMediaFormat(mime, width, height, b_h_sps, b_h_pps);
+                        for(int j=0;j<outputList.size();j++){
+                            outputList.get(j).writeObject(vdata);
+                            outputList.get(j).flush();
+                        }
+                        
+                        Log.d(TAG, "client: done sending format");
+
+                        break;
+                    }
+                }
+
+                // feeding start
+                boolean isEOS = true;
+
+                ByteBuffer byteBuffer = ByteBuffer.allocate(300000);
+
+                while (isEOS) {
+                    int sampleSize = 0;
+                    try {
+                        sampleSize = mExtractor.readSampleData(byteBuffer, 0);
+                        // Log.d(TAG, j + "  " + byteBuffer.toString());
+                        // byteBuffer.get(to_send);
+                    } catch (IllegalArgumentException e) {
+                        e.printStackTrace();
+                    }
+                    if (sampleSize < 0) {
+                        isEOS = false;
+                        break;
+                    }
+                    byte[] to_send = new byte[sampleSize];
+
+                    for (int i = 0; i < sampleSize; i++) {
+                        to_send[i] = byteBuffer.get(i);
+                    }
+
+                    // Log.d(TAG, to_send.length + ", " + byteBuffer.limit());
+                    // Log.d(TAG, "The sample size is " + String.valueOf(sampleSize));
+                    long presentationTime = mExtractor.getSampleTime();
+
+                    vData vdata = new vData(sampleSize, to_send, presentationTime);
+
+                    for(int j=0;j<outputList.size();j++){
+                        try{
+                            outputList.get(j).writeObject(vdata);
+                            outputList.get(j).flush();
+                        } catch (Exception e){
+                            Log.d("VideoStreaming", "Exception when sending");
+                        }
+                    }
+//                    Log.d(TAG, "sent this much:  " + sampleSize);
+//                    output.writeObject(vdata);
+
+                    mExtractor.advance();
+                }
+
+                mExtractor.release();
+                //                socket.close();
+                //                serverSocket.close();
+            } catch (IOException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+
+            return null;
+        }
+    }
+    
+    
+    private class mAudioServerAsync extends AsyncTask<Object, Void, AppendingObjectOutputStream>{
+
+        MediaExtractor mExtractor;
+        private AppendingObjectOutputStream output;
+        String path_url = null;
+        
+        @Override
+        protected AppendingObjectOutputStream doInBackground(Object... params) {
+
+            int port = (Integer) params[0];
+
+            ServerSocket serverSocket = null;
+
+            try {
+                serverSocket = new ServerSocket();
+                serverSocket.setReuseAddress(true);
+                serverSocket.bind(new InetSocketAddress(port));
+            } catch (IOException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+
+            try {
+                Log.d(TAG, "Audio: the server is ready to feed!! "+port);
+                Socket socket = serverSocket.accept();
+                Log.d(TAG, "Audio: the client of streaming video is in!! "+port);
+                // Socket s = new Socket(InetAddress.getLocalHost(), vport);
+                OutputStream os = socket.getOutputStream();
+                ObjectOutputStream toos = new ObjectOutputStream(os);
+                output = new AppendingObjectOutputStream(os);
+            } catch (IOException e){
+                e.printStackTrace();
+            }
+
+            return output;
+            
+        }
+    }
+    
+    private class mAudioGoAsync extends AsyncTask<Object, Void, Void>{
+
+        private MediaExtractor mExtractor;
+        AppendingObjectOutputStream output;
+        int port = 22300;
+        String path_url = "";
+
+        @Override
+        protected Void doInBackground(Object... params) {
+            // TODO Auto-generated method stub
+
+            Uri uri = (Uri) params[0];
+            AssetFileDescriptor fd = null;
+            try {
+                ContentResolver resolver = mContext.getContentResolver();
+                fd = resolver.openAssetFileDescriptor(uri, "r");
+            } catch (FileNotFoundException e1) {
+                // TODO Auto-generated catch block
+                e1.printStackTrace();
+            }
+
+            try {
+                mExtractor = new MediaExtractor();
+                mExtractor.setDataSource(fd.getFileDescriptor());
+            } catch (IOException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+
+            int sampleRate = 0, channels = 0, bitrate = 0;
+            long duration = 0;
+            
+            try{
+                // Media format
+                ArrayList<AppendingObjectOutputStream> outputList = (ArrayList<AppendingObjectOutputStream>) params[1];
+                for (int i = 0; i < mExtractor.getTrackCount(); i++) {
+                    MediaFormat format = mExtractor.getTrackFormat(i);
+                    String mime = format.getString(MediaFormat.KEY_MIME);
+                    if (mime.startsWith("audio/")) {
+                        mExtractor.selectTrack(i);
+                        try {
+                            mime = format.getString(MediaFormat.KEY_MIME);
+                            sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
+                            channels = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
+                            // if duration is 0, we are probably playing a live stream
+                            duration = format.getLong(MediaFormat.KEY_DURATION);
+                            // getting csd-0
+                            ByteBuffer header_sps = format.getByteBuffer("csd-0");
+                            byte[] b_h_sps = new byte[header_sps.capacity()];
+                            header_sps.get(b_h_sps);
+                            
+                            for(int j=0;j<outputList.size();j++){
+                                outputList.get(j).writeUTF("connect");
+                                outputList.get(j).flush();
+                            }
+                            
+                            SdPackage s = new SdPackage(mime, bitrate, channels,
+                                    sampleRate, duration, b_h_sps);
+                            for(int j=0;j<outputList.size();j++){
+                                outputList.get(j).writeObject(s);
+                                outputList.get(j).flush();
+                            }
+                            
+                        } catch (Exception e) {
+                            Log.e(TAG, "Reading format parameters exception:"
+                                    + e.getMessage());
+                            // don't exit, tolerate this error, we'll fail later if this is critical
+                        }
+                        
+                        Log.d(TAG, "Audio Async go: output test is done");
+                                                
+                        Log.d(TAG, "client: done sending format");
+
+                        break;
+                    }
+                }
+
+                // feeding start
+                boolean isEOS = true;
+
+                ByteBuffer byteBuffer = ByteBuffer.allocate(2000);
+
+                while (isEOS) {
+                    int sampleSize = 0;
+                    try {
+                        sampleSize = mExtractor.readSampleData(byteBuffer, 0);
+                    } catch (IllegalArgumentException e) {
+                        e.printStackTrace();
+                    }
+                    if (sampleSize < 0) {
+                        isEOS = false;
+                        break;
+                    }
+                    byte[] to_send = new byte[sampleSize];
+
+                    for (int i = 0; i < sampleSize; i++) {
+                        to_send[i] = byteBuffer.get(i);
+                    }
+
+                    // Log.d(TAG, to_send.length + ", " + byteBuffer.limit());
+                    // Log.d(TAG, "The sample size is " + String.valueOf(sampleSize));
+                    long presentationTime = mExtractor.getSampleTime();
+
+                    SdPackage s = new SdPackage(sampleSize, to_send, presentationTime);
+                    
+                    for(int j=0;j<outputList.size();j++){
+                        outputList.get(j).writeObject(s);
+                        outputList.get(j).flush();
+                    }
+//                    Log.d(TAG, "sent this much:  " + sampleSize);
+//                    output.writeObject(vdata);
+
+                    mExtractor.advance();
+                }
+
+                mExtractor.release();
+            } catch (IOException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+
+            return null;
+        }
+    }
+    
+    
+    
+    private class mVideoFeederAsync extends AsyncTask<Object, Void, AppendingObjectOutputStream>{
+
+        private MediaExtractor mExtractor;
+        AppendingObjectOutputStream output;
+        int port = 22300;
+        String path_url = "";
+
+        @Override
+        protected AppendingObjectOutputStream doInBackground(Object... params) {
+            // TODO Auto-generated method stub
+            try{
+                Uri uri = (Uri) params[0];
+                AssetFileDescriptor fd = null;
+                try {
+                    ContentResolver resolver = mContext.getContentResolver();
+                    fd = resolver.openAssetFileDescriptor(uri, "r");
+                } catch (FileNotFoundException e1) {
+                    // TODO Auto-generated catch block
+                    e1.printStackTrace();
+                }
+
+                //            FileDescriptor fd = (FileDescriptor) params[0];
+                this.port = (Integer) params[1];
+
+                ServerSocket serverSocket = null;
+                try {
+                    serverSocket = new ServerSocket();
+                    serverSocket.setReuseAddress(true);
+                    serverSocket.bind(new InetSocketAddress(port));
+                    mExtractor = new MediaExtractor();
+                    mExtractor.setDataSource(fd.getFileDescriptor());
+                } catch (IOException e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+
+                try {
+                    Log.d(TAG, "Video: the server is ready to feed!!");
+                    Socket socket = serverSocket.accept();
+                    socket.setTcpNoDelay(true);
+                    Log.d(TAG, "Video: the client of streaming video is in!!");
+                    // Socket s = new Socket(InetAddress.getLocalHost(), vport);
+                    OutputStream os = socket.getOutputStream();
+                    ObjectOutputStream toos = new ObjectOutputStream(os);
+                    output = new AppendingObjectOutputStream(os);
+                } catch (IOException e){
+                    e.printStackTrace();
+                }
+
+                // Media format
+                for (int i = 0; i < mExtractor.getTrackCount(); i++) {
+                    MediaFormat format = mExtractor.getTrackFormat(i);
+                    String mime = format.getString(MediaFormat.KEY_MIME);
+                    int width = 0, height = 0;
+                    if (mime.startsWith("video/")) {
+                        mExtractor.selectTrack(i);
+                        try {
+                            width = format.getInteger(MediaFormat.KEY_WIDTH);
+                            height = format.getInteger(MediaFormat.KEY_HEIGHT);
+                            // if duration is 0, we are probably playing a live
+                            // stream
+
+                            Log.d(TAG, "Track info: mime:" + mime
+                                    + " sampleRate:" + width + " channels:"
+                                    + height);
+                        } catch (Exception e) {
+                            Log.e(TAG, "Reading format parameters exception:"
+                                    + e.getMessage());
+                            // don't exit, tolerate this error, we'll fail later
+                            // if this is critical
+                        }
+
+
+                        output.writeUTF("connect");
+                        output.flush();
+
+
+                        Log.d(TAG, "client: connect? ");
+
+                        // getting csd-0
+                        ByteBuffer header_sps = format.getByteBuffer("csd-0");
+                        byte[] b_h_sps = new byte[header_sps.capacity()];
+                        header_sps.get(b_h_sps);
+                        // getting csd-1
+                        ByteBuffer header_pps = format.getByteBuffer("csd-1");
+                        byte[] b_h_pps = new byte[header_pps.capacity()];
+                        header_pps.get(b_h_pps);
+
+                        vData vdata = new vData();
+                        vdata.setMediaFormat(mime, width, height, b_h_sps,
+                                b_h_pps);
+
+                        output.writeObject(vdata);
+                        output.flush();
+
+
+                        Log.d(TAG, "client: done sending format");
+
+                        break;
+                    }
+                }
+
+                // feeding start
+                boolean isEOS = true;
+
+                ByteBuffer byteBuffer = ByteBuffer.allocate(250000);
+
+                while (isEOS) {
+                    int sampleSize = 0;
+                    try {
+                        sampleSize = mExtractor.readSampleData(byteBuffer, 0);
+                        // Log.d(TAG, j + "  " + byteBuffer.toString());
+                        // byteBuffer.get(to_send);
+                    } catch (IllegalArgumentException e) {
+                        e.printStackTrace();
+                    }
+                    if (sampleSize < 0) {
+                        isEOS = false;
+                        break;
+                    }
+                    byte[] to_send = new byte[sampleSize];
+
+                    for (int i = 0; i < sampleSize; i++) {
+                        to_send[i] = byteBuffer.get(i);
+                    }
+
+                    // Log.d(TAG, to_send.length + ", " + byteBuffer.limit());
+                    // Log.d(TAG,
+                    // "The sample size is " + String.valueOf(sampleSize));
+                    long presentationTime = mExtractor.getSampleTime();
+
+                    vData vdata = new vData(sampleSize, to_send,
+                            presentationTime);
+
+                    output.writeObject(vdata);
+                    output.flush();
+
+                                      Log.d(TAG, "sampleSize at giving " + sampleSize + "");
+                    // if (sampleSize < 0) {
+                    // break;
+                    // } else {
+                    mExtractor.advance();
+                    // }
+                }
+
+
+
+                try {
+                    mExtractor.release();
+                    //              socket.close();
+                    serverSocket.close();
+                } catch (IOException e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+            } catch (IOException ioe){
+                ioe.printStackTrace();
+            }
+
+
+            return output;
+        }       
+    }
+    
+    
+    private class mAudioFeederAsync extends AsyncTask<Object, Void, AppendingObjectOutputStream>{
+
+        MediaExtractor mExtractor;
+        private AppendingObjectOutputStream oos;
+        private int port = 4439;
+        String path_url = null;
+        
+        @Override
+        protected AppendingObjectOutputStream doInBackground(Object... params) {
+            Log.d("AAAAA", "good to go");
+            // TODO Auto-generated method stub
+            Uri uri = (Uri) params[0];
+            AssetFileDescriptor fd = null;
+            try {
+                ContentResolver resolver = mContext.getContentResolver();
+                fd = resolver.openAssetFileDescriptor(uri, "r");
+            } catch (FileNotFoundException e1) {
+                // TODO Auto-generated catch block
+                e1.printStackTrace();
+            }
+
+//            FileDescriptor fd = (FileDescriptor) params[0];
+            this.port = (Integer) params[1];
+            MediaFormat format = null;
+            String mime = "";
+            int sampleRate = 0, channels = 0, bitrate = 0;
+            long duration = 0;
+            ServerSocket serverSocket = null;
+            
+            
+            try {
+                serverSocket = new ServerSocket();
+                serverSocket.setReuseAddress(true);
+                serverSocket.bind(new InetSocketAddress(this.port));
+                mExtractor = new MediaExtractor();
+                mExtractor.setDataSource(fd.getFileDescriptor());
+            } catch (IOException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+            
+            try {
+                // serverSocket = new ServerSocket(aport);
+                Socket socket = serverSocket.accept();
+                // Socket socket = new Socket(InetAddress.getLocalHost(),
+                // aport);
+                Log.d(TAG, "Audio: client has connected");
+
+                OutputStream out = socket.getOutputStream();
+                ObjectOutputStream oo = new ObjectOutputStream(out);
+                InputStream in = socket.getInputStream();
+                ObjectInputStream ois = new ObjectInputStream(in);
+
+                oo.writeUTF("Hello");
+                oo.flush();
+                
+                oos = new AppendingObjectOutputStream(out);
+                
+                
+                // format setting
+                try {
+                    format = mExtractor.getTrackFormat(1);
+                    mime = format.getString(MediaFormat.KEY_MIME);
+                    sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
+                    channels = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
+                    // if duration is 0, we are probably playing a live stream
+                    duration = format.getLong(MediaFormat.KEY_DURATION);
+                    // getting csd-0
+                    ByteBuffer header_sps = format.getByteBuffer("csd-0");
+                    byte[] b_h_sps = new byte[header_sps.capacity()];
+                    header_sps.get(b_h_sps);
+
+                    // sending format meta-information from here
+                    SdPackage s = new SdPackage(mime, bitrate, channels,
+                            sampleRate, duration, b_h_sps);
+                    oos.writeObject(s);
+                    oos.flush();
+                } catch (IOException ioe) {
+                    ioe.printStackTrace();
+                }
+
+                Log.d(TAG, "feeder, Audio Track info: " + format.toString());
+                mExtractor.selectTrack(1);
+
+                ByteBuffer tmp_byteBuffer = ByteBuffer.allocate(2000);
+                int sampleSize = 0;
+                boolean flag = true;
+                while (flag) {
+                    sampleSize = mExtractor.readSampleData(tmp_byteBuffer, 0);
+
+                    if (sampleSize > 0) {
+                        byte[] to_send = new byte[sampleSize];
+                        for (int i = 0; i < sampleSize; i++) {
+                            to_send[i] = tmp_byteBuffer.get(i);
+                        }
+
+                        long presentationTime = mExtractor.getSampleTime();
+
+                        SdPackage sdp = new SdPackage(sampleSize, to_send,
+                                presentationTime);
+                        oos.writeObject(sdp);
+//                        oos.flush();
+                    }
+                    if (sampleSize < 0) {
+                        flag = false;
+                    } else {
+                        mExtractor.advance();
+                    }
+                }
+                
+                ois.close();
+                serverSocket.close();
+                socket.close();
+            } catch (IOException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+            return null;
+            
+        }
+    }
+    
+    
+    private class mVideoFeeder extends Thread {
+        private MediaExtractor mExtractor;
+        AppendingObjectOutputStream output;
+        int vport = 22300;
+        String path_url = "";
+
+        mVideoFeeder(FileDescriptor fd , int port) {
+            vport = port;
+
+             mExtractor = new MediaExtractor();
+             try {
+             mExtractor.setDataSource(fd);
+             } catch (IOException e) {
+             // TODO Auto-generated catch block
+             e.printStackTrace();
+             }
+        }
+
+        mVideoFeeder(String path, int port) {
+            vport = port;
+            path_url = path;
+        }
+
+        @Override
+        public void run() {
+            try {
+
+//                mExtractor = new MediaExtractor();
+//                mExtractor.setDataSource(fd1);
+
+                ServerSocket serverSocket = new ServerSocket();
+                serverSocket.setReuseAddress(true);
+                serverSocket.bind(new InetSocketAddress(vport));
+                Log.d(TAG, "the server is ready to feed!!");
+                Socket socket = serverSocket.accept();
+                Log.d(TAG, "the client of streaming video is in!!");
+                // Socket s = new Socket(InetAddress.getLocalHost(), vport);
+                OutputStream os = socket.getOutputStream();
+                ObjectOutputStream toos = new ObjectOutputStream(os);
+                output = new AppendingObjectOutputStream(os);
+
+                // Media format
+                for (int i = 0; i < mExtractor.getTrackCount(); i++) {
+                    MediaFormat format = mExtractor.getTrackFormat(i);
+                    String mime = format.getString(MediaFormat.KEY_MIME);
+                    int width = 0, height = 0;
+                    if (mime.startsWith("video/")) {
+                        mExtractor.selectTrack(i);
+                        try {
+                            width = format.getInteger(MediaFormat.KEY_WIDTH);
+                            height = format.getInteger(MediaFormat.KEY_HEIGHT);
+                            // if duration is 0, we are probably playing a live
+                            // stream
+
+                            Log.d(TAG, "Track info: mime:" + mime
+                                    + " sampleRate:" + width + " channels:"
+                                    + height);
+                        } catch (Exception e) {
+                            Log.e(TAG, "Reading format parameters exception:"
+                                    + e.getMessage());
+                            // don't exit, tolerate this error, we'll fail later
+                            // if this is critical
+                        }
+
+                        // toos.writeUTF("connect!");
+                        // toos.flush();
+                        output.writeUTF("connect");
+                        output.flush();
+                        Log.d(TAG, "client: connect? ");
+
+                        // getting csd-0
+                        ByteBuffer header_sps = format.getByteBuffer("csd-0");
+                        byte[] b_h_sps = new byte[header_sps.capacity()];
+                        header_sps.get(b_h_sps);
+                        // getting csd-1
+                        ByteBuffer header_pps = format.getByteBuffer("csd-1");
+                        byte[] b_h_pps = new byte[header_pps.capacity()];
+                        header_pps.get(b_h_pps);
+
+                        vData vdata = new vData();
+                        vdata.setMediaFormat(mime, width, height, b_h_sps,
+                                b_h_pps);
+                        output.writeObject(vdata);
+                        output.flush();
+                        Log.d(TAG, "client: done sending format");
+
+                        break;
+                    }
+                }
+
+                // feeding start
+                boolean isEOS = true;
+
+                ByteBuffer byteBuffer = ByteBuffer.allocate(250000);
+
+                while (isEOS) {
+                    int sampleSize = 0;
+                    try {
+                        sampleSize = mExtractor.readSampleData(byteBuffer, 0);
+                        // Log.d(TAG, j + "  " + byteBuffer.toString());
+                        // byteBuffer.get(to_send);
+                    } catch (IllegalArgumentException e) {
+                        e.printStackTrace();
+                    }
+                    // if (sampleSize < 0) {
+                    // isEOS = false;
+                    // break;
+                    // }
+                    byte[] to_send = new byte[sampleSize];
+
+                    for (int i = 0; i < sampleSize; i++) {
+                        to_send[i] = byteBuffer.get(i);
+                    }
+
+                    // Log.d(TAG, to_send.length + ", " + byteBuffer.limit());
+                    // Log.d(TAG,
+                    // "The sample size is " + String.valueOf(sampleSize));
+                    long presentationTime = mExtractor.getSampleTime();
+
+                    vData vdata = new vData(sampleSize, to_send,
+                            presentationTime);
+                    output.writeObject(vdata);
+                    output.flush();
+//                    Log.d(TAG, "sampleSize at giving " + sampleSize + "");
+                    // if (sampleSize < 0) {
+                    // break;
+                    // } else {
+                    mExtractor.advance();
+                    // }
+                }
+
+                mExtractor.release();
+                socket.close();
+                serverSocket.close();
+            } catch (IOException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+    }
+    
+    private class mAudioFeeder extends Thread {
+
+        MediaExtractor extractor;
+        AppendingObjectOutputStream oos;
+        private int aport = 4439;
+        String path_url = null;
+
+        mAudioFeeder(FileDescriptor fd, int port) {
+            aport = port;
+             extractor = new MediaExtractor();
+             try {
+             extractor.setDataSource(fd);
+             } catch (IOException e) {
+             // TODO Auto-generated catch block
+             e.printStackTrace();
+             }
+        }
+
+        mAudioFeeder(String path, int port) {
+            aport = port;
+            path_url = path;
+        }
+
+        @Override
+        public void run() {
+            
+            MediaFormat format = null;
+            String mime = "";
+            int sampleRate = 0, channels = 0, bitrate = 0;
+            long duration = 0;
+            ServerSocket serverSocket = null;
+            Log.d(TAG, "You entered Audio Feeder");
+
+            try {
+                serverSocket = new ServerSocket();
+                serverSocket.setReuseAddress(true);
+                serverSocket.bind(new InetSocketAddress(aport));
+            } catch (IOException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+                Log.d(TAG, "File not found!!");
+            }
+
+            // Log.d(TAG, String.valueOf(buffer));
+            // ServerSocket serverSocket;
+            try {
+                // serverSocket = new ServerSocket(aport);
+                Socket socket = serverSocket.accept();
+                // Socket socket = new Socket(InetAddress.getLocalHost(),
+                // aport);
+                Log.d(TAG, "Audio: client has connected");
+
+                OutputStream out = socket.getOutputStream();
+                ObjectOutputStream oo = new ObjectOutputStream(out);
+                InputStream in = socket.getInputStream();
+                ObjectInputStream ois = new ObjectInputStream(in);
+
+                oo.writeUTF("Hello");
+                oo.flush();
+                oos = new AppendingObjectOutputStream(out);
+
+                // format setting
+                try {
+                    format = extractor.getTrackFormat(1);
+                    mime = format.getString(MediaFormat.KEY_MIME);
+                    sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
+                    channels = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
+                    // if duration is 0, we are probably playing a live stream
+                    duration = format.getLong(MediaFormat.KEY_DURATION);
+                    // getting csd-0
+                    ByteBuffer header_sps = format.getByteBuffer("csd-0");
+                    byte[] b_h_sps = new byte[header_sps.capacity()];
+                    header_sps.get(b_h_sps);
+
+                    // sending format meta-information from here
+                    SdPackage s = new SdPackage(mime, bitrate, channels,
+                            sampleRate, duration, b_h_sps);
+                    oos.writeObject(s);
+                    oos.flush();
+                } catch (IOException ioe) {
+                    ioe.printStackTrace();
+                }
+
+                Log.d(TAG, "feeder, Audio Track info: " + format.toString());
+                extractor.selectTrack(1);
+
+                ByteBuffer tmp_byteBuffer = ByteBuffer.allocate(2000);
+                int sampleSize = 0;
+                boolean flag = true;
+                while (flag) {
+                    sampleSize = extractor.readSampleData(tmp_byteBuffer, 0);
+
+                    if (sampleSize > 0) {
+                        byte[] to_send = new byte[sampleSize];
+                        for (int i = 0; i < sampleSize; i++) {
+                            to_send[i] = tmp_byteBuffer.get(i);
+                        }
+
+                        long presentationTime = extractor.getSampleTime();
+
+                        SdPackage sdp = new SdPackage(sampleSize, to_send,
+                                presentationTime);
+                        oos.writeObject(sdp);
+                        oos.flush();
+                    }
+                    if (sampleSize < 0) {
+                        flag = false;
+                    } else {
+                        extractor.advance();
+                    }
+                }
+
+                oos.close();
+                socket.close();
+            } catch (IOException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+    }
+
     /**
-     * Prepares the player for playback, synchronously.
-     *
-     * After setting the datasource and the display surface, you need to either
-     * call prepare() or prepareAsync(). For files, it is OK to call prepare(),
-     * which blocks until MediaPlayer is ready for playback.
-     *
+     * Prepares the player for playback, synchronously. After setting the
+     * datasource and the display surface, you need to either call prepare() or
+     * prepareAsync(). For files, it is OK to call prepare(), which blocks until
+     * MediaPlayer is ready for playback.
+     * 
      * @throws IllegalStateException if it is called in an invalid state
      */
     public native void prepare() throws IOException, IllegalStateException;
 
     /**
-     * Prepares the player for playback, asynchronously.
-     *
-     * After setting the datasource and the display surface, you need to either
-     * call prepare() or prepareAsync(). For streams, you should call prepareAsync(),
-     * which returns immediately, rather than blocking until enough data has been
+     * Prepares the player for playback, asynchronously. After setting the
+     * datasource and the display surface, you need to either call prepare() or
+     * prepareAsync(). For streams, you should call prepareAsync(), which
+     * returns immediately, rather than blocking until enough data has been
      * buffered.
-     *
+     * 
      * @throws IllegalStateException if it is called in an invalid state
      */
     public native void prepareAsync() throws IllegalStateException;
 
     /**
      * Starts or resumes playback. If playback had previously been paused,
-     * playback will continue from where it was paused. If playback had
-     * been stopped, or never started before, playback will start at the
-     * beginning.
-     *
+     * playback will continue from where it was paused. If playback had been
+     * stopped, or never started before, playback will start at the beginning.
+     * 
      * @throws IllegalStateException if it is called in an invalid state
      */
-    public  void start() throws IllegalStateException {
+    public void start() throws IllegalStateException {
         stayAwake(true);
+//        Log.d("VideoLatency", "Before _start()");
         _start();
+        Log.d("VideoLatency", "After _start()");
     }
 
     private native void _start() throws IllegalStateException;
 
     /**
      * Stops playback after playback has been stopped or paused.
-     *
+     * 
      * @throws IllegalStateException if the internal player engine has not been
-     * initialized.
+     *             initialized.
      */
     public void stop() throws IllegalStateException {
         stayAwake(false);
         _stop();
+        
     }
 
     private native void _stop() throws IllegalStateException;
 
     /**
      * Pauses playback. Call start() to resume.
-     *
+     * 
      * @throws IllegalStateException if the internal player engine has not been
-     * initialized.
+     *             initialized.
      */
     public void pause() throws IllegalStateException {
         stayAwake(false);
         _pause();
+        
+        Log.d(TAG, "pause.......................");
+        IRemoteService mService = IRemoteService.Stub
+                .asInterface(ServiceManager.getService(Context.REMOTE_SERVICE));
+            
+            if (isAudio) {
+                ArrayList<Object> para = new ArrayList<Object>();
+                RemoteRequest mRequest = new RemoteRequest("StopMusic",
+                        "Stop", para);
+                
+                try {
+                    mService.sendAllrequest(mRequest);
+                } catch (RemoteException e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+            }
+        
+        
+        Log.d(TAG, "closing all sockets");
+//        closing_all_serversockets();
     }
 
     private native void _pause() throws IllegalStateException;
 
     /**
-     * Set the low-level power management behavior for this MediaPlayer.  This
+     * Set the low-level power management behavior for this MediaPlayer. This
      * can be used when the MediaPlayer is not playing through a SurfaceHolder
      * set with {@link #setDisplay(SurfaceHolder)} and thus can use the
      * high-level {@link #setScreenOnWhilePlaying(boolean)} feature.
-     *
-     * <p>This function has the MediaPlayer access the low-level power manager
+     * <p>
+     * This function has the MediaPlayer access the low-level power manager
      * service to control the device's power usage while playing is occurring.
-     * The parameter is a combination of {@link android.os.PowerManager} wake flags.
-     * Use of this method requires {@link android.Manifest.permission#WAKE_LOCK}
-     * permission.
-     * By default, no attempt is made to keep the device awake during playback.
-     *
+     * The parameter is a combination of {@link android.os.PowerManager} wake
+     * flags. Use of this method requires
+     * {@link android.Manifest.permission#WAKE_LOCK} permission. By default, no
+     * attempt is made to keep the device awake during playback.
+     * 
      * @param context the Context to use
-     * @param mode    the power/wake mode to set
+     * @param mode the power/wake mode to set
      * @see android.os.PowerManager
      */
     public void setWakeMode(Context context, int mode) {
@@ -1119,8 +2518,9 @@
             mWakeLock = null;
         }
 
-        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
-        mWakeLock = pm.newWakeLock(mode|PowerManager.ON_AFTER_RELEASE, MediaPlayer.class.getName());
+        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+        mWakeLock = pm.newWakeLock(mode | PowerManager.ON_AFTER_RELEASE,
+                MediaPlayer.class.getName());
         mWakeLock.setReferenceCounted(false);
         if (washeld) {
             mWakeLock.acquire();
@@ -1129,13 +2529,12 @@
 
     /**
      * Control whether we should use the attached SurfaceHolder to keep the
-     * screen on while video playback is occurring.  This is the preferred
-     * method over {@link #setWakeMode} where possible, since it doesn't
-     * require that the application have permission for low-level wake lock
-     * access.
-     *
-     * @param screenOn Supply true to keep the screen on, false to allow it
-     * to turn off.
+     * screen on while video playback is occurring. This is the preferred method
+     * over {@link #setWakeMode} where possible, since it doesn't require that
+     * the application have permission for low-level wake lock access.
+     * 
+     * @param screenOn Supply true to keep the screen on, false to allow it to
+     *            turn off.
      */
     public void setScreenOnWhilePlaying(boolean screenOn) {
         if (mScreenOnWhilePlaying != screenOn) {
@@ -1167,77 +2566,73 @@
 
     /**
      * Returns the width of the video.
-     *
-     * @return the width of the video, or 0 if there is no video,
-     * no display surface was set, or the width has not been determined
-     * yet. The OnVideoSizeChangedListener can be registered via
-     * {@link #setOnVideoSizeChangedListener(OnVideoSizeChangedListener)}
-     * to provide a notification when the width is available.
+     * 
+     * @return the width of the video, or 0 if there is no video, no display
+     *         surface was set, or the width has not been determined yet. The
+     *         OnVideoSizeChangedListener can be registered via
+     *         {@link #setOnVideoSizeChangedListener(OnVideoSizeChangedListener)}
+     *         to provide a notification when the width is available.
      */
     public native int getVideoWidth();
 
     /**
      * Returns the height of the video.
-     *
-     * @return the height of the video, or 0 if there is no video,
-     * no display surface was set, or the height has not been determined
-     * yet. The OnVideoSizeChangedListener can be registered via
-     * {@link #setOnVideoSizeChangedListener(OnVideoSizeChangedListener)}
-     * to provide a notification when the height is available.
+     * 
+     * @return the height of the video, or 0 if there is no video, no display
+     *         surface was set, or the height has not been determined yet. The
+     *         OnVideoSizeChangedListener can be registered via
+     *         {@link #setOnVideoSizeChangedListener(OnVideoSizeChangedListener)}
+     *         to provide a notification when the height is available.
      */
     public native int getVideoHeight();
 
     /**
      * Checks whether the MediaPlayer is playing.
-     *
+     * 
      * @return true if currently playing, false otherwise
      * @throws IllegalStateException if the internal player engine has not been
-     * initialized or has been released.
+     *             initialized or has been released.
      */
     public native boolean isPlaying();
 
     /**
      * Seeks to specified time position.
-     *
+     * 
      * @param msec the offset in milliseconds from the start to seek to
      * @throws IllegalStateException if the internal player engine has not been
-     * initialized
+     *             initialized
      */
     public native void seekTo(int msec) throws IllegalStateException;
 
     /**
      * Gets the current playback position.
-     *
+     * 
      * @return the current position in milliseconds
      */
     public native int getCurrentPosition();
 
     /**
      * Gets the duration of the file.
-     *
-     * @return the duration in milliseconds, if no duration is available
-     *         (for example, if streaming live content), -1 is returned.
+     * 
+     * @return the duration in milliseconds, if no duration is available (for
+     *         example, if streaming live content), -1 is returned.
      */
     public native int getDuration();
 
     /**
      * Gets the media metadata.
-     *
-     * @param update_only controls whether the full set of available
-     * metadata is returned or just the set that changed since the
-     * last call. See {@see #METADATA_UPDATE_ONLY} and {@see
-     * #METADATA_ALL}.
-     *
-     * @param apply_filter if true only metadata that matches the
-     * filter is returned. See {@see #APPLY_METADATA_FILTER} and {@see
-     * #BYPASS_METADATA_FILTER}.
-     *
-     * @return The metadata, possibly empty. null if an error occured.
-     // FIXME: unhide.
-     * {@hide}
+     * 
+     * @param update_only controls whether the full set of available metadata is
+     *            returned or just the set that changed since the last call. See
+     *            {@see #METADATA_UPDATE_ONLY} and {@see #METADATA_ALL}.
+     * @param apply_filter if true only metadata that matches the filter is
+     *            returned. See {@see #APPLY_METADATA_FILTER} and {@see
+     *            #BYPASS_METADATA_FILTER}.
+     * @return The metadata, possibly empty. null if an error occured. // FIXME:
+     *         unhide. {@hide}
      */
     public Metadata getMetadata(final boolean update_only,
-                                final boolean apply_filter) {
+            final boolean apply_filter) {
         Parcel reply = Parcel.obtain();
         Metadata data = new Metadata();
 
@@ -1256,23 +2651,18 @@
     }
 
     /**
-     * Set a filter for the metadata update notification and update
-     * retrieval. The caller provides 2 set of metadata keys, allowed
-     * and blocked. The blocked set always takes precedence over the
-     * allowed one.
+     * Set a filter for the metadata update notification and update retrieval.
+     * The caller provides 2 set of metadata keys, allowed and blocked. The
+     * blocked set always takes precedence over the allowed one.
      * Metadata.MATCH_ALL and Metadata.MATCH_NONE are 2 sets available as
-     * shorthands to allow/block all or no metadata.
-     *
-     * By default, there is no filter set.
-     *
-     * @param allow Is the set of metadata the client is interested
-     *              in receiving new notifications for.
-     * @param block Is the set of metadata the client is not interested
-     *              in receiving new notifications for.
-     * @return The call status code.
-     *
-     // FIXME: unhide.
-     * {@hide}
+     * shorthands to allow/block all or no metadata. By default, there is no
+     * filter set.
+     * 
+     * @param allow Is the set of metadata the client is interested in receiving
+     *            new notifications for.
+     * @param block Is the set of metadata the client is not interested in
+     *            receiving new notifications for.
+     * @return The call status code. // FIXME: unhide. {@hide}
      */
     public int setMetadataFilter(Set<Integer> allow, Set<Integer> block) {
         // Do our serialization manually instead of calling
@@ -1280,7 +2670,7 @@
         // we avoid paying the price of calling writeValue (used by
         // writeArray) which burns an extra int per element to encode
         // the type.
-        Parcel request =  newRequest();
+        Parcel request = newRequest();
 
         // The parcel starts already with an interface token. There
         // are 2 filters. Each one starts with a 4bytes number to
@@ -1293,11 +2683,11 @@
         }
 
         request.writeInt(allow.size());
-        for(Integer t: allow) {
+        for (Integer t : allow) {
             request.writeInt(t);
         }
         request.writeInt(block.size());
-        for(Integer t: block) {
+        for (Integer t : block) {
             request.writeInt(t);
         }
         return native_setMetadataFilter(request);
@@ -1305,40 +2695,35 @@
 
     /**
      * Set the MediaPlayer to start when this MediaPlayer finishes playback
-     * (i.e. reaches the end of the stream).
-     * The media framework will attempt to transition from this player to
-     * the next as seamlessly as possible. The next player can be set at
-     * any time before completion. The next player must be prepared by the
-     * app, and the application should not call start() on it.
-     * The next MediaPlayer must be different from 'this'. An exception
-     * will be thrown if next == this.
-     * The application may call setNextMediaPlayer(null) to indicate no
-     * next player should be started at the end of playback.
-     * If the current player is looping, it will keep looping and the next
-     * player will not be started.
-     *
+     * (i.e. reaches the end of the stream). The media framework will attempt to
+     * transition from this player to the next as seamlessly as possible. The
+     * next player can be set at any time before completion. The next player
+     * must be prepared by the app, and the application should not call start()
+     * on it. The next MediaPlayer must be different from 'this'. An exception
+     * will be thrown if next == this. The application may call
+     * setNextMediaPlayer(null) to indicate no next player should be started at
+     * the end of playback. If the current player is looping, it will keep
+     * looping and the next player will not be started.
+     * 
      * @param next the player to start after this one completes playback.
-     *
      */
     public native void setNextMediaPlayer(MediaPlayer next);
 
     /**
-     * Releases resources associated with this MediaPlayer object.
-     * It is considered good practice to call this method when you're
-     * done using the MediaPlayer. In particular, whenever an Activity
-     * of an application is paused (its onPause() method is called),
-     * or stopped (its onStop() method is called), this method should be
-     * invoked to release the MediaPlayer object, unless the application
-     * has a special need to keep the object around. In addition to
-     * unnecessary resources (such as memory and instances of codecs)
-     * being held, failure to call this method immediately if a
-     * MediaPlayer object is no longer needed may also lead to
-     * continuous battery consumption for mobile devices, and playback
-     * failure for other applications if no multiple instances of the
-     * same codec are supported on a device. Even if multiple instances
-     * of the same codec are supported, some performance degradation
-     * may be expected when unnecessary multiple instances are used
-     * at the same time.
+     * Releases resources associated with this MediaPlayer object. It is
+     * considered good practice to call this method when you're done using the
+     * MediaPlayer. In particular, whenever an Activity of an application is
+     * paused (its onPause() method is called), or stopped (its onStop() method
+     * is called), this method should be invoked to release the MediaPlayer
+     * object, unless the application has a special need to keep the object
+     * around. In addition to unnecessary resources (such as memory and
+     * instances of codecs) being held, failure to call this method immediately
+     * if a MediaPlayer object is no longer needed may also lead to continuous
+     * battery consumption for mobile devices, and playback failure for other
+     * applications if no multiple instances of the same codec are supported on
+     * a device. Even if multiple instances of the same codec are supported,
+     * some performance degradation may be expected when unnecessary multiple
+     * instances are used at the same time.
      */
     public void release() {
         stayAwake(false);
@@ -1362,14 +2747,14 @@
     private native void _release();
 
     /**
-     * Resets the MediaPlayer to its uninitialized state. After calling
-     * this method, you will have to initialize it again by setting the
-     * data source and calling prepare().
+     * Resets the MediaPlayer to its uninitialized state. After calling this
+     * method, you will have to initialize it again by setting the data source
+     * and calling prepare().
      */
     public void reset() {
         mSelectedSubtitleTrackIndex = -1;
-        synchronized(mOpenSubtitleSources) {
-            for (final InputStream is: mOpenSubtitleSources) {
+        synchronized (mOpenSubtitleSources) {
+            for (final InputStream is : mOpenSubtitleSources) {
                 try {
                     is.close();
                 } catch (IOException e) {
@@ -1404,7 +2789,7 @@
      * for a list of stream types. Must call this method before prepare() or
      * prepareAsync() in order for the target stream type to become effective
      * thereafter.
-     *
+     * 
      * @param streamtype the audio stream type
      * @see android.media.AudioManager
      */
@@ -1412,39 +2797,40 @@
 
     /**
      * Sets the player to be looping or non-looping.
-     *
+     * 
      * @param looping whether to loop or not
      */
     public native void setLooping(boolean looping);
 
     /**
      * Checks whether the MediaPlayer is looping or non-looping.
-     *
+     * 
      * @return true if the MediaPlayer is currently looping, false otherwise
      */
     public native boolean isLooping();
 
     /**
-     * Sets the volume on this player.
-     * This API is recommended for balancing the output of audio streams
-     * within an application. Unless you are writing an application to
-     * control user settings, this API should be used in preference to
-     * {@link AudioManager#setStreamVolume(int, int, int)} which sets the volume of ALL streams of
-     * a particular type. Note that the passed volume values are raw scalars in range 0.0 to 1.0.
-     * UI controls should be scaled logarithmically.
-     *
+     * Sets the volume on this player. This API is recommended for balancing the
+     * output of audio streams within an application. Unless you are writing an
+     * application to control user settings, this API should be used in
+     * preference to {@link AudioManager#setStreamVolume(int, int, int)} which
+     * sets the volume of ALL streams of a particular type. Note that the passed
+     * volume values are raw scalars in range 0.0 to 1.0. UI controls should be
+     * scaled logarithmically.
+     * 
      * @param leftVolume left volume scalar
      * @param rightVolume right volume scalar
      */
     /*
-     * FIXME: Merge this into javadoc comment above when setVolume(float) is not @hide.
-     * The single parameter form below is preferred if the channel volumes don't need
-     * to be set independently.
+     * FIXME: Merge this into javadoc comment above when setVolume(float) is not
+     * @hide. The single parameter form below is preferred if the channel
+     * volumes don't need to be set independently.
      */
     public native void setVolume(float leftVolume, float rightVolume);
 
     /**
      * Similar, excepts sets volume of all channels to same value.
+     * 
      * @hide
      */
     public void setVolume(float volume) {
@@ -1453,110 +2839,122 @@
 
     /**
      * Sets the audio session ID.
-     *
-     * @param sessionId the audio session ID.
-     * The audio session ID is a system wide unique identifier for the audio stream played by
-     * this MediaPlayer instance.
-     * The primary use of the audio session ID  is to associate audio effects to a particular
-     * instance of MediaPlayer: if an audio session ID is provided when creating an audio effect,
-     * this effect will be applied only to the audio content of media players within the same
-     * audio session and not to the output mix.
-     * When created, a MediaPlayer instance automatically generates its own audio session ID.
-     * However, it is possible to force this player to be part of an already existing audio session
-     * by calling this method.
-     * This method must be called before one of the overloaded <code> setDataSource </code> methods.
+     * 
+     * @param sessionId the audio session ID. The audio session ID is a system
+     *            wide unique identifier for the audio stream played by this
+     *            MediaPlayer instance. The primary use of the audio session ID
+     *            is to associate audio effects to a particular instance of
+     *            MediaPlayer: if an audio session ID is provided when creating
+     *            an audio effect, this effect will be applied only to the audio
+     *            content of media players within the same audio session and not
+     *            to the output mix. When created, a MediaPlayer instance
+     *            automatically generates its own audio session ID. However, it
+     *            is possible to force this player to be part of an already
+     *            existing audio session by calling this method. This method
+     *            must be called before one of the overloaded
+     *            <code> setDataSource </code> methods.
      * @throws IllegalStateException if it is called in an invalid state
      */
-    public native void setAudioSessionId(int sessionId)  throws IllegalArgumentException, IllegalStateException;
+    public native void setAudioSessionId(int sessionId) throws IllegalArgumentException,
+            IllegalStateException;
 
     /**
      * Returns the audio session ID.
-     *
-     * @return the audio session ID. {@see #setAudioSessionId(int)}
-     * Note that the audio session ID is 0 only if a problem occured when the MediaPlayer was contructed.
+     * 
+     * @return the audio session ID. {@see #setAudioSessionId(int)} Note that
+     *         the audio session ID is 0 only if a problem occured when the
+     *         MediaPlayer was contructed.
      */
     public native int getAudioSessionId();
 
     /**
-     * Attaches an auxiliary effect to the player. A typical auxiliary effect is a reverberation
-     * effect which can be applied on any sound source that directs a certain amount of its
-     * energy to this effect. This amount is defined by setAuxEffectSendLevel().
-     * {@see #setAuxEffectSendLevel(float)}.
-     * <p>After creating an auxiliary effect (e.g.
+     * Attaches an auxiliary effect to the player. A typical auxiliary effect is
+     * a reverberation effect which can be applied on any sound source that
+     * directs a certain amount of its energy to this effect. This amount is
+     * defined by setAuxEffectSendLevel(). {@see #setAuxEffectSendLevel(float)}.
+     * <p>
+     * After creating an auxiliary effect (e.g.
      * {@link android.media.audiofx.EnvironmentalReverb}), retrieve its ID with
-     * {@link android.media.audiofx.AudioEffect#getId()} and use it when calling this method
-     * to attach the player to the effect.
-     * <p>To detach the effect from the player, call this method with a null effect id.
-     * <p>This method must be called after one of the overloaded <code> setDataSource </code>
-     * methods.
+     * {@link android.media.audiofx.AudioEffect#getId()} and use it when calling
+     * this method to attach the player to the effect.
+     * <p>
+     * To detach the effect from the player, call this method with a null effect
+     * id.
+     * <p>
+     * This method must be called after one of the overloaded
+     * <code> setDataSource </code> methods.
+     * 
      * @param effectId system wide unique id of the effect to attach
      */
     public native void attachAuxEffect(int effectId);
 
-
     /**
-     * Sets the send level of the player to the attached auxiliary effect
-     * {@see #attachAuxEffect(int)}. The level value range is 0 to 1.0.
-     * <p>By default the send level is 0, so even if an effect is attached to the player
-     * this method must be called for the effect to be applied.
-     * <p>Note that the passed level value is a raw scalar. UI controls should be scaled
-     * logarithmically: the gain applied by audio framework ranges from -72dB to 0dB,
-     * so an appropriate conversion from linear UI input x to level is:
-     * x == 0 -> level = 0
-     * 0 < x <= R -> level = 10^(72*(x-R)/20/R)
+     * Sets the send level of the player to the attached auxiliary effect {@see
+     * #attachAuxEffect(int)}. The level value range is 0 to 1.0.
+     * <p>
+     * By default the send level is 0, so even if an effect is attached to the
+     * player this method must be called for the effect to be applied.
+     * <p>
+     * Note that the passed level value is a raw scalar. UI controls should be
+     * scaled logarithmically: the gain applied by audio framework ranges from
+     * -72dB to 0dB, so an appropriate conversion from linear UI input x to
+     * level is: x == 0 -> level = 0 0 < x <= R -> level = 10^(72*(x-R)/20/R)
+     * 
      * @param level send level scalar
      */
     public native void setAuxEffectSendLevel(float level);
 
     /*
-     * @param request Parcel destinated to the media player. The
-     *                Interface token must be set to the IMediaPlayer
-     *                one to be routed correctly through the system.
+     * @param request Parcel destinated to the media player. The Interface token
+     * must be set to the IMediaPlayer one to be routed correctly through the
+     * system.
      * @param reply[out] Parcel that will contain the reply.
      * @return The status code.
      */
     private native final int native_invoke(Parcel request, Parcel reply);
 
-
     /*
      * @param update_only If true fetch only the set of metadata that have
-     *                    changed since the last invocation of getMetadata.
-     *                    The set is built using the unfiltered
-     *                    notifications the native player sent to the
-     *                    MediaPlayerService during that period of
-     *                    time. If false, all the metadatas are considered.
-     * @param apply_filter  If true, once the metadata set has been built based on
-     *                     the value update_only, the current filter is applied.
-     * @param reply[out] On return contains the serialized
-     *                   metadata. Valid only if the call was successful.
+     * changed since the last invocation of getMetadata. The set is built using
+     * the unfiltered notifications the native player sent to the
+     * MediaPlayerService during that period of time. If false, all the
+     * metadatas are considered.
+     * @param apply_filter If true, once the metadata set has been built based
+     * on the value update_only, the current filter is applied.
+     * @param reply[out] On return contains the serialized metadata. Valid only
+     * if the call was successful.
      * @return The status code.
      */
     private native final boolean native_getMetadata(boolean update_only,
-                                                    boolean apply_filter,
-                                                    Parcel reply);
+            boolean apply_filter,
+            Parcel reply);
 
     /*
-     * @param request Parcel with the 2 serialized lists of allowed
-     *                metadata types followed by the one to be
-     *                dropped. Each list starts with an integer
-     *                indicating the number of metadata type elements.
+     * @param request Parcel with the 2 serialized lists of allowed metadata
+     * types followed by the one to be dropped. Each list starts with an integer
+     * indicating the number of metadata type elements.
      * @return The status code.
      */
     private native final int native_setMetadataFilter(Parcel request);
 
     private static native final void native_init();
+
     private native final void native_setup(Object mediaplayer_this);
+
     private native final void native_finalize();
 
     /**
-     * Class for MediaPlayer to return each audio/video/subtitle track's metadata.
-     *
+     * Class for MediaPlayer to return each audio/video/subtitle track's
+     * metadata.
+     * 
      * @see android.media.MediaPlayer#getTrackInfo
      */
     static public class TrackInfo implements Parcelable {
         /**
          * Gets the track type.
-         * @return TrackType which indicates if the track is video, audio, timed text.
+         * 
+         * @return TrackType which indicates if the track is video, audio, timed
+         *         text.
          */
         public int getTrackType() {
             return mTrackType;
@@ -1564,9 +2962,10 @@
 
         /**
          * Gets the language code of the track.
-         * @return a language code in either way of ISO-639-1 or ISO-639-2.
-         * When the language is unknown or could not be determined,
-         * ISO-639-2 language code, "und", is returned.
+         * 
+         * @return a language code in either way of ISO-639-1 or ISO-639-2. When
+         *         the language is unknown or could not be determined, ISO-639-2
+         *         language code, "und", is returned.
          */
         public String getLanguage() {
             String language = mFormat.getString(MediaFormat.KEY_LANGUAGE);
@@ -1574,8 +2973,8 @@
         }
 
         /**
-         * Gets the {@link MediaFormat} of the track.  If the format is
-         * unknown or could not be determined, null is returned.
+         * Gets the {@link MediaFormat} of the track. If the format is unknown
+         * or could not be determined, null is returned.
          */
         public MediaFormat getFormat() {
             if (mTrackType == MEDIA_TRACK_TYPE_TIMEDTEXT
@@ -1602,10 +3001,10 @@
 
             if (mTrackType == MEDIA_TRACK_TYPE_TIMEDTEXT) {
                 mFormat = MediaFormat.createSubtitleFormat(
-                    MEDIA_MIMETYPE_TEXT_SUBRIP, language);
+                        MEDIA_MIMETYPE_TEXT_SUBRIP, language);
             } else if (mTrackType == MEDIA_TRACK_TYPE_SUBTITLE) {
                 mFormat = MediaFormat.createSubtitleFormat(
-                    MEDIA_MIMETYPE_TEXT_VTT, language);
+                        MEDIA_MIMETYPE_TEXT_VTT, language);
                 mFormat.setInteger(MediaFormat.KEY_IS_AUTOSELECT, in.readInt());
                 mFormat.setInteger(MediaFormat.KEY_IS_DEFAULT, in.readInt());
                 mFormat.setInteger(MediaFormat.KEY_IS_FORCED_SUBTITLE, in.readInt());
@@ -1647,27 +3046,27 @@
         /**
          * Used to read a TrackInfo from a Parcel.
          */
-        static final Parcelable.Creator<TrackInfo> CREATOR
-                = new Parcelable.Creator<TrackInfo>() {
-                    @Override
-                    public TrackInfo createFromParcel(Parcel in) {
-                        return new TrackInfo(in);
-                    }
+        static final Parcelable.Creator<TrackInfo> CREATOR = new Parcelable.Creator<TrackInfo>() {
+            @Override
+            public TrackInfo createFromParcel(Parcel in) {
+                return new TrackInfo(in);
+            }
 
-                    @Override
-                    public TrackInfo[] newArray(int size) {
-                        return new TrackInfo[size];
-                    }
-                };
+            @Override
+            public TrackInfo[] newArray(int size) {
+                return new TrackInfo[size];
+            }
+        };
 
     };
 
     /**
      * Returns an array of track information.
-     *
-     * @return Array of track info. The total number of tracks is the array length.
-     * Must be called again if an external timed text source has been added after any of the
-     * addTimedTextSource methods are called.
+     * 
+     * @return Array of track info. The total number of tracks is the array
+     *         length. Must be called again if an external timed text source has
+     *         been added after any of the addTimedTextSource methods are
+     *         called.
      * @throws IllegalStateException if it is called in an invalid state.
      */
     public TrackInfo[] getTrackInfo() throws IllegalStateException {
@@ -1676,7 +3075,7 @@
         TrackInfo allTrackInfo[] = new TrackInfo[trackInfo.length + mOutOfBandSubtitleTracks.size()];
         System.arraycopy(trackInfo, 0, allTrackInfo, 0, trackInfo.length);
         int i = trackInfo.length;
-        for (SubtitleTrack track: mOutOfBandSubtitleTracks) {
+        for (SubtitleTrack track : mOutOfBandSubtitleTracks) {
             allTrackInfo[i] = new TrackInfo(TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE, track.getFormat());
             ++i;
         }
@@ -1698,8 +3097,10 @@
         }
     }
 
-    /* Do not change these values without updating their counterparts
-     * in include/media/stagefright/MediaDefs.h and media/libstagefright/MediaDefs.cpp!
+    /*
+     * Do not change these values without updating their counterparts in
+     * include/media/stagefright/MediaDefs.h and
+     * media/libstagefright/MediaDefs.cpp!
      */
     /**
      * MIME type for SubRip (SRT) container. Used in addTimedTextSource APIs.
@@ -1708,12 +3109,14 @@
 
     /**
      * MIME type for WebVTT subtitle data.
+     * 
      * @hide
      */
     public static final String MEDIA_MIMETYPE_TEXT_VTT = "text/vtt";
 
     /*
-     * A helper function to check if the mime type is supported by media framework.
+     * A helper function to check if the mime type is supported by media
+     * framework.
      */
     private static boolean availableMimeTypeForExternalSource(String mimeType) {
         if (mimeType == MEDIA_MIMETYPE_TEXT_SUBRIP) {
@@ -1797,15 +3200,15 @@
         final InputStream fIs = is;
         final MediaFormat fFormat = format;
 
-        // Ensure all input streams are closed.  It is also a handy
+        // Ensure all input streams are closed. It is also a handy
         // way to implement timeouts in the future.
-        synchronized(mOpenSubtitleSources) {
+        synchronized (mOpenSubtitleSources) {
             mOpenSubtitleSources.add(is);
         }
 
         // process each subtitle in its own thread
         final HandlerThread thread = new HandlerThread("SubtitleReadThread",
-              Process.THREAD_PRIORITY_BACKGROUND + Process.THREAD_PRIORITY_MORE_FAVORABLE);
+                Process.THREAD_PRIORITY_BACKGROUND + Process.THREAD_PRIORITY_MORE_FAVORABLE);
         thread.start();
         Handler handler = new Handler(thread.getLooper());
         handler.post(new Runnable() {
@@ -1822,7 +3225,7 @@
                 // TODO: do the conversion in the subtitle track
                 Scanner scanner = new Scanner(fIs, "UTF-8");
                 String contents = scanner.useDelimiter("\\A").next();
-                synchronized(mOpenSubtitleSources) {
+                synchronized (mOpenSubtitleSources) {
                     mOpenSubtitleSources.remove(fIs);
                 }
                 scanner.close();
@@ -1850,7 +3253,7 @@
 
         TrackInfo[] tracks = getInbandTrackInfo();
         SubtitleTrack[] inbandTracks = new SubtitleTrack[tracks.length];
-        for (int i=0; i < tracks.length; i++) {
+        for (int i = 0; i < tracks.length; i++) {
             if (tracks[i].getTrackType() == TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) {
                 if (i < mInbandSubtitleTracks.length) {
                     inbandTracks[i] = mInbandSubtitleTracks[i];
@@ -1865,18 +3268,20 @@
         mSubtitleController.selectDefaultTrack();
     }
 
-    /* TODO: Limit the total number of external timed text source to a reasonable number.
+    /*
+     * TODO: Limit the total number of external timed text source to a
+     * reasonable number.
      */
     /**
-     * Adds an external timed text source file.
-     *
-     * Currently supported format is SubRip with the file extension .srt, case insensitive.
-     * Note that a single external timed text source may contain multiple tracks in it.
-     * One can find the total number of available tracks using {@link #getTrackInfo()} to see what
-     * additional tracks become available after this method call.
-     *
+     * Adds an external timed text source file. Currently supported format is
+     * SubRip with the file extension .srt, case insensitive. Note that a single
+     * external timed text source may contain multiple tracks in it. One can
+     * find the total number of available tracks using {@link #getTrackInfo()}
+     * to see what additional tracks become available after this method call.
+     * 
      * @param path The file path of external timed text source file.
-     * @param mimeType The mime type of the file. Must be one of the mime types listed above.
+     * @param mimeType The mime type of the file. Must be one of the mime types
+     *            listed above.
      * @throws IOException if the file cannot be accessed or is corrupted.
      * @throws IllegalArgumentException if the mimeType is not supported.
      * @throws IllegalStateException if called in an invalid state.
@@ -1901,16 +3306,17 @@
     }
 
     /**
-     * Adds an external timed text source file (Uri).
-     *
-     * Currently supported format is SubRip with the file extension .srt, case insensitive.
-     * Note that a single external timed text source may contain multiple tracks in it.
-     * One can find the total number of available tracks using {@link #getTrackInfo()} to see what
-     * additional tracks become available after this method call.
-     *
+     * Adds an external timed text source file (Uri). Currently supported format
+     * is SubRip with the file extension .srt, case insensitive. Note that a
+     * single external timed text source may contain multiple tracks in it. One
+     * can find the total number of available tracks using
+     * {@link #getTrackInfo()} to see what additional tracks become available
+     * after this method call.
+     * 
      * @param context the Context to use when resolving the Uri
      * @param uri the Content URI of the data you want to play
-     * @param mimeType The mime type of the file. Must be one of the mime types listed above.
+     * @param mimeType The mime type of the file. Must be one of the mime types
+     *            listed above.
      * @throws IOException if the file cannot be accessed or is corrupted.
      * @throws IllegalArgumentException if the mimeType is not supported.
      * @throws IllegalStateException if called in an invalid state.
@@ -1918,7 +3324,7 @@
     public void addTimedTextSource(Context context, Uri uri, String mimeType)
             throws IOException, IllegalArgumentException, IllegalStateException {
         String scheme = uri.getScheme();
-        if(scheme == null || scheme.equals("file")) {
+        if (scheme == null || scheme.equals("file")) {
             addTimedTextSource(uri.getPath(), mimeType);
             return;
         }
@@ -1942,18 +3348,17 @@
     }
 
     /**
-     * Adds an external timed text source file (FileDescriptor).
-     *
-     * It is the caller's responsibility to close the file descriptor.
-     * It is safe to do so as soon as this call returns.
-     *
-     * Currently supported format is SubRip. Note that a single external timed text source may
-     * contain multiple tracks in it. One can find the total number of available tracks
-     * using {@link #getTrackInfo()} to see what additional tracks become available
+     * Adds an external timed text source file (FileDescriptor). It is the
+     * caller's responsibility to close the file descriptor. It is safe to do so
+     * as soon as this call returns. Currently supported format is SubRip. Note
+     * that a single external timed text source may contain multiple tracks in
+     * it. One can find the total number of available tracks using
+     * {@link #getTrackInfo()} to see what additional tracks become available
      * after this method call.
-     *
+     * 
      * @param fd the FileDescriptor for the file you want to play
-     * @param mimeType The mime type of the file. Must be one of the mime types listed above.
+     * @param mimeType The mime type of the file. Must be one of the mime types
+     *            listed above.
      * @throws IllegalArgumentException if the mimeType is not supported.
      * @throws IllegalStateException if called in an invalid state.
      */
@@ -1964,27 +3369,28 @@
     }
 
     /**
-     * Adds an external timed text file (FileDescriptor).
-     *
-     * It is the caller's responsibility to close the file descriptor.
-     * It is safe to do so as soon as this call returns.
-     *
-     * Currently supported format is SubRip. Note that a single external timed text source may
-     * contain multiple tracks in it. One can find the total number of available tracks
-     * using {@link #getTrackInfo()} to see what additional tracks become available
+     * Adds an external timed text file (FileDescriptor). It is the caller's
+     * responsibility to close the file descriptor. It is safe to do so as soon
+     * as this call returns. Currently supported format is SubRip. Note that a
+     * single external timed text source may contain multiple tracks in it. One
+     * can find the total number of available tracks using
+     * {@link #getTrackInfo()} to see what additional tracks become available
      * after this method call.
-     *
+     * 
      * @param fd the FileDescriptor for the file you want to play
-     * @param offset the offset into the file where the data to be played starts, in bytes
+     * @param offset the offset into the file where the data to be played
+     *            starts, in bytes
      * @param length the length in bytes of the data to be played
-     * @param mimeType The mime type of the file. Must be one of the mime types listed above.
+     * @param mimeType The mime type of the file. Must be one of the mime types
+     *            listed above.
      * @throws IllegalArgumentException if the mimeType is not supported.
      * @throws IllegalStateException if called in an invalid state.
      */
     public void addTimedTextSource(FileDescriptor fd, long offset, long length, String mimeType)
             throws IllegalArgumentException, IllegalStateException {
         if (!availableMimeTypeForExternalSource(mimeType)) {
-            throw new IllegalArgumentException("Illegal mimeType for timed text source: " + mimeType);
+            throw new IllegalArgumentException("Illegal mimeType for timed text source: "
+                    + mimeType);
         }
 
         Parcel request = Parcel.obtain();
@@ -2006,29 +3412,32 @@
     /**
      * Selects a track.
      * <p>
-     * If a MediaPlayer is in invalid state, it throws an IllegalStateException exception.
-     * If a MediaPlayer is in <em>Started</em> state, the selected track is presented immediately.
-     * If a MediaPlayer is not in Started state, it just marks the track to be played.
+     * If a MediaPlayer is in invalid state, it throws an IllegalStateException
+     * exception. If a MediaPlayer is in <em>Started</em> state, the selected
+     * track is presented immediately. If a MediaPlayer is not in Started state,
+     * it just marks the track to be played.
      * </p>
      * <p>
-     * In any valid state, if it is called multiple times on the same type of track (ie. Video,
-     * Audio, Timed Text), the most recent one will be chosen.
+     * In any valid state, if it is called multiple times on the same type of
+     * track (ie. Video, Audio, Timed Text), the most recent one will be chosen.
      * </p>
      * <p>
-     * The first audio and video tracks are selected by default if available, even though
-     * this method is not called. However, no timed text track will be selected until
-     * this function is called.
+     * The first audio and video tracks are selected by default if available,
+     * even though this method is not called. However, no timed text track will
+     * be selected until this function is called.
      * </p>
      * <p>
-     * Currently, only timed text tracks or audio tracks can be selected via this method.
-     * In addition, the support for selecting an audio track at runtime is pretty limited
-     * in that an audio track can only be selected in the <em>Prepared</em> state.
+     * Currently, only timed text tracks or audio tracks can be selected via
+     * this method. In addition, the support for selecting an audio track at
+     * runtime is pretty limited in that an audio track can only be selected in
+     * the <em>Prepared</em> state.
      * </p>
-     * @param index the index of the track to be selected. The valid range of the index
-     * is 0..total number of track - 1. The total number of tracks as well as the type of
-     * each individual track can be found by calling {@link #getTrackInfo()} method.
+     * 
+     * @param index the index of the track to be selected. The valid range of
+     *            the index is 0..total number of track - 1. The total number of
+     *            tracks as well as the type of each individual track can be
+     *            found by calling {@link #getTrackInfo()} method.
      * @throws IllegalStateException if called in an invalid state.
-     *
      * @see android.media.MediaPlayer#getTrackInfo
      */
     public void selectTrack(int index) throws IllegalStateException {
@@ -2038,15 +3447,16 @@
     /**
      * Deselect a track.
      * <p>
-     * Currently, the track must be a timed text track and no audio or video tracks can be
-     * deselected. If the timed text track identified by index has not been
-     * selected before, it throws an exception.
+     * Currently, the track must be a timed text track and no audio or video
+     * tracks can be deselected. If the timed text track identified by index has
+     * not been selected before, it throws an exception.
      * </p>
-     * @param index the index of the track to be deselected. The valid range of the index
-     * is 0..total number of tracks - 1. The total number of tracks as well as the type of
-     * each individual track can be found by calling {@link #getTrackInfo()} method.
+     * 
+     * @param index the index of the track to be deselected. The valid range of
+     *            the index is 0..total number of tracks - 1. The total number
+     *            of tracks as well as the type of each individual track can be
+     *            found by calling {@link #getTrackInfo()} method.
      * @throws IllegalStateException if called in an invalid state.
-     *
      * @see android.media.MediaPlayer#getTrackInfo
      */
     public void deselectTrack(int index) throws IllegalStateException {
@@ -2083,7 +3493,7 @@
         Parcel reply = Parcel.obtain();
         try {
             request.writeInterfaceToken(IMEDIA_PLAYER);
-            request.writeInt(select? INVOKE_ID_SELECT_TRACK: INVOKE_ID_DESELECT_TRACK);
+            request.writeInt(select ? INVOKE_ID_SELECT_TRACK : INVOKE_ID_DESELECT_TRACK);
             request.writeInt(index);
             invoke(request, reply);
         } finally {
@@ -2092,41 +3502,33 @@
         }
     }
 
-
     /**
-     * @param reply Parcel with audio/video duration info for battery
-                    tracking usage
-     * @return The status code.
-     * {@hide}
+     * @param reply Parcel with audio/video duration info for battery tracking
+     *            usage
+     * @return The status code. {@hide}
      */
     public native static int native_pullBatteryData(Parcel reply);
 
     /**
      * Sets the target UDP re-transmit endpoint for the low level player.
      * Generally, the address portion of the endpoint is an IP multicast
-     * address, although a unicast address would be equally valid.  When a valid
+     * address, although a unicast address would be equally valid. When a valid
      * retransmit endpoint has been set, the media player will not decode and
-     * render the media presentation locally.  Instead, the player will attempt
+     * render the media presentation locally. Instead, the player will attempt
      * to re-multiplex its media data using the Android@Home RTP profile and
-     * re-transmit to the target endpoint.  Receiver devices (which may be
-     * either the same as the transmitting device or different devices) may
+     * re-transmit to the target endpoint. Receiver devices (which may be either
+     * the same as the transmitting device or different devices) may
      * instantiate, prepare, and start a receiver player using a setDataSource
-     * URL of the form...
-     *
-     * aahRX://&lt;multicastIP&gt;:&lt;port&gt;
-     *
-     * to receive, decode and render the re-transmitted content.
-     *
-     * setRetransmitEndpoint may only be called before setDataSource has been
-     * called; while the player is in the Idle state.
-     *
+     * URL of the form... aahRX://&lt;multicastIP&gt;:&lt;port&gt; to receive,
+     * decode and render the re-transmitted content. setRetransmitEndpoint may
+     * only be called before setDataSource has been called; while the player is
+     * in the Idle state.
+     * 
      * @param endpoint the address and UDP port of the re-transmission target or
-     * null if no re-transmission is to be performed.
+     *            null if no re-transmission is to be performed.
      * @throws IllegalStateException if it is called in an invalid state
      * @throws IllegalArgumentException if the retransmit endpoint is supplied,
-     * but invalid.
-     *
-     * {@hide} pending API council
+     *             but invalid. {@hide} pending API council
      */
     public void setRetransmitEndpoint(InetSocketAddress endpoint)
             throws IllegalStateException, IllegalArgumentException
@@ -2148,10 +3550,13 @@
     private native final int native_setRetransmitEndpoint(String addrString, int port);
 
     @Override
-    protected void finalize() { native_finalize(); }
+    protected void finalize() {
+        native_finalize();
+    }
 
-    /* Do not change these values without updating their counterparts
-     * in include/media/mediaplayer.h!
+    /*
+     * Do not change these values without updating their counterparts in
+     * include/media/mediaplayer.h!
      */
     private static final int MEDIA_NOP = 0; // interface test message
     private static final int MEDIA_PREPARED = 1;
@@ -2193,141 +3598,144 @@
                 Log.w(TAG, "mediaplayer went away with unhandled events");
                 return;
             }
-            switch(msg.what) {
-            case MEDIA_PREPARED:
-                scanInternalSubtitleTracks();
-                if (mOnPreparedListener != null)
-                    mOnPreparedListener.onPrepared(mMediaPlayer);
-                return;
-
-            case MEDIA_PLAYBACK_COMPLETE:
-                if (mOnCompletionListener != null)
-                    mOnCompletionListener.onCompletion(mMediaPlayer);
-                stayAwake(false);
-                return;
+            switch (msg.what) {
+                case MEDIA_PREPARED:
+                    scanInternalSubtitleTracks();
+                    if (mOnPreparedListener != null)
+                        mOnPreparedListener.onPrepared(mMediaPlayer);
+                    return;
 
-            case MEDIA_STOPPED:
-                if (mTimeProvider != null) {
-                    mTimeProvider.onStopped();
-                }
-                break;
+                case MEDIA_PLAYBACK_COMPLETE:
+                    if (mOnCompletionListener != null)
+                        mOnCompletionListener.onCompletion(mMediaPlayer);
+                    stayAwake(false);
+                    return;
 
-            case MEDIA_STARTED:
-            case MEDIA_PAUSED:
-                if (mTimeProvider != null) {
-                    mTimeProvider.onPaused(msg.what == MEDIA_PAUSED);
-                }
-                break;
+                case MEDIA_STOPPED:
+                    if (mTimeProvider != null) {
+                        mTimeProvider.onStopped();
+                    }
+                    break;
 
-            case MEDIA_BUFFERING_UPDATE:
-                if (mOnBufferingUpdateListener != null)
-                    mOnBufferingUpdateListener.onBufferingUpdate(mMediaPlayer, msg.arg1);
-                return;
+                case MEDIA_STARTED:
+                case MEDIA_PAUSED:
+                    if (mTimeProvider != null) {
+                        mTimeProvider.onPaused(msg.what == MEDIA_PAUSED);
+                    }
+                    break;
 
-            case MEDIA_SEEK_COMPLETE:
-              if (mOnSeekCompleteListener != null) {
-                  mOnSeekCompleteListener.onSeekComplete(mMediaPlayer);
-              }
-              // fall through
-
-            case MEDIA_SKIPPED:
-              if (mTimeProvider != null) {
-                  mTimeProvider.onSeekComplete(mMediaPlayer);
-              }
-              return;
-
-            case MEDIA_SET_VIDEO_SIZE:
-              if (mOnVideoSizeChangedListener != null)
-                  mOnVideoSizeChangedListener.onVideoSizeChanged(mMediaPlayer, msg.arg1, msg.arg2);
-              return;
-
-            case MEDIA_ERROR:
-                Log.e(TAG, "Error (" + msg.arg1 + "," + msg.arg2 + ")");
-                boolean error_was_handled = false;
-                if (mOnErrorListener != null) {
-                    error_was_handled = mOnErrorListener.onError(mMediaPlayer, msg.arg1, msg.arg2);
-                }
-                if (mOnCompletionListener != null && ! error_was_handled) {
-                    mOnCompletionListener.onCompletion(mMediaPlayer);
-                }
-                stayAwake(false);
-                return;
+                case MEDIA_BUFFERING_UPDATE:
+                    if (mOnBufferingUpdateListener != null)
+                        mOnBufferingUpdateListener.onBufferingUpdate(mMediaPlayer, msg.arg1);
+                    return;
 
-            case MEDIA_INFO:
-                switch (msg.arg1) {
-                case MEDIA_INFO_VIDEO_TRACK_LAGGING:
-                    Log.i(TAG, "Info (" + msg.arg1 + "," + msg.arg2 + ")");
-                    break;
-                case MEDIA_INFO_METADATA_UPDATE:
-                    scanInternalSubtitleTracks();
+                case MEDIA_SEEK_COMPLETE:
+                    if (mOnSeekCompleteListener != null) {
+                        mOnSeekCompleteListener.onSeekComplete(mMediaPlayer);
+                    }
                     // fall through
 
-                case MEDIA_INFO_EXTERNAL_METADATA_UPDATE:
-                    msg.arg1 = MEDIA_INFO_METADATA_UPDATE;
-                    // update default track selection
-                    mSubtitleController.selectDefaultTrack();
-                    break;
-                }
+                case MEDIA_SKIPPED:
+                    if (mTimeProvider != null) {
+                        mTimeProvider.onSeekComplete(mMediaPlayer);
+                    }
+                    return;
 
-                if (mOnInfoListener != null) {
-                    mOnInfoListener.onInfo(mMediaPlayer, msg.arg1, msg.arg2);
-                }
-                // No real default action so far.
-                return;
-            case MEDIA_TIMED_TEXT:
-                if (mOnTimedTextListener == null)
+                case MEDIA_SET_VIDEO_SIZE:
+                    if (mOnVideoSizeChangedListener != null)
+                        mOnVideoSizeChangedListener.onVideoSizeChanged(mMediaPlayer, msg.arg1,
+                                msg.arg2);
                     return;
-                if (msg.obj == null) {
-                    mOnTimedTextListener.onTimedText(mMediaPlayer, null);
-                } else {
+
+                case MEDIA_ERROR:
+                    Log.e(TAG, "Error (" + msg.arg1 + "," + msg.arg2 + ")");
+                    boolean error_was_handled = false;
+                    if (mOnErrorListener != null) {
+                        error_was_handled = mOnErrorListener.onError(mMediaPlayer, msg.arg1,
+                                msg.arg2);
+                    }
+                    if (mOnCompletionListener != null && !error_was_handled) {
+                        mOnCompletionListener.onCompletion(mMediaPlayer);
+                    }
+                    stayAwake(false);
+                    return;
+
+                case MEDIA_INFO:
+                    switch (msg.arg1) {
+                        case MEDIA_INFO_VIDEO_TRACK_LAGGING:
+                            Log.i(TAG, "Info (" + msg.arg1 + "," + msg.arg2 + ")");
+                            break;
+                        case MEDIA_INFO_METADATA_UPDATE:
+                            scanInternalSubtitleTracks();
+                            // fall through
+
+                        case MEDIA_INFO_EXTERNAL_METADATA_UPDATE:
+                            msg.arg1 = MEDIA_INFO_METADATA_UPDATE;
+                            // update default track selection
+                            mSubtitleController.selectDefaultTrack();
+                            break;
+                    }
+
+                    if (mOnInfoListener != null) {
+                        mOnInfoListener.onInfo(mMediaPlayer, msg.arg1, msg.arg2);
+                    }
+                    // No real default action so far.
+                    return;
+                case MEDIA_TIMED_TEXT:
+                    if (mOnTimedTextListener == null)
+                        return;
+                    if (msg.obj == null) {
+                        mOnTimedTextListener.onTimedText(mMediaPlayer, null);
+                    } else {
+                        if (msg.obj instanceof Parcel) {
+                            Parcel parcel = (Parcel) msg.obj;
+                            TimedText text = new TimedText(parcel);
+                            parcel.recycle();
+                            mOnTimedTextListener.onTimedText(mMediaPlayer, text);
+                        }
+                    }
+                    return;
+
+                case MEDIA_SUBTITLE_DATA:
+                    if (mOnSubtitleDataListener == null) {
+                        return;
+                    }
                     if (msg.obj instanceof Parcel) {
-                        Parcel parcel = (Parcel)msg.obj;
-                        TimedText text = new TimedText(parcel);
+                        Parcel parcel = (Parcel) msg.obj;
+                        SubtitleData data = new SubtitleData(parcel);
                         parcel.recycle();
-                        mOnTimedTextListener.onTimedText(mMediaPlayer, text);
+                        mOnSubtitleDataListener.onSubtitleData(mMediaPlayer, data);
                     }
-                }
-                return;
-
-            case MEDIA_SUBTITLE_DATA:
-                if (mOnSubtitleDataListener == null) {
                     return;
-                }
-                if (msg.obj instanceof Parcel) {
-                    Parcel parcel = (Parcel) msg.obj;
-                    SubtitleData data = new SubtitleData(parcel);
-                    parcel.recycle();
-                    mOnSubtitleDataListener.onSubtitleData(mMediaPlayer, data);
-                }
-                return;
 
-            case MEDIA_NOP: // interface test message - ignore
-                break;
+                case MEDIA_NOP: // interface test message - ignore
+                    break;
 
-            default:
-                Log.e(TAG, "Unknown message type " + msg.what);
-                return;
+                default:
+                    Log.e(TAG, "Unknown message type " + msg.what);
+                    return;
             }
         }
     }
 
     /*
-     * Called from native code when an interesting event happens.  This method
-     * just uses the EventHandler system to post the event back to the main app thread.
-     * We use a weak reference to the original MediaPlayer object so that the native
-     * code is safe from the object disappearing from underneath it.  (This is
-     * the cookie passed to native_setup().)
+     * Called from native code when an interesting event happens. This method
+     * just uses the EventHandler system to post the event back to the main app
+     * thread. We use a weak reference to the original MediaPlayer object so
+     * that the native code is safe from the object disappearing from underneath
+     * it. (This is the cookie passed to native_setup().)
      */
     private static void postEventFromNative(Object mediaplayer_ref,
-                                            int what, int arg1, int arg2, Object obj)
+            int what, int arg1, int arg2, Object obj)
     {
-        MediaPlayer mp = (MediaPlayer)((WeakReference)mediaplayer_ref).get();
+        MediaPlayer mp = (MediaPlayer) ((WeakReference) mediaplayer_ref).get();
         if (mp == null) {
             return;
         }
 
         if (what == MEDIA_INFO && arg1 == MEDIA_INFO_STARTED_AS_NEXT) {
-            // this acquires the wakelock if needed, and sets the client side state
+            // this acquires the wakelock if needed, and sets the client side
+            // state
             mp.start();
         }
         if (mp.mEventHandler != null) {
@@ -2337,23 +3745,23 @@
     }
 
     /**
-     * Interface definition for a callback to be invoked when the media
-     * source is ready for playback.
+     * Interface definition for a callback to be invoked when the media source
+     * is ready for playback.
      */
     public interface OnPreparedListener
     {
         /**
          * Called when the media file is ready for playback.
-         *
+         * 
          * @param mp the MediaPlayer that is ready for playback
          */
         void onPrepared(MediaPlayer mp);
     }
 
     /**
-     * Register a callback to be invoked when the media source is ready
-     * for playback.
-     *
+     * Register a callback to be invoked when the media source is ready for
+     * playback.
+     * 
      * @param listener the callback that will be run
      */
     public void setOnPreparedListener(OnPreparedListener listener)
@@ -2364,23 +3772,23 @@
     private OnPreparedListener mOnPreparedListener;
 
     /**
-     * Interface definition for a callback to be invoked when playback of
-     * a media source has completed.
+     * Interface definition for a callback to be invoked when playback of a
+     * media source has completed.
      */
     public interface OnCompletionListener
     {
         /**
          * Called when the end of a media source is reached during playback.
-         *
+         * 
          * @param mp the MediaPlayer that reached the end of the file
          */
         void onCompletion(MediaPlayer mp);
     }
 
     /**
-     * Register a callback to be invoked when the end of a media source
-     * has been reached during playback.
-     *
+     * Register a callback to be invoked when the end of a media source has been
+     * reached during playback.
+     * 
      * @param listener the callback that will be run
      */
     public void setOnCompletionListener(OnCompletionListener listener)
@@ -2399,22 +3807,22 @@
         /**
          * Called to update status in buffering a media stream received through
          * progressive HTTP download. The received buffering percentage
-         * indicates how much of the content has been buffered or played.
-         * For example a buffering update of 80 percent when half the content
-         * has already been played indicates that the next 30 percent of the
-         * content to play has been buffered.
-         *
-         * @param mp      the MediaPlayer the update pertains to
-         * @param percent the percentage (0-100) of the content
-         *                that has been buffered or played thus far
+         * indicates how much of the content has been buffered or played. For
+         * example a buffering update of 80 percent when half the content has
+         * already been played indicates that the next 30 percent of the content
+         * to play has been buffered.
+         * 
+         * @param mp the MediaPlayer the update pertains to
+         * @param percent the percentage (0-100) of the content that has been
+         *            buffered or played thus far
          */
         void onBufferingUpdate(MediaPlayer mp, int percent);
     }
 
     /**
-     * Register a callback to be invoked when the status of a network
-     * stream's buffer has changed.
-     *
+     * Register a callback to be invoked when the status of a network stream's
+     * buffer has changed.
+     * 
      * @param listener the callback that will be run.
      */
     public void setOnBufferingUpdateListener(OnBufferingUpdateListener listener)
@@ -2425,14 +3833,14 @@
     private OnBufferingUpdateListener mOnBufferingUpdateListener;
 
     /**
-     * Interface definition of a callback to be invoked indicating
-     * the completion of a seek operation.
+     * Interface definition of a callback to be invoked indicating the
+     * completion of a seek operation.
      */
     public interface OnSeekCompleteListener
     {
         /**
          * Called to indicate the completion of a seek operation.
-         *
+         * 
          * @param mp the MediaPlayer that issued the seek operation
          */
         public void onSeekComplete(MediaPlayer mp);
@@ -2441,7 +3849,7 @@
     /**
      * Register a callback to be invoked when a seek operation has been
      * completed.
-     *
+     * 
      * @param listener the callback that will be run
      */
     public void setOnSeekCompleteListener(OnSeekCompleteListener listener)
@@ -2452,28 +3860,27 @@
     private OnSeekCompleteListener mOnSeekCompleteListener;
 
     /**
-     * Interface definition of a callback to be invoked when the
-     * video size is first known or updated
+     * Interface definition of a callback to be invoked when the video size is
+     * first known or updated
      */
     public interface OnVideoSizeChangedListener
     {
         /**
-         * Called to indicate the video size
-         *
-         * The video size (width and height) could be 0 if there was no video,
-         * no display surface was set, or the value was not determined yet.
-         *
-         * @param mp        the MediaPlayer associated with this callback
-         * @param width     the width of the video
-         * @param height    the height of the video
+         * Called to indicate the video size The video size (width and height)
+         * could be 0 if there was no video, no display surface was set, or the
+         * value was not determined yet.
+         * 
+         * @param mp the MediaPlayer associated with this callback
+         * @param width the width of the video
+         * @param height the height of the video
          */
         public void onVideoSizeChanged(MediaPlayer mp, int width, int height);
     }
 
     /**
-     * Register a callback to be invoked when the video size is
-     * known or updated.
-     *
+     * Register a callback to be invoked when the video size is known or
+     * updated.
+     * 
      * @param listener the callback that will be run
      */
     public void setOnVideoSizeChangedListener(OnVideoSizeChangedListener listener)
@@ -2484,25 +3891,25 @@
     private OnVideoSizeChangedListener mOnVideoSizeChangedListener;
 
     /**
-     * Interface definition of a callback to be invoked when a
-     * timed text is available for display.
+     * Interface definition of a callback to be invoked when a timed text is
+     * available for display.
      */
     public interface OnTimedTextListener
     {
         /**
          * Called to indicate an avaliable timed text
-         *
-         * @param mp             the MediaPlayer associated with this callback
-         * @param text           the timed text sample which contains the text
-         *                       needed to be displayed and the display format.
+         * 
+         * @param mp the MediaPlayer associated with this callback
+         * @param text the timed text sample which contains the text needed to
+         *            be displayed and the display format.
          */
         public void onTimedText(MediaPlayer mp, TimedText text);
     }
 
     /**
-     * Register a callback to be invoked when a timed text is available
-     * for display.
-     *
+     * Register a callback to be invoked when a timed text is available for
+     * display.
+     * 
      * @param listener the callback that will be run
      */
     public void setOnTimedTextListener(OnTimedTextListener listener)
@@ -2513,9 +3920,9 @@
     private OnTimedTextListener mOnTimedTextListener;
 
     /**
-     * Interface definition of a callback to be invoked when a
-     * track has data available.
-     *
+     * Interface definition of a callback to be invoked when a track has data
+     * available.
+     * 
      * @hide
      */
     public interface OnSubtitleDataListener
@@ -2525,9 +3932,8 @@
 
     /**
      * Register a callback to be invoked when a track has data available.
-     *
+     * 
      * @param listener the callback that will be run
-     *
      * @hide
      */
     public void setOnSubtitleDataListener(OnSubtitleDataListener listener)
@@ -2537,23 +3943,30 @@
 
     private OnSubtitleDataListener mOnSubtitleDataListener;
 
-    /* Do not change these values without updating their counterparts
-     * in include/media/mediaplayer.h!
+    /*
+     * Do not change these values without updating their counterparts in
+     * include/media/mediaplayer.h!
      */
-    /** Unspecified media player error.
+    /**
+     * Unspecified media player error.
+     * 
      * @see android.media.MediaPlayer.OnErrorListener
      */
     public static final int MEDIA_ERROR_UNKNOWN = 1;
 
-    /** Media server died. In this case, the application must release the
+    /**
+     * Media server died. In this case, the application must release the
      * MediaPlayer object and instantiate a new one.
+     * 
      * @see android.media.MediaPlayer.OnErrorListener
      */
     public static final int MEDIA_ERROR_SERVER_DIED = 100;
 
-    /** The video is streamed and its container is not valid for progressive
+    /**
+     * The video is streamed and its container is not valid for progressive
      * playback i.e the video's index (e.g moov atom) is not at the start of the
      * file.
+     * 
      * @see android.media.MediaPlayer.OnErrorListener
      */
     public static final int MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK = 200;
@@ -2562,47 +3975,51 @@
     public static final int MEDIA_ERROR_IO = -1004;
     /** Bitstream is not conforming to the related coding standard or file spec. */
     public static final int MEDIA_ERROR_MALFORMED = -1007;
-    /** Bitstream is conforming to the related coding standard or file spec, but
-     * the media framework does not support the feature. */
+    /**
+     * Bitstream is conforming to the related coding standard or file spec, but
+     * the media framework does not support the feature.
+     */
     public static final int MEDIA_ERROR_UNSUPPORTED = -1010;
-    /** Some operation takes too long to complete, usually more than 3-5 seconds. */
+    /**
+     * Some operation takes too long to complete, usually more than 3-5 seconds.
+     */
     public static final int MEDIA_ERROR_TIMED_OUT = -110;
 
     /**
-     * Interface definition of a callback to be invoked when there
-     * has been an error during an asynchronous operation (other errors
-     * will throw exceptions at method call time).
+     * Interface definition of a callback to be invoked when there has been an
+     * error during an asynchronous operation (other errors will throw
+     * exceptions at method call time).
      */
     public interface OnErrorListener
     {
         /**
          * Called to indicate an error.
-         *
-         * @param mp      the MediaPlayer the error pertains to
-         * @param what    the type of error that has occurred:
-         * <ul>
-         * <li>{@link #MEDIA_ERROR_UNKNOWN}
-         * <li>{@link #MEDIA_ERROR_SERVER_DIED}
-         * </ul>
+         * 
+         * @param mp the MediaPlayer the error pertains to
+         * @param what the type of error that has occurred:
+         *            <ul>
+         *            <li>{@link #MEDIA_ERROR_UNKNOWN}
+         *            <li>{@link #MEDIA_ERROR_SERVER_DIED}
+         *            </ul>
          * @param extra an extra code, specific to the error. Typically
-         * implementation dependent.
-         * <ul>
-         * <li>{@link #MEDIA_ERROR_IO}
-         * <li>{@link #MEDIA_ERROR_MALFORMED}
-         * <li>{@link #MEDIA_ERROR_UNSUPPORTED}
-         * <li>{@link #MEDIA_ERROR_TIMED_OUT}
-         * </ul>
+         *            implementation dependent.
+         *            <ul>
+         *            <li>{@link #MEDIA_ERROR_IO}
+         *            <li>{@link #MEDIA_ERROR_MALFORMED}
+         *            <li>{@link #MEDIA_ERROR_UNSUPPORTED}
+         *            <li>{@link #MEDIA_ERROR_TIMED_OUT}
+         *            </ul>
          * @return True if the method handled the error, false if it didn't.
-         * Returning false, or not having an OnErrorListener at all, will
-         * cause the OnCompletionListener to be called.
+         *         Returning false, or not having an OnErrorListener at all,
+         *         will cause the OnCompletionListener to be called.
          */
         boolean onError(MediaPlayer mp, int what, int extra);
     }
 
     /**
-     * Register a callback to be invoked when an error has happened
-     * during an asynchronous operation.
-     *
+     * Register a callback to be invoked when an error has happened during an
+     * asynchronous operation.
+     * 
      * @param listener the callback that will be run
      */
     public void setOnErrorListener(OnErrorListener listener)
@@ -2612,119 +4029,143 @@
 
     private OnErrorListener mOnErrorListener;
 
-
-    /* Do not change these values without updating their counterparts
-     * in include/media/mediaplayer.h!
+    /*
+     * Do not change these values without updating their counterparts in
+     * include/media/mediaplayer.h!
      */
-    /** Unspecified media player info.
+    /**
+     * Unspecified media player info.
+     * 
      * @see android.media.MediaPlayer.OnInfoListener
      */
     public static final int MEDIA_INFO_UNKNOWN = 1;
 
-    /** The player was started because it was used as the next player for another
+    /**
+     * The player was started because it was used as the next player for another
      * player, which just completed playback.
+     * 
      * @see android.media.MediaPlayer.OnInfoListener
      * @hide
      */
     public static final int MEDIA_INFO_STARTED_AS_NEXT = 2;
 
-    /** The player just pushed the very first video frame for rendering.
+    /**
+     * The player just pushed the very first video frame for rendering.
+     * 
      * @see android.media.MediaPlayer.OnInfoListener
      */
     public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3;
 
-    /** The video is too complex for the decoder: it can't decode frames fast
-     *  enough. Possibly only the audio plays fine at this stage.
+    /**
+     * The video is too complex for the decoder: it can't decode frames fast
+     * enough. Possibly only the audio plays fine at this stage.
+     * 
      * @see android.media.MediaPlayer.OnInfoListener
      */
     public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700;
 
-    /** MediaPlayer is temporarily pausing playback internally in order to
-     * buffer more data.
+    /**
+     * MediaPlayer is temporarily pausing playback internally in order to buffer
+     * more data.
+     * 
      * @see android.media.MediaPlayer.OnInfoListener
      */
     public static final int MEDIA_INFO_BUFFERING_START = 701;
 
-    /** MediaPlayer is resuming playback after filling buffers.
+    /**
+     * MediaPlayer is resuming playback after filling buffers.
+     * 
      * @see android.media.MediaPlayer.OnInfoListener
      */
     public static final int MEDIA_INFO_BUFFERING_END = 702;
 
-    /** Bad interleaving means that a media has been improperly interleaved or
+    /**
+     * Bad interleaving means that a media has been improperly interleaved or
      * not interleaved at all, e.g has all the video samples first then all the
      * audio ones. Video is playing but a lot of disk seeks may be happening.
+     * 
      * @see android.media.MediaPlayer.OnInfoListener
      */
     public static final int MEDIA_INFO_BAD_INTERLEAVING = 800;
 
-    /** The media cannot be seeked (e.g live stream)
+    /**
+     * The media cannot be seeked (e.g live stream)
+     * 
      * @see android.media.MediaPlayer.OnInfoListener
      */
     public static final int MEDIA_INFO_NOT_SEEKABLE = 801;
 
-    /** A new set of metadata is available.
+    /**
+     * A new set of metadata is available.
+     * 
      * @see android.media.MediaPlayer.OnInfoListener
      */
     public static final int MEDIA_INFO_METADATA_UPDATE = 802;
 
-    /** A new set of external-only metadata is available.  Used by
-     *  JAVA framework to avoid triggering track scanning.
+    /**
+     * A new set of external-only metadata is available. Used by JAVA framework
+     * to avoid triggering track scanning.
+     * 
      * @hide
      */
     public static final int MEDIA_INFO_EXTERNAL_METADATA_UPDATE = 803;
 
-    /** Failed to handle timed text track properly.
-     * @see android.media.MediaPlayer.OnInfoListener
-     *
-     * {@hide}
+    /**
+     * Failed to handle timed text track properly.
+     * 
+     * @see android.media.MediaPlayer.OnInfoListener {@hide}
      */
     public static final int MEDIA_INFO_TIMED_TEXT_ERROR = 900;
 
-    /** Subtitle track was not supported by the media framework.
+    /**
+     * Subtitle track was not supported by the media framework.
+     * 
      * @see android.media.MediaPlayer.OnInfoListener
      */
     public static final int MEDIA_INFO_UNSUPPORTED_SUBTITLE = 901;
 
-    /** Reading the subtitle track takes too long.
+    /**
+     * Reading the subtitle track takes too long.
+     * 
      * @see android.media.MediaPlayer.OnInfoListener
      */
     public static final int MEDIA_INFO_SUBTITLE_TIMED_OUT = 902;
 
     /**
-     * Interface definition of a callback to be invoked to communicate some
-     * info and/or warning about the media or its playback.
+     * Interface definition of a callback to be invoked to communicate some info
+     * and/or warning about the media or its playback.
      */
     public interface OnInfoListener
     {
         /**
          * Called to indicate an info or a warning.
-         *
-         * @param mp      the MediaPlayer the info pertains to.
-         * @param what    the type of info or warning.
-         * <ul>
-         * <li>{@link #MEDIA_INFO_UNKNOWN}
-         * <li>{@link #MEDIA_INFO_VIDEO_TRACK_LAGGING}
-         * <li>{@link #MEDIA_INFO_VIDEO_RENDERING_START}
-         * <li>{@link #MEDIA_INFO_BUFFERING_START}
-         * <li>{@link #MEDIA_INFO_BUFFERING_END}
-         * <li>{@link #MEDIA_INFO_BAD_INTERLEAVING}
-         * <li>{@link #MEDIA_INFO_NOT_SEEKABLE}
-         * <li>{@link #MEDIA_INFO_METADATA_UPDATE}
-         * <li>{@link #MEDIA_INFO_UNSUPPORTED_SUBTITLE}
-         * <li>{@link #MEDIA_INFO_SUBTITLE_TIMED_OUT}
-         * </ul>
+         * 
+         * @param mp the MediaPlayer the info pertains to.
+         * @param what the type of info or warning.
+         *            <ul>
+         *            <li>{@link #MEDIA_INFO_UNKNOWN}
+         *            <li>{@link #MEDIA_INFO_VIDEO_TRACK_LAGGING}
+         *            <li>{@link #MEDIA_INFO_VIDEO_RENDERING_START}
+         *            <li>{@link #MEDIA_INFO_BUFFERING_START}
+         *            <li>{@link #MEDIA_INFO_BUFFERING_END}
+         *            <li>{@link #MEDIA_INFO_BAD_INTERLEAVING}
+         *            <li>{@link #MEDIA_INFO_NOT_SEEKABLE}
+         *            <li>{@link #MEDIA_INFO_METADATA_UPDATE}
+         *            <li>{@link #MEDIA_INFO_UNSUPPORTED_SUBTITLE}
+         *            <li>{@link #MEDIA_INFO_SUBTITLE_TIMED_OUT}
+         *            </ul>
          * @param extra an extra code, specific to the info. Typically
-         * implementation dependent.
+         *            implementation dependent.
          * @return True if the method handled the info, false if it didn't.
-         * Returning false, or not having an OnErrorListener at all, will
-         * cause the info to be discarded.
+         *         Returning false, or not having an OnErrorListener at all,
+         *         will cause the info to be discarded.
          */
         boolean onInfo(MediaPlayer mp, int what, int extra);
     }
 
     /**
      * Register a callback to be invoked when an info/warning is available.
-     *
+     * 
      * @param listener the callback that will be run
      */
     public void setOnInfoListener(OnInfoListener listener)
@@ -2738,8 +4179,7 @@
      * Test whether a given video scaling mode is supported.
      */
     private boolean isVideoScalingModeSupported(int mode) {
-        return (mode == VIDEO_SCALING_MODE_SCALE_TO_FIT ||
-                mode == VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
+        return (mode == VIDEO_SCALING_MODE_SCALE_TO_FIT || mode == VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
     }
 
     private Context mProxyContext = null;
@@ -2752,7 +4192,7 @@
         mProxyContext = context;
 
         Intent currentProxy =
-            context.getApplicationContext().registerReceiver(mProxyReceiver, filter);
+                context.getApplicationContext().registerReceiver(mProxyReceiver, filter);
 
         if (currentProxy != null) {
             handleProxyBroadcast(currentProxy);
@@ -2775,7 +4215,7 @@
 
     private void handleProxyBroadcast(Intent intent) {
         ProxyProperties props =
-            (ProxyProperties)intent.getExtra(Proxy.EXTRA_PROXY_INFO);
+                (ProxyProperties) intent.getExtra(Proxy.EXTRA_PROXY_INFO);
 
         if (props == null || props.getHost() == null) {
             updateProxyConfig(null);
@@ -2801,7 +4241,7 @@
         private static final String TAG = "MTP";
         private static final long MAX_NS_WITHOUT_POSITION_CHECK = 5000000000L;
         private static final long MAX_EARLY_CALLBACK_US = 1000;
-        private static final long TIME_ADJUSTMENT_RATE = 2;  /* meaning 1/2 */
+        private static final long TIME_ADJUSTMENT_RATE = 2; /* meaning 1/2 */
         private long mLastTimeUs = 0;
         private MediaPlayer mPlayer;
         private boolean mPaused = true;
@@ -2838,10 +4278,10 @@
 
             Looper looper;
             if ((looper = Looper.myLooper()) == null &&
-                (looper = Looper.getMainLooper()) == null) {
+                    (looper = Looper.getMainLooper()) == null) {
                 // Create our own looper here in case MP was created without one
                 mHandlerThread = new HandlerThread("MediaPlayerMTPEventThread",
-                      Process.THREAD_PRIORITY_FOREGROUND);
+                        Process.THREAD_PRIORITY_FOREGROUND);
                 mHandlerThread.start();
                 looper = mHandlerThread.getLooper();
             }
@@ -2860,7 +4300,8 @@
                 return;
             }
 
-            if (DEBUG) Log.v(TAG, "scheduleNotification " + type + " in " + delayUs);
+            if (DEBUG)
+                Log.v(TAG, "scheduleNotification " + type + " in " + delayUs);
             mEventHandler.removeMessages(NOTIFY);
             Message msg = mEventHandler.obtainMessage(NOTIFY, type, 0);
             mEventHandler.sendMessageDelayed(msg, (int) (delayUs / 1000));
@@ -2884,14 +4325,15 @@
 
         /** @hide */
         public void onPaused(boolean paused) {
-            synchronized(this) {
-                if (DEBUG) Log.d(TAG, "onPaused: " + paused);
+            synchronized (this) {
+                if (DEBUG)
+                    Log.d(TAG, "onPaused: " + paused);
                 if (mStopped) { // handle as seek if we were stopped
                     mStopped = false;
                     mSeeking = true;
                     scheduleNotification(NOTIFY_SEEK, 0 /* delay */);
                 } else {
-                    mPausing = paused;  // special handling if player disappeared
+                    mPausing = paused; // special handling if player disappeared
                     mSeeking = false;
                     scheduleNotification(REFRESH_AND_NOTIFY_TIME, 0 /* delay */);
                 }
@@ -2900,8 +4342,9 @@
 
         /** @hide */
         public void onStopped() {
-            synchronized(this) {
-                if (DEBUG) Log.d(TAG, "onStopped");
+            synchronized (this) {
+                if (DEBUG)
+                    Log.d(TAG, "onStopped");
                 mPaused = true;
                 mStopped = true;
                 mSeeking = false;
@@ -2912,7 +4355,7 @@
         /** @hide */
         @Override
         public void onSeekComplete(MediaPlayer mp) {
-            synchronized(this) {
+            synchronized (this) {
                 mStopped = false;
                 mSeeking = true;
                 scheduleNotification(NOTIFY_SEEK, 0 /* delay */);
@@ -2922,7 +4365,7 @@
         /** @hide */
         public void onNewPlayer() {
             if (mRefresh) {
-                synchronized(this) {
+                synchronized (this) {
                     mStopped = false;
                     mSeeking = true;
                     scheduleNotification(NOTIFY_SEEK, 0 /* delay */);
@@ -2934,9 +4377,10 @@
             mSeeking = false;
             try {
                 long timeUs = getCurrentTimeUs(true, false);
-                if (DEBUG) Log.d(TAG, "onSeekComplete at " + timeUs);
+                if (DEBUG)
+                    Log.d(TAG, "onSeekComplete at " + timeUs);
 
-                for (MediaTimeProvider.OnMediaTimeListener listener: mListeners) {
+                for (MediaTimeProvider.OnMediaTimeListener listener : mListeners) {
                     if (listener == null) {
                         break;
                     }
@@ -2944,14 +4388,15 @@
                 }
             } catch (IllegalStateException e) {
                 // we should not be there, but at least signal pause
-                if (DEBUG) Log.d(TAG, "onSeekComplete but no player");
-                mPausing = true;  // special handling if player disappeared
+                if (DEBUG)
+                    Log.d(TAG, "onSeekComplete but no player");
+                mPausing = true; // special handling if player disappeared
                 notifyTimedEvent(false /* refreshTime */);
             }
         }
 
         private synchronized void notifyStop() {
-            for (MediaTimeProvider.OnMediaTimeListener listener: mListeners) {
+            for (MediaTimeProvider.OnMediaTimeListener listener : mListeners) {
                 if (listener == null) {
                     break;
                 }
@@ -2970,7 +4415,7 @@
             // new listener
             if (i >= mListeners.length) {
                 MediaTimeProvider.OnMediaTimeListener[] newListeners =
-                    new MediaTimeProvider.OnMediaTimeListener[i + 1];
+                        new MediaTimeProvider.OnMediaTimeListener[i + 1];
                 long[] newTimes = new long[i + 1];
                 System.arraycopy(mListeners, 0, newListeners, 0, mListeners.length);
                 System.arraycopy(mTimes, 0, newTimes, 0, mTimes.length);
@@ -2987,16 +4432,18 @@
 
         public void notifyAt(
                 long timeUs, MediaTimeProvider.OnMediaTimeListener listener) {
-            synchronized(this) {
-                if (DEBUG) Log.d(TAG, "notifyAt " + timeUs);
+            synchronized (this) {
+                if (DEBUG)
+                    Log.d(TAG, "notifyAt " + timeUs);
                 mTimes[registerListener(listener)] = timeUs;
                 scheduleNotification(NOTIFY_TIME, 0 /* delay */);
             }
         }
 
         public void scheduleUpdate(MediaTimeProvider.OnMediaTimeListener listener) {
-            synchronized(this) {
-                if (DEBUG) Log.d(TAG, "scheduleUpdate");
+            synchronized (this) {
+                if (DEBUG)
+                    Log.d(TAG, "scheduleUpdate");
                 int i = registerListener(listener);
 
                 if (mStopped) {
@@ -3010,7 +4457,7 @@
 
         public void cancelNotifications(
                 MediaTimeProvider.OnMediaTimeListener listener) {
-            synchronized(this) {
+            synchronized (this) {
                 int i = 0;
                 for (; i < mListeners.length; i++) {
                     if (mListeners[i] == listener) {
@@ -3053,11 +4500,12 @@
                 sb.append("notifyTimedEvent(").append(mLastTimeUs).append(" -> ")
                         .append(nowUs).append(") from {");
                 boolean first = true;
-                for (long time: mTimes) {
+                for (long time : mTimes) {
                     if (time == NO_TIME) {
                         continue;
                     }
-                    if (!first) sb.append(", ");
+                    if (!first)
+                        sb.append(", ");
                     sb.append(time);
                     first = false;
                 }
@@ -3066,7 +4514,7 @@
             }
 
             Vector<MediaTimeProvider.OnMediaTimeListener> activatedListeners =
-                new Vector<MediaTimeProvider.OnMediaTimeListener>();
+                    new Vector<MediaTimeProvider.OnMediaTimeListener>();
             for (int ix = 0; ix < mTimes.length; ix++) {
                 if (mListeners[ix] == null) {
                     break;
@@ -3075,7 +4523,8 @@
                     // ignore, unless we were stopped
                 } else if (mTimes[ix] <= nowUs + MAX_EARLY_CALLBACK_US) {
                     activatedListeners.add(mListeners[ix]);
-                    if (DEBUG) Log.d(TAG, "removed");
+                    if (DEBUG)
+                        Log.d(TAG, "removed");
                     mTimes[ix] = NO_TIME;
                 } else if (nextTimeUs == nowUs || mTimes[ix] < nextTimeUs) {
                     nextTimeUs = mTimes[ix];
@@ -3084,14 +4533,15 @@
 
             if (nextTimeUs > nowUs && !mPaused) {
                 // schedule callback at nextTimeUs
-                if (DEBUG) Log.d(TAG, "scheduling for " + nextTimeUs + " and " + nowUs);
+                if (DEBUG)
+                    Log.d(TAG, "scheduling for " + nextTimeUs + " and " + nowUs);
                 scheduleNotification(NOTIFY_TIME, nextTimeUs - nowUs);
             } else {
                 mEventHandler.removeMessages(NOTIFY);
                 // no more callbacks
             }
 
-            for (MediaTimeProvider.OnMediaTimeListener listener: activatedListeners) {
+            for (MediaTimeProvider.OnMediaTimeListener listener : activatedListeners) {
                 listener.onTimedEvent(nowUs);
             }
         }
@@ -3104,7 +4554,7 @@
                 mLastReportedTime = mLastTimeUs + timeSinceRead;
                 if (mTimeAdjustment > 0) {
                     long adjustment =
-                        mTimeAdjustment - timeSinceRead / TIME_ADJUSTMENT_RATE;
+                            mTimeAdjustment - timeSinceRead / TIME_ADJUSTMENT_RATE;
                     if (adjustment <= 0) {
                         mTimeAdjustment = 0;
                     } else {
@@ -3118,7 +4568,8 @@
         public long getCurrentTimeUs(boolean refreshTime, boolean monotonic)
                 throws IllegalStateException {
             synchronized (this) {
-                // we always refresh the time when the paused-state changes, because
+                // we always refresh the time when the paused-state changes,
+                // because
                 // we expect to have received the pause-change event delayed.
                 if (mPaused && !refreshTime) {
                     return mLastReportedTime;
@@ -3130,14 +4581,17 @@
                     try {
                         mLastTimeUs = mPlayer.getCurrentPosition() * 1000L;
                         mPaused = !mPlayer.isPlaying();
-                        if (DEBUG) Log.v(TAG, (mPaused ? "paused" : "playing") + " at " + mLastTimeUs);
+                        if (DEBUG)
+                            Log.v(TAG, (mPaused ? "paused" : "playing") + " at " + mLastTimeUs);
                     } catch (IllegalStateException e) {
                         if (mPausing) {
                             // if we were pausing, get last estimated timestamp
                             mPausing = false;
                             getEstimatedTime(nanoTime, monotonic);
                             mPaused = true;
-                            if (DEBUG) Log.d(TAG, "illegal state, but pausing: estimating at " + mLastReportedTime);
+                            if (DEBUG)
+                                Log.d(TAG, "illegal state, but pausing: estimating at "
+                                        + mLastReportedTime);
                             return mLastReportedTime;
                         }
                         // TODO get time when prepared
@@ -3148,8 +4602,10 @@
                         /* have to adjust time */
                         mTimeAdjustment = mLastReportedTime - mLastTimeUs;
                         if (mTimeAdjustment > 1000000) {
-                            // schedule seeked event if time jumped significantly
-                            // TODO: do this properly by introducing an exception
+                            // schedule seeked event if time jumped
+                            // significantly
+                            // TODO: do this properly by introducing an
+                            // exception
                             mStopped = false;
                             mSeeking = true;
                             scheduleNotification(NOTIFY_SEEK, 0 /* delay */);
@@ -3172,18 +4628,18 @@
             public void handleMessage(Message msg) {
                 if (msg.what == NOTIFY) {
                     switch (msg.arg1) {
-                    case NOTIFY_TIME:
-                        notifyTimedEvent(false /* refreshTime */);
-                        break;
-                    case REFRESH_AND_NOTIFY_TIME:
-                        notifyTimedEvent(true /* refreshTime */);
-                        break;
-                    case NOTIFY_STOP:
-                        notifyStop();
-                        break;
-                    case NOTIFY_SEEK:
-                        notifySeek();
-                        break;
+                        case NOTIFY_TIME:
+                            notifyTimedEvent(false /* refreshTime */);
+                            break;
+                        case REFRESH_AND_NOTIFY_TIME:
+                            notifyTimedEvent(true /* refreshTime */);
+                            break;
+                        case NOTIFY_STOP:
+                            notifyStop();
+                            break;
+                        case NOTIFY_SEEK:
+                            notifySeek();
+                            break;
                     }
                 }
             }
diff -urN Original_4.4.4_r1/frameworks/base/services/input/InputDispatcher.cpp AndroidSource/frameworks/base/services/input/InputDispatcher.cpp
--- Original_4.4.4_r1/frameworks/base/services/input/InputDispatcher.cpp	2016-01-29 15:12:34.459488000 +0900
+++ AndroidSource/frameworks/base/services/input/InputDispatcher.cpp	2015-08-04 09:56:42.000000000 +0900
@@ -1989,8 +1989,12 @@
             }
 
             // Publish the motion event.
+
+            //ALOGD("InputDispatcher-startdispatch: %d", motionEntry->sourceDevice);
+
             status = connection->inputPublisher.publishMotionEvent(dispatchEntry->seq,
                     motionEntry->deviceId, motionEntry->source,
+                    //motionEntry->sourceDevice,
                     dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
                     motionEntry->edgeFlags, motionEntry->metaState, motionEntry->buttonState,
                     xOffset, yOffset,
@@ -2307,6 +2311,7 @@
             originalMotionEntry->deviceId,
             originalMotionEntry->source,
             originalMotionEntry->policyFlags,
+            //originalMotionEntry->sourceDevice,
             action,
             originalMotionEntry->flags,
             originalMotionEntry->metaState,
@@ -2432,6 +2437,7 @@
             "action=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, edgeFlags=0x%x, "
             "xPrecision=%f, yPrecision=%f, downTime=%lld",
             args->eventTime, args->deviceId, args->source, args->policyFlags,
+            //args->sourceDevice,
             args->action, args->flags, args->metaState, args->buttonState,
             args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime);
     for (uint32_t i = 0; i < args->pointerCount; i++) {
@@ -2468,7 +2474,12 @@
             mLock.unlock();
 
             MotionEvent event;
-            event.initialize(args->deviceId, args->source, args->action, args->flags,
+
+            //ALOGD("inputDispatcher-notifymotion: %d", args->sourceDevice);
+
+            event.initialize(args->deviceId, args->source,
+            		//args->sourceDevice,
+            		args->action, args->flags,
                     args->edgeFlags, args->metaState, args->buttonState, 0, 0,
                     args->xPrecision, args->yPrecision,
                     args->downTime, args->eventTime,
@@ -2485,6 +2496,7 @@
         // Just enqueue a new motion event.
         MotionEntry* newEntry = new MotionEntry(args->eventTime,
                 args->deviceId, args->source, policyFlags,
+                //args->sourceDevice,
                 args->action, args->flags, args->metaState, args->buttonState,
                 args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime,
                 args->displayId,
@@ -2605,6 +2617,7 @@
         const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
         firstInjectedEntry = new MotionEntry(*sampleEventTimes,
                 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
+                //motionEvent->getSourceDevice(),
                 action, motionEvent->getFlags(),
                 motionEvent->getMetaState(), motionEvent->getButtonState(),
                 motionEvent->getEdgeFlags(),
@@ -2617,6 +2630,7 @@
             samplePointerCoords += pointerCount;
             MotionEntry* nextInjectedEntry = new MotionEntry(*sampleEventTimes,
                     motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
+                    //motionEvent->getSourceDevice(),
                     action, motionEvent->getFlags(),
                     motionEvent->getMetaState(), motionEvent->getButtonState(),
                     motionEvent->getEdgeFlags(),
@@ -3894,14 +3908,18 @@
 // --- InputDispatcher::MotionEntry ---
 
 InputDispatcher::MotionEntry::MotionEntry(nsecs_t eventTime,
-        int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
+        int32_t deviceId, uint32_t source, uint32_t policyFlags,
+        //int32_t sourceDevice,
+        int32_t action, int32_t flags,
         int32_t metaState, int32_t buttonState,
         int32_t edgeFlags, float xPrecision, float yPrecision,
         nsecs_t downTime, int32_t displayId, uint32_t pointerCount,
         const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) :
         EventEntry(TYPE_MOTION, eventTime, policyFlags),
         eventTime(eventTime),
-        deviceId(deviceId), source(source), action(action), flags(flags),
+        deviceId(deviceId), source(source),
+        //sourceDevice(sourceDevice),
+        action(action), flags(flags),
         metaState(metaState), buttonState(buttonState), edgeFlags(edgeFlags),
         xPrecision(xPrecision), yPrecision(yPrecision),
         downTime(downTime), displayId(displayId), pointerCount(pointerCount) {
@@ -4195,6 +4213,7 @@
         if (shouldCancelMotion(memento, options)) {
             outEvents.push(new MotionEntry(currentTime,
                     memento.deviceId, memento.source, memento.policyFlags,
+                    //memento.sourceDevice,
                     memento.hovering
                             ? AMOTION_EVENT_ACTION_HOVER_EXIT
                             : AMOTION_EVENT_ACTION_CANCEL,
diff -urN Original_4.4.4_r1/frameworks/base/services/input/InputDispatcher.h AndroidSource/frameworks/base/services/input/InputDispatcher.h
--- Original_4.4.4_r1/frameworks/base/services/input/InputDispatcher.h	2016-01-29 15:12:34.459488000 +0900
+++ AndroidSource/frameworks/base/services/input/InputDispatcher.h	2015-08-04 09:57:07.000000000 +0900
@@ -506,6 +506,7 @@
         nsecs_t eventTime;
         int32_t deviceId;
         uint32_t source;
+        //int32_t sourceDevice;
         int32_t action;
         int32_t flags;
         int32_t metaState;
@@ -521,6 +522,7 @@
 
         MotionEntry(nsecs_t eventTime,
                 int32_t deviceId, uint32_t source, uint32_t policyFlags,
+                //int32_t sourceDevice,
                 int32_t action, int32_t flags,
                 int32_t metaState, int32_t buttonState, int32_t edgeFlags,
                 float xPrecision, float yPrecision,
@@ -754,6 +756,7 @@
         struct MotionMemento {
             int32_t deviceId;
             uint32_t source;
+            //int32_t sourceDevice;
             int32_t flags;
             float xPrecision;
             float yPrecision;
diff -urN Original_4.4.4_r1/frameworks/base/services/input/InputListener.cpp AndroidSource/frameworks/base/services/input/InputListener.cpp
--- Original_4.4.4_r1/frameworks/base/services/input/InputListener.cpp	2016-01-29 15:12:34.459488000 +0900
+++ AndroidSource/frameworks/base/services/input/InputListener.cpp	2015-08-04 10:05:40.000000000 +0900
@@ -68,14 +68,17 @@
 
 NotifyMotionArgs::NotifyMotionArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source,
         uint32_t policyFlags,
+        //int32_t sourceDevice,
         int32_t action, int32_t flags, int32_t metaState, int32_t buttonState,
         int32_t edgeFlags, int32_t displayId, uint32_t pointerCount,
         const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
         float xPrecision, float yPrecision, nsecs_t downTime) :
         eventTime(eventTime), deviceId(deviceId), source(source), policyFlags(policyFlags),
+        //sourceDevice(sourceDevice),
         action(action), flags(flags), metaState(metaState), buttonState(buttonState),
         edgeFlags(edgeFlags), displayId(displayId), pointerCount(pointerCount),
         xPrecision(xPrecision), yPrecision(yPrecision), downTime(downTime) {
+	//ALOGD("inputListener-NotifyMotionArgs: %d", sourceDevice);
     for (uint32_t i = 0; i < pointerCount; i++) {
         this->pointerProperties[i].copyFrom(pointerProperties[i]);
         this->pointerCoords[i].copyFrom(pointerCoords[i]);
@@ -85,11 +88,13 @@
 NotifyMotionArgs::NotifyMotionArgs(const NotifyMotionArgs& other) :
         eventTime(other.eventTime), deviceId(other.deviceId), source(other.source),
         policyFlags(other.policyFlags),
+        //sourceDevice(other.sourceDevice),
         action(other.action), flags(other.flags),
         metaState(other.metaState), buttonState(other.buttonState),
         edgeFlags(other.edgeFlags), displayId(other.displayId),
         pointerCount(other.pointerCount),
         xPrecision(other.xPrecision), yPrecision(other.yPrecision), downTime(other.downTime) {
+	//ALOGD("inputListener-OtherNotifyMotionArgs: %d", other.sourceDevice);
     for (uint32_t i = 0; i < pointerCount; i++) {
         pointerProperties[i].copyFrom(other.pointerProperties[i]);
         pointerCoords[i].copyFrom(other.pointerCoords[i]);
diff -urN Original_4.4.4_r1/frameworks/base/services/input/InputListener.h AndroidSource/frameworks/base/services/input/InputListener.h
--- Original_4.4.4_r1/frameworks/base/services/input/InputListener.h	2016-01-29 15:12:34.459488000 +0900
+++ AndroidSource/frameworks/base/services/input/InputListener.h	2015-08-04 10:05:06.000000000 +0900
@@ -83,6 +83,7 @@
     int32_t deviceId;
     uint32_t source;
     uint32_t policyFlags;
+    //int32_t sourceDevice;
     int32_t action;
     int32_t flags;
     int32_t metaState;
@@ -99,7 +100,8 @@
     inline NotifyMotionArgs() { }
 
     NotifyMotionArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source, uint32_t policyFlags,
-            int32_t action, int32_t flags, int32_t metaState, int32_t buttonState,
+            //int32_t sourceDevice,
+    		int32_t action, int32_t flags, int32_t metaState, int32_t buttonState,
             int32_t edgeFlags, int32_t displayId, uint32_t pointerCount,
             const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
             float xPrecision, float yPrecision, nsecs_t downTime);
diff -urN Original_4.4.4_r1/frameworks/base/services/input/InputReader.cpp AndroidSource/frameworks/base/services/input/InputReader.cpp
--- Original_4.4.4_r1/frameworks/base/services/input/InputReader.cpp	2016-01-29 15:12:34.459488000 +0900
+++ AndroidSource/frameworks/base/services/input/InputReader.cpp	2015-08-04 10:07:57.000000000 +0900
@@ -2509,6 +2509,7 @@
         }
 
         NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+        		//0,
                 motionEventAction, 0, metaState, currentButtonState, 0,
                 displayId, 1, &pointerProperties, &pointerCoords,
                 mXPrecision, mYPrecision, downTime);
@@ -2518,6 +2519,7 @@
         if (motionEventAction == AMOTION_EVENT_ACTION_UP
                 && mPointerController != NULL) {
             NotifyMotionArgs hoverArgs(when, getDeviceId(), mSource, policyFlags,
+            		//0,
                     AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
                     metaState, currentButtonState, AMOTION_EVENT_EDGE_FLAG_NONE,
                     displayId, 1, &pointerProperties, &pointerCoords,
@@ -2531,6 +2533,7 @@
             pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
 
             NotifyMotionArgs scrollArgs(when, getDeviceId(), mSource, policyFlags,
+            		//0,
                     AMOTION_EVENT_ACTION_SCROLL, 0, metaState, currentButtonState,
                     AMOTION_EVENT_EDGE_FLAG_NONE,
                     displayId, 1, &pointerProperties, &pointerCoords,
@@ -4550,6 +4553,7 @@
         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
 
         NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+        		//0,
                 AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
                 metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
                 mViewport.displayId, 1, &pointerProperties, &pointerCoords,
@@ -5472,6 +5476,7 @@
 
         // Send up.
         NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+        		//0,
                  AMOTION_EVENT_ACTION_UP, 0, metaState, mLastButtonState, 0,
                  mViewport.displayId,
                  1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
@@ -5485,6 +5490,7 @@
 
         // Send hover exit.
         NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+        		//0,
                 AMOTION_EVENT_ACTION_HOVER_EXIT, 0, metaState, mLastButtonState, 0,
                 mViewport.displayId,
                 1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
@@ -5500,6 +5506,7 @@
 
             // Send down.
             NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+            		//0,
                     AMOTION_EVENT_ACTION_DOWN, 0, metaState, mCurrentButtonState, 0,
                     mViewport.displayId,
                     1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
@@ -5510,6 +5517,7 @@
 
         // Send move.
         NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+        		//0,
                 AMOTION_EVENT_ACTION_MOVE, 0, metaState, mCurrentButtonState, 0,
                 mViewport.displayId,
                 1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
@@ -5524,6 +5532,7 @@
 
             // Send hover enter.
             NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+            		//0,
                     AMOTION_EVENT_ACTION_HOVER_ENTER, 0, metaState, mCurrentButtonState, 0,
                     mViewport.displayId,
                     1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
@@ -5534,6 +5543,7 @@
 
         // Send hover move.
         NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+        		//0,
                 AMOTION_EVENT_ACTION_HOVER_MOVE, 0, metaState, mCurrentButtonState, 0,
                 mViewport.displayId,
                 1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
@@ -5555,6 +5565,7 @@
         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
 
         NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+        		//0,
                 AMOTION_EVENT_ACTION_SCROLL, 0, metaState, mCurrentButtonState, 0,
                 mViewport.displayId,
                 1, &mPointerSimple.currentProperties, &pointerCoords,
@@ -5617,6 +5628,7 @@
     }
 
     NotifyMotionArgs args(when, getDeviceId(), source, policyFlags,
+    		//0,
             action, flags, metaState, buttonState, edgeFlags,
             mViewport.displayId, pointerCount, pointerProperties, pointerCoords,
             xPrecision, yPrecision, downTime);
@@ -6460,6 +6472,7 @@
     uint32_t policyFlags = 0;
 
     NotifyMotionArgs args(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, policyFlags,
+    		//0,
             AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
             ADISPLAY_ID_NONE, 1, &pointerProperties, &pointerCoords, 0, 0, 0);
     getListener()->notifyMotion(&args);
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/devicemanager/DeviceManagementService.java AndroidSource/frameworks/base/services/java/com/android/server/devicemanager/DeviceManagementService.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/devicemanager/DeviceManagementService.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/devicemanager/DeviceManagementService.java	2016-09-08 18:57:34.464975065 +0900
@@ -0,0 +1,331 @@
+
+package com.android.server.devicemanager;
+
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.net.DhcpInfo;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.service.devicemanager.Device;
+import android.service.devicemanager.DeviceList;
+import android.service.devicemanager.IDeviceManager;
+import android.service.remote.IRemoteService;
+import android.util.Log;
+import android.util.SparseArray;
+
+public class DeviceManagementService extends IDeviceManager.Stub {
+    private Context mContext;
+
+    public static final String TAG = "DeviceManagementService";
+    public RecommenderUDPSender sender;
+
+    private List<Device> configuredDeviceList;
+    private HashMap<String, Device> nameToDevice;
+    private ArrayList<Device> connectedDevices;
+    
+    private SparseArray<ArrayList<String>> resourceToAllowedDevices;
+
+    public final int SYSTEM_SERVICE_LIST = 1;
+    public final int TASK_EXECUTOR_LIST = 2;
+
+    public DeviceManagementService(Context context) {
+        // TODO Auto-generated constructor stub
+        mContext = context;
+        RecommenderUDPReceiver t = new RecommenderUDPReceiver(getBroadcastIp(), context);
+        RecommenderTCPReceiver tr = new RecommenderTCPReceiver();
+        t.start();
+        tr.start();
+        
+        resourceToAllowedDevices = new SparseArray<ArrayList<String>>();
+        for(int i=0; i<Device.RESOURCE_TYPE_SIZE; i++)
+        {
+        	if(resourceToAllowedDevices.get(i) == null)
+        		resourceToAllowedDevices.put(i, new ArrayList<String>());
+        }
+        
+        nameToDevice = new HashMap<String, Device>();
+        connectedDevices = new ArrayList<Device>();
+    }
+    
+    public void initDevices()
+    {
+    	nameToDevice.clear();
+    	if(configuredDeviceList != null)
+    		configuredDeviceList.clear();
+    	
+    	for(int i=0; i<Device.RESOURCE_TYPE_SIZE; i++)
+        {
+        	if(resourceToAllowedDevices.get(i) != null)
+        		resourceToAllowedDevices.get(i).clear();
+        }    		
+    	
+    }
+    
+    public int getNumofConfiguredDevices()
+    {
+    	if(configuredDeviceList == null)
+    		return 0;
+    	else
+    		return configuredDeviceList.size();
+    }
+    
+    public Device getDevice(String name)
+    {
+    	return nameToDevice.get(name);
+    }
+
+    public void constructCluster(List<Device> devicelist) {
+        this.configuredDeviceList = devicelist;
+        IRemoteService remoteService = IRemoteService.Stub.asInterface(ServiceManager.getService(Context.REMOTE_SERVICE));
+        try 
+        {
+			remoteService.sendResourceRequests(devicelist);
+		} 
+        catch (RemoteException e) 
+        {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+        
+        for (Device d : configuredDeviceList) {
+        	if(!nameToDevice.containsKey(d.deviceName))
+        		nameToDevice.put(d.deviceName, d);
+        }
+        
+        //categorizeDevices();
+    }
+    
+    public void showRequestDialog(String deviceName, String deviceIP, int askedResources[])
+    {
+    	Device device;
+    	
+    	if(nameToDevice.containsKey(deviceName))
+    		device = nameToDevice.get(deviceName);
+		else
+		{
+			device = new Device(deviceIP, "-1", deviceName, 0, 0);
+			nameToDevice.put(deviceName, device);
+		}
+    	
+    	ComponentName compName = new ComponentName(
+                "com.test"
+                , "com.test.alert.RequestDialog");
+        
+        Intent intent = new Intent("android.intent.action.COLLABOROID");
+        //intent.addCategory("android.intent.category.VIDEO_STREAMING");
+        intent.setComponent(compName);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.addCategory(Intent.CATEGORY_DEFAULT);
+        
+        intent.putExtra("deviceName", device.deviceName);
+        intent.putExtra("resources", askedResources);
+        
+        mContext.startActivity(intent);
+    }
+    
+    public void askResources(List<Device> devicelist) {
+        this.configuredDeviceList = devicelist;
+        IRemoteService remoteService = IRemoteService.Stub.asInterface(ServiceManager.getService(Context.REMOTE_SERVICE));
+        try 
+        {
+			remoteService.sendResourceRequests(devicelist);
+		} 
+        catch (RemoteException e) 
+        {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+        
+        for (Device d : configuredDeviceList) {
+        	if(!nameToDevice.containsKey(d.deviceName))
+        		nameToDevice.put(d.deviceName, d);
+        }
+    }
+    
+    public void allowResources(String deviceName, int allowedResources[]) //Device device)
+    {
+    	Log.d(TAG, "1 - " + "deviceName / " + Arrays.toString(allowedResources));
+    	if(allowedResources != null)
+    	{
+    		Log.d(TAG, "2 - " + "deviceName / " + Arrays.toString(allowedResources));
+    		if(nameToDevice.containsKey(deviceName))
+    		{
+    			Log.d(TAG, "3 - " + "deviceName / " + Arrays.toString(allowedResources));
+    			
+    			Device device = nameToDevice.get(deviceName);
+    			
+    			for(int i : allowedResources)
+    			{
+    				device.allowedResources[i] = 1;
+    				if(!resourceToAllowedDevices.get(i).contains(device.ipaddress))
+    					resourceToAllowedDevices.get(i).add(device.ipaddress);
+    			}
+    			
+    			IRemoteService remoteService = IRemoteService.Stub.asInterface(ServiceManager.getService(Context.REMOTE_SERVICE));
+    	        try 
+    	        {
+    				remoteService.respondAllowedResources(device.ipaddress, allowedResources);
+    			} 
+    	        catch (RemoteException e) 
+    	        {
+    				// TODO Auto-generated catch block
+    				e.printStackTrace();
+    			}
+    				
+    		}
+    		
+    	}
+    	/*else if(allowedResources == null)
+    	{
+    		
+    	}
+    	
+    	if(nameToDevice.containsKey(deviceName))
+    	{
+    		
+    	}
+    	Device device = nameToDevice.get(deviceName);
+    	
+    	
+    	
+    	
+    	
+    	if(!nameToDevice.containsKey(device.deviceName))
+    		nameToDevice.put(device.deviceName, device);
+    	
+        for(int i=0; i<Device.RESOURCE_TYPE_SIZE; i++)
+        {
+        	if(device.allowedResources[i] == 1 && !resourceToAllowedDevices.get(i).contains(device.ipaddress))
+        		resourceToAllowedDevices.get(i).add(device.ipaddress);
+        }*/
+    }
+
+    public void categorizeDevices() {
+        for (Device d : configuredDeviceList) {
+        	if(!nameToDevice.containsKey(d.deviceName))
+        		nameToDevice.put(d.deviceName, d);
+            
+        	for(int i=0; i<Device.RESOURCE_TYPE_SIZE; i++)
+            {
+            	if(d.allowedResources[i] == 1 && !resourceToAllowedDevices.get(i).contains(d.ipaddress))
+            		resourceToAllowedDevices.get(i).add(d.ipaddress);
+            }
+        }
+    }
+    
+    @Override
+	public boolean isAllowedForResource(String device, int resource) throws RemoteException {
+		// TODO Auto-generated method stub
+    	return resourceToAllowedDevices.get(resource).contains(device);
+    }
+
+    public String recommendDevice(List<Device> devicelist) throws RemoteException {
+        // TODO Auto-generated method stub
+
+        if (!devicelist.isEmpty()) {
+
+            Collections.sort(devicelist, new RecommenderPeerCompare());
+            Device p = devicelist.get(0);
+            for (int i = 0; i < devicelist.size(); i++) {
+                Device d = devicelist.get(i);
+                Log.i("RecommService", "address: " + d.ipaddress + "  SystemServer: "
+                        + d.isSystemServiceOn
+                        + "  TaskServer: " + d.isTaskExecutorOn);
+            }
+            return p.ipaddress;
+        }
+        return null;
+    }
+
+    public List<Device> getDeviceList(int kind) throws RemoteException {
+        // TODO Auto-generated method stub
+        findDevice();
+        /*
+         * Set<String> keys = DeviceList.getDevices().keySet(); List<Device> ps
+         * = new ArrayList<Device>(); for (String key : keys) {
+         * ps.add(DeviceList.getDevices().get(key)); }
+         */
+        return getServerList(kind);
+    }
+
+    public String[] getSystemServiceOnServerList() throws RemoteException {
+        return (String[]) getServerList(SYSTEM_SERVICE_LIST).toArray();
+
+    }
+
+    public String[] getTaskExecutorOnServerList() throws RemoteException {
+        return (String[]) getServerList(TASK_EXECUTOR_LIST).toArray();
+    }
+
+    public ArrayList<Device> getServerList(int kind) throws RemoteException {
+        ArrayList<Device> deviceList = new ArrayList<Device>();
+        Collection<Device> cp = DeviceList.getDevices().values();
+        for (Device p : cp) {
+            if (kind == SYSTEM_SERVICE_LIST) {
+                if (p.isSystemServiceOn > 0) {
+                    deviceList.add(p);
+                }
+            } else if (kind == TASK_EXECUTOR_LIST) {
+                if (p.isTaskExecutorOn > 0) {
+                    deviceList.add(p);
+                }
+            }
+        }
+
+        return deviceList;
+    }
+
+    /*
+     * public ArrayList<String> getServerList(int KIND) throws RemoteException{
+     * ArrayList<String> serverlist = new ArrayList<String>();
+     * Collection<Device> cp = DeviceList.getDevices().values(); for(Device p :
+     * cp){ if(KIND == SYSTEM_SERVICE_LIST){ if(p.isSystemServiceOn > 0){
+     * serverlist.add(p.ipaddress); } } else if(KIND == TASK_EXECUTOR_LIST){
+     * if(p.isTaskExecutorOn > 0){ serverlist.add(p.ipaddress); } } } return
+     * serverlist; }
+     */
+
+    private void findDevice() {
+        // TODO Auto-generated method stub
+        InetAddress broadcast = getBroadcastIp();
+        Log.i("RecommService", "broadcast: " + broadcast.toString());
+        sender = new RecommenderUDPSender(broadcast);
+        sender.start();
+    }
+
+    public InetAddress getBroadcastIp() {
+        try {
+            WifiManager mWifi = (WifiManager) mContext
+                    .getSystemService(Context.WIFI_SERVICE);
+            WifiInfo info = mWifi.getConnectionInfo();
+
+            DhcpInfo dhcp = mWifi.getDhcpInfo();
+
+            int broadcast = (dhcp.ipAddress & dhcp.netmask) | ~dhcp.netmask;
+
+            byte[] quads = new byte[4];
+            for (int k = 0; k < 4; k++)
+                quads[k] = (byte) ((broadcast >> k * 8) & 0xFF);
+
+            // Log.d("UDP", "main ipadd1 = : " + dhcp.ipAddress);
+            // Log.d("UDP", "main ipadd2 = : " + dhcp.netmask);
+            Log.d("UDP", "broadcast ip = : " + InetAddress.getByAddress(quads));
+            return InetAddress.getByAddress(quads);
+        } catch (Exception e) {
+
+        }
+        return null;
+
+    }
+}
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/devicemanager/RecommenderPeerCompare.java AndroidSource/frameworks/base/services/java/com/android/server/devicemanager/RecommenderPeerCompare.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/devicemanager/RecommenderPeerCompare.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/devicemanager/RecommenderPeerCompare.java	2016-01-11 20:04:03.000000000 +0900
@@ -0,0 +1,16 @@
+package com.android.server.devicemanager;
+
+import java.util.Comparator;
+
+import android.service.devicemanager.Device;
+
+public class RecommenderPeerCompare implements Comparator<Device> {
+
+	@Override
+	public int compare(Device device1, Device device2) {
+		// TODO Auto-generated method stub
+		return device2.idleCpu.compareTo(device1.idleCpu);
+	}
+
+
+}
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/devicemanager/RecommenderTCPReceiver.java AndroidSource/frameworks/base/services/java/com/android/server/devicemanager/RecommenderTCPReceiver.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/devicemanager/RecommenderTCPReceiver.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/devicemanager/RecommenderTCPReceiver.java	2016-01-11 20:04:10.000000000 +0900
@@ -0,0 +1,39 @@
+package com.android.server.devicemanager;
+
+import android.util.Log;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+public class RecommenderTCPReceiver extends Thread {
+	public static final int PORT = 9050;
+
+	public void run() {
+		ServerSocket sc;
+		try {
+			sc = new ServerSocket(PORT + 1);
+			Log.i("TCP Receiver", "waiting for a client to join: ");
+			try {
+				while (true) {
+					Socket returnSocket = sc.accept();
+					Log.i("TCP Receiver", "return from "
+                            + returnSocket.getInetAddress().getHostAddress());
+//					System.out.println("return from " + returnSocket.getInetAddress().getAddress());
+					ReturnThread rt = new ReturnThread(returnSocket);
+					rt.start();
+				}
+			} catch (Exception e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			} finally {
+				sc.close();
+			}
+
+		} catch (IOException e1) {
+			// TODO Auto-generated catch block
+			e1.printStackTrace();
+		}
+
+	}
+}
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/devicemanager/RecommenderUDPReceiver.java AndroidSource/frameworks/base/services/java/com/android/server/devicemanager/RecommenderUDPReceiver.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/devicemanager/RecommenderUDPReceiver.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/devicemanager/RecommenderUDPReceiver.java	2016-06-24 12:42:10.000000000 +0900
@@ -0,0 +1,203 @@
+package com.android.server.devicemanager;
+
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.Socket;
+import java.net.SocketException;
+import java.util.Enumeration;
+
+import android.app.Application;
+import android.content.Context;
+import android.os.Build;
+import android.provider.Settings.Secure;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+
+public class RecommenderUDPReceiver extends Thread {
+	public static final int PORT = 9050;
+	public InetAddress broadcastip;
+	Context mContext;
+	
+	public RecommenderUDPReceiver(InetAddress broadcastip, Context context) {
+		this.broadcastip = broadcastip;
+		this.mContext = context;
+	}
+
+	public static String getIpaddress() {
+		// TODO Auto-generated method stub
+		try {
+			for (Enumeration<NetworkInterface> en = NetworkInterface
+					.getNetworkInterfaces(); en.hasMoreElements();) {
+				NetworkInterface intf = (NetworkInterface) en.nextElement();
+				for (Enumeration<InetAddress> enumIpaddr = intf
+						.getInetAddresses(); enumIpaddr.hasMoreElements();) {
+					InetAddress inetAddress = (InetAddress) enumIpaddr
+							.nextElement();
+					if (!inetAddress.isLoopbackAddress()
+							&& inetAddress instanceof Inet4Address) {
+						return inetAddress.getHostAddress();
+					}
+				}
+			}
+		} catch (SocketException e) {
+		}
+		return null;
+	}
+	public String getWifiMacAddress(){
+		Process p;
+		try {
+			p = Runtime.getRuntime().exec("cat /sys/class/net/wlan0/address");
+			BufferedReader br = new BufferedReader(new InputStreamReader(
+					p.getInputStream()));
+			String line = null;
+			line = br.readLine();
+			if(!line.isEmpty()){
+				return line;
+			}
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return null;
+
+	}
+	public double cpuUsage() {
+		try {
+			Process p = Runtime.getRuntime().exec("cat /proc/stat");
+			BufferedReader br = new BufferedReader(new InputStreamReader(
+					p.getInputStream()));
+			String line = null;
+
+			while ((line = br.readLine()) != null) {
+				if (line.contains("cpu ")) {
+					System.out.println(line);
+					String[] temp = line.split(" ");
+					double total_cpu = 0;
+					for (int i = 2; i < 6; i++)
+						total_cpu = Double.parseDouble(temp[i]) + total_cpu;
+
+					double idle = Double.parseDouble(temp[5]);
+					double result = (idle / total_cpu) * 100;
+
+					return Math.round(result);
+				}
+			}
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return -1;
+	}
+	
+    public String getDeviceName() {
+        /*String manufacturer = Build.MANUFACTURER;
+        String model = Build.MODEL;
+        if (model.startsWith(manufacturer)) {
+            return capitalize(model);
+        } else {
+            return capitalize(manufacturer) + " " + model;
+        }*/
+//        TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
+//        return telephonyManager.getDeviceId().substring(11);
+        
+        //final String deviceId = ((TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId();
+        
+    	
+    	return capitalize(Build.SERIAL);
+    	
+    	/*
+        String deviceId = Secure.getString(mContext.getContentResolver(),
+                Secure.ANDROID_ID); 
+        
+        Log.d("UDP", deviceId);
+        
+        if (deviceId != null) {
+            return capitalize(deviceId);
+        } else {
+            return capitalize(Build.SERIAL);
+        }*/
+    }
+
+    private String capitalize(String s) {
+        if (s == null || s.length() == 0) {
+            return "";
+        }
+        char first = s.charAt(0);
+        if (Character.isUpperCase(first)) {
+            return s;
+        } else {
+            return Character.toUpperCase(first) + s.substring(1);
+        }
+    }
+	
+	
+	@Override
+	public void run() {
+		// TODO Auto-generated method stub
+		DatagramSocket socket = null;
+		try {
+			socket = new DatagramSocket(PORT);
+			socket.setBroadcast(true);
+			// socket.setSoTimeout(5000);
+			byte[] buf = new byte[4096];
+
+			while (true) {
+				try {
+					DatagramPacket receivepacket = new DatagramPacket(buf,
+							buf.length);
+
+					Log.i("UDP Receiver", "WAITING UDP BROADCAST");
+					socket.receive(receivepacket);
+
+					InetAddress returnAddress = receivepacket.getAddress();
+					String message = new String(receivepacket.getData()).trim();
+
+					Log.i("UDP Receiver", "Got udp broadcast from "
+							+ returnAddress.getHostAddress() + ", msg : " + message);
+
+					String ipaddress = getIpaddress();
+					double idlecpu = cpuUsage();
+					String macAddr = getWifiMacAddress();
+//					android.provider.Settings.Global.putInt(, name, value)
+//					int isCollaboroidOn = android.provider.Settings.Global.getInt(mContext.getContentResolver(), android.provider.Settings.Global.COLLABOROID_ON, 0);
+					int isCollaboroidOn = 1;
+					int taskExecutorOn = 0;
+					
+					String result = macAddr + "_" + ipaddress + "_" + idlecpu + "_" + getDeviceName() + "_" + String.valueOf(isCollaboroidOn) + "_" + String.valueOf(taskExecutorOn);
+
+					Log.i(DeviceManagementService.TAG, "msg: " + result);
+
+					// buf = result.getBytes();
+
+					Socket returnInfo = new Socket(returnAddress,
+							PORT + 1);
+					OutputStream out = returnInfo.getOutputStream();
+					DataOutputStream dos = new DataOutputStream(out);
+
+					dos.writeUTF(result);
+					Log.i("UDP Receiver", "return to " + returnAddress
+							+ "  msg " + result);
+					returnInfo.close();
+					dos.close();
+
+				} catch (Exception e) {
+					Log.e(DeviceManagementService.TAG, "UDP receiver error: ");
+					e.getStackTrace();
+				}
+			}
+
+		} catch (Exception e) {
+
+		} finally {
+			socket.close();
+		}
+	}
+}
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/devicemanager/RecommenderUDPSender.java AndroidSource/frameworks/base/services/java/com/android/server/devicemanager/RecommenderUDPSender.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/devicemanager/RecommenderUDPSender.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/devicemanager/RecommenderUDPSender.java	2016-01-11 20:04:57.000000000 +0900
@@ -0,0 +1,80 @@
+package com.android.server.devicemanager;
+
+import android.util.Log;
+
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+
+public class RecommenderUDPSender extends Thread {
+	public static final int PORT = 9050;
+	public InetAddress broadcastIp;
+
+	public RecommenderUDPSender(InetAddress broadcastIp) {
+		this.broadcastIp = broadcastIp;
+	}
+
+	@Override
+	public void run() {
+		// TODO Auto-generated method stub
+		String return_msg = null;
+		try {
+
+			DatagramSocket send_socket = new DatagramSocket();
+//			DatagramSocket receive_socket = new DatagramSocket(PORT+1);
+			send_socket.setBroadcast(true);
+
+			byte[] buf = new byte[4096];
+			buf = ("ip/cpu").getBytes(); 
+
+			DatagramPacket sendpacket = new DatagramPacket(buf, buf.length,
+					this.broadcastIp, PORT);
+
+			send_socket.send(sendpacket);
+			Log.i("UDPSender", "Send:"+ new String(buf).trim());
+			
+//			
+//			
+//			ServerSocket sc = new ServerSocket(PORT+1);
+//			Socket returnSocket = sc.accept();
+//			System.out.println("return from" + returnSocket.getInetAddress().getAddress());
+//			ReturnThread rt = new ReturnThread(returnSocket);
+//			rt.start();
+			
+//			
+//			InputStream in = returnSocket.getInputStream();
+//			DataInputStream dis = new DataInputStream(in);
+////			
+//			
+//			DatagramPacket receviePacket = new DatagramPacket(buf, buf.length);
+//			receive_socket.receive(receviePacket);
+	
+//			return_msg = new String(receviePacket.getData())+"";
+//			
+//			Log.i(RecommenderService.TAG, "udp return msg: " + return_msg);
+//
+//			String[] temp2 = return_msg.split("_");
+//			String ipaddress = temp2[0];
+//			String idlecpu = temp2[1];
+//			
+//			Log.i(RecommenderService.TAG, "return ip:" + ipaddress + "return cpu usage:" + idlecpu);
+//
+//			Peer p = new Peer(ipaddress, idlecpu);
+//			
+//			Log.i(RecommenderService.TAG, "peer:" + p.toString());
+//			
+//			
+//			PeerList.getPeers().add(p);
+
+			send_socket.close();
+			
+//			receive_socket.close();
+//			sc.close();
+//			dis.close();
+//			returnSocket.close();
+
+		} catch (Exception e) {
+			Log.e("UDP", "S: Error", e);
+		}
+	}
+}
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/devicemanager/ReturnThread.java AndroidSource/frameworks/base/services/java/com/android/server/devicemanager/ReturnThread.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/devicemanager/ReturnThread.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/devicemanager/ReturnThread.java	2016-01-12 20:47:27.000000000 +0900
@@ -0,0 +1,57 @@
+
+package com.android.server.devicemanager;
+
+import android.service.devicemanager.Device;
+import android.service.devicemanager.DeviceList;
+import android.util.Log;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+
+public class ReturnThread extends Thread {
+    public static final int PORT = 9050;
+
+    private Socket socket;
+
+    public ReturnThread(Socket socket) {
+        this.socket = socket;
+    }
+
+    public void run() {
+        try {
+            InputStream in = socket.getInputStream();
+            DataInputStream dis = new DataInputStream(in);
+            String return_msg = dis.readUTF();
+
+            String[] temp2 = return_msg.split("_");
+            String macAddr = temp2[0];
+            String ipaddress = temp2[1];
+            String idlecpu = temp2[2];
+            String deviceName = temp2[3];
+            int isCollaboroidOn = Integer.parseInt(temp2[4]);
+            int isTaskExecutor = Integer.parseInt(temp2[5]);
+
+            Log.i("ReturnThread", "device: " + macAddr + "  return ip: " + ipaddress
+                    + "  return cpu usage: " + idlecpu);
+            
+            Device p = new Device(ipaddress, idlecpu, deviceName, isCollaboroidOn, isTaskExecutor);
+            Log.i("ReturnThread", "device name: " + macAddr + " / peer: " + p.toString());
+            
+            if (ipaddress.equals(RecommenderUDPReceiver.getIpaddress())){
+                Log.i("ReturnThread", "Return from own device: " + ipaddress + ", " + InetAddress.getLocalHost().getHostAddress());
+            }
+            else{
+                DeviceList.getDevices().put(macAddr, p);
+                Log.i("ReturnThread", "Added to Peer list " + ipaddress + ", " + RecommenderUDPReceiver.getIpaddress());
+            }
+            
+            socket.close();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+}
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/distribute/DistributedComputingService.java AndroidSource/frameworks/base/services/java/com/android/server/distribute/DistributedComputingService.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/distribute/DistributedComputingService.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/distribute/DistributedComputingService.java	2016-02-16 19:52:38.000000000 +0900
@@ -0,0 +1,93 @@
+package com.android.server.distribute;
+
+import java.util.ArrayList;
+
+import android.content.Context;
+import android.service.distribute.IDistributedComputingService;
+import android.util.Log;
+
+public class DistributedComputingService extends IDistributedComputingService.Stub
+{
+	private static final String TAG = "DistributedComputing";
+	// private static final int SERVERPORT = 55555;
+
+	Context mContext;
+
+	private JobManager mJobManager;
+	
+	// For Server
+	private TaskExecutor mTaskExecutor = null;
+	private Thread taskExecutorThread = null;
+
+	public DistributedComputingService(Context context)
+	{
+		mContext = context;
+	}
+
+
+	@Override
+	public void startJobManager(String ip)
+	{
+		if(mJobManager == null)
+		{
+			ArrayList<String> ip_list = new ArrayList<String>();
+			ip_list.add(ip);
+			mJobManager = new JobManager(ip_list);
+		}
+		else
+			Log.d(TAG, "HAHA?");
+	}
+	
+	@Override
+	public void stopJobManager()
+	{
+		
+	}
+	
+	@Override
+	public void startTaskExecutor()
+	{
+		if(taskExecutorThread == null)
+		{
+			mTaskExecutor = new TaskExecutor();
+			taskExecutorThread = new Thread(mTaskExecutor);
+			
+			taskExecutorThread.start();
+		}
+	}
+	
+	@Override
+	public void stopTaskExecutor()
+	{
+		if(taskExecutorThread != null)
+		{
+			mTaskExecutor.terminate();
+			taskExecutorThread.interrupt();
+		}
+	}
+
+	@Override
+	public int sum(int start, int end)
+	{
+		// TODO Auto-generated method stub
+		ArrayList<Object> paras = new ArrayList<Object>();
+		paras.add(start);
+		paras.add(end);
+		
+		//mJobManager.submitTask(new TaskRequest("com.android.server.distribute.Sum", paras));
+		mJobManager.submitTask(new TaskRequest("SUM", paras));
+		
+		Log.d(TAG, "result: " + mJobManager.executeJob()[0]);
+		
+		return 432;
+	}
+
+
+
+	@Override
+	public void testOperation()
+	{
+		// TODO Auto-generated method stub
+		sum(10, 50);
+	}
+}
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/distribute/JobManager.java AndroidSource/frameworks/base/services/java/com/android/server/distribute/JobManager.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/distribute/JobManager.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/distribute/JobManager.java	2015-01-27 17:21:21.000000000 +0900
@@ -0,0 +1,291 @@
+package com.android.server.distribute;
+
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import android.util.Log;
+
+public class JobManager 
+{
+	private static final String TAG = "JobManager";
+	private static final int DISTRIBUTED_COMPUTING_PORT = 55556;
+	
+	int node_num = 0, task_num = 0, total_task_num = 0;
+	
+	ArrayList<String> nodes;
+	//private final IRecommender mService;
+	
+	// for node performance
+	long node_info[][];
+	int node_perf_ratio[];
+	
+	long total_runtime = 0;
+	boolean isrunning = false;
+
+	int task_length, taskinfo_length;
+
+	AtomicInteger current_task = new AtomicInteger(0);
+	
+	ArrayList<TaskRequest> tasks;
+	
+	public JobManager(ArrayList<String> ip_list)
+	{
+		//mService = IRecommender.Stub.asInterface(ServiceManager.getService("recommender"));
+		
+		//nodes = mService.getPeerList();
+		nodes = ip_list;
+		node_num = nodes.size();
+		
+		node_info = new long[node_num][2]; // [][0]=task_count, [][1]=runtime
+		node_perf_ratio = new int[node_num];
+		
+		tasks = new ArrayList<TaskRequest>();
+		
+		Log.d(TAG, nodes.toString());
+		Log.d(TAG, "node_num: " + node_num);
+	}
+	
+	public void submitTask(TaskRequest task)
+	{
+		tasks.add(task);
+		task_num++;
+		Log.d(TAG, tasks.toString());
+	}
+	
+	/*public <T> Task submitTask(T t)
+	{
+		Task task = (Task)t;
+		
+		return task;
+	}*/
+	
+	public Object[] executeJob()
+	{
+		Thread node_thread[] = new Thread[node_num];
+		final long[][] job_info = new long[node_num][2];
+		
+		long begin, terminate;
+		
+		final Object[] results = new Object[task_num];
+		
+		// calculate node performance
+		if(node_perf_ratio[0] == 0)
+			executeTestcode();
+		else
+			for(int i=1; i<node_num; i++)
+				node_perf_ratio[i] = (int) Math.round((double)((float)node_info[i][1]/(float)node_info[i][0]) / ((float)node_info[0][1]/(float)node_info[0][0]));
+		
+		begin = System.currentTimeMillis();
+		try
+		{
+			// create thread for each node
+			for(int i = 0; i < node_num; i++)
+			{
+				final int num = i;
+				node_thread[i] = new Thread(new Runnable()
+				{
+					public void run()
+					{
+						long start=0, end=0;
+						job_info[num][0] = 0;
+						job_info[num][1] = 0;
+						
+						if(nodes.get(num).equals("localhost"))
+						{
+							int running_task = 0;// current_task.getAndIncrement();
+							
+							while((running_task=current_task.getAndIncrement()) < task_num)
+							{
+								if((task_num-running_task) < node_perf_ratio[num])
+								{
+									Log.d(TAG, "remain task: " + (task_num-running_task));
+									task_num++;
+									tasks.add(tasks.get(running_task));				
+									break;
+								}
+							
+								start = System.currentTimeMillis();
+	
+								//tasks.get(running_task).setValue(tasks.get(running_task).getTask().execute());
+						
+								end = System.currentTimeMillis();		
+								
+								job_info[num][0]++;
+								job_info[num][1]+=(end-start);
+							}
+						}
+						else
+						{
+							try
+							{
+								Socket node = new Socket(nodes.get(num), DISTRIBUTED_COMPUTING_PORT);
+
+								ObjectOutputStream oos = new ObjectOutputStream(node.getOutputStream());
+								ObjectInputStream ois = new ObjectInputStream(node.getInputStream());
+
+								int running_task=0;
+								
+								while((running_task=current_task.getAndIncrement()) < task_num)
+								{
+									Log.d(TAG, "running_task: " + running_task);
+									Log.d(TAG, "task_num: " + task_num);
+									
+									if((task_num-running_task) < node_perf_ratio[num])
+									{
+										Log.d(TAG, "remain task: " + (task_num-running_task));
+										task_num++;
+										tasks.add(tasks.get(running_task));				
+										break;
+									}
+									
+									start = System.currentTimeMillis();
+	
+									oos.writeObject(tasks.get(running_task));
+									//oos.flush();
+
+									//tasks.get(running_task).setValue(ois.readObject());
+									//reois.readObject()
+									
+									//results.set(running_task, ois.readObject());
+									results[running_task] = ois.readObject();
+									
+									end = System.currentTimeMillis();
+									
+									job_info[num][0]++;
+									job_info[num][1]+=(end-start);
+								}
+								oos.writeObject(new TaskRequest("BYE", null));
+								node.close();
+							}
+							catch (Exception e)
+							{
+								// TODO Auto-generated catch block
+								Log.e(TAG, "ExecuteJob exception:");
+								e.printStackTrace();
+							}
+						}
+					}
+				});
+				node_thread[i].start();
+			}
+			for(int i = 0; i < node_num; i++)
+				node_thread[i].join();
+		}
+		catch (Exception e)
+		{
+			e.printStackTrace();
+		}
+		
+		terminate = System.currentTimeMillis();
+		tasks.clear();
+		current_task.set(0);
+		collect_info(job_info);
+		total_runtime += (terminate - begin);
+		isrunning = false;
+		total_task_num += task_num;
+		task_num = 0;
+		
+		return results;
+	}
+	
+	public void executeTestcode()
+	{
+		final ArrayList<String> temp_list = new ArrayList<String>();
+		final ArrayList<Long> testcode_runtime = new ArrayList<Long>();
+		
+		final ArrayList<Object> paras = new ArrayList<Object>();
+		paras.add(10);
+		paras.add(100000);
+		
+		Thread node_thread[] = new Thread[node_num];
+		
+		try
+		{
+			// create thread for each node
+			for(int i=0; i<node_num; i++)
+			{
+				final int num = i;
+				node_thread[i] = new Thread(new Runnable()
+				{
+					public void run()
+					{
+						try
+						{
+							long start, end;
+							Socket node = new Socket(nodes.get(num), DISTRIBUTED_COMPUTING_PORT);
+
+							ObjectOutputStream oos = new ObjectOutputStream(node.getOutputStream());
+							ObjectInputStream ois = new ObjectInputStream(node.getInputStream());
+
+							start = System.currentTimeMillis();
+
+							oos.writeObject(new TaskRequest("SUM", paras));
+							ois.readObject();
+							
+							end = System.currentTimeMillis();
+
+							temp_list.add(nodes.get(num));
+							testcode_runtime.add(end-start);
+							
+							oos.writeObject(new TaskRequest("BYE", null));
+							node.close();
+						}
+						catch (Exception e)
+						{
+							// TODO Auto-generated catch block
+							Log.e(TAG, "TestCode exception:");
+							e.printStackTrace();
+						}											
+					}
+				});
+				node_thread[i].start();
+			}		
+			for(int i=0; i<node_num; i++)
+				node_thread[i].join();		
+			Log.d(TAG, "all finish!" + node_num);
+		}
+		catch(Exception e)
+		{
+			e.printStackTrace();
+		}
+		
+		nodes = temp_list;
+		
+		for(int i=0; i<node_num; i++)
+    		node_perf_ratio[i] = (int) Math.round((double)testcode_runtime.get(i) / testcode_runtime.get(0));
+	}
+	
+	public void collect_info(long[][] job_info)
+	{
+		for(int i = 0; i < node_num; i++)
+		{
+			node_info[i][0] += job_info[i][0];
+			node_info[i][1] += job_info[i][1];
+		}
+	}
+
+	public void print_info()
+	{
+		System.out
+				.println(" task count | % of all tasks | task time sum | time per task | job server");
+
+		for(int i = 0; i < node_num; i++)
+			System.out.printf(
+					"%11d |        %7.2f |     %9.3f |  %12.6f | %s\n",
+					node_info[i][0],
+					(((float) node_info[i][0] / (float) total_task_num)) * 100,
+					(float) node_info[i][1] / 1000,
+					((float) node_info[i][1] / (float) node_info[i][0]) / 1000,
+					nodes.get(i));
+
+		System.out.println("\ntotal runtime is " + total_runtime / 1000 + "."
+				+ total_runtime % 1000 + "sec");
+
+		System.out.println("task_length : " + task_length + "\ntaskinfo_length : "
+				+ taskinfo_length);
+
+	}
+}
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/distribute/NodeManager.java AndroidSource/frameworks/base/services/java/com/android/server/distribute/NodeManager.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/distribute/NodeManager.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/distribute/NodeManager.java	2016-01-12 09:25:30.000000000 +0900
@@ -0,0 +1,23 @@
+package com.android.server.distribute;
+
+import android.os.ServiceManager;
+import android.service.devicemanager.IDeviceManager;
+
+public class NodeManager 
+{
+	private final IDeviceManager mService;
+	
+	public NodeManager()
+	{
+		mService = IDeviceManager.Stub.asInterface(ServiceManager.getService("devicemanager"));
+	}
+	
+	/*public ArrayList<String> getNodes()
+	{
+		List<Peer> peers = mService.getPeerList();
+		
+		ArrayList<String> nodes = new ArrayList<String>();
+		
+		nodes.addAll(peers.)
+	}*/
+}
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/distribute/Sum.java AndroidSource/frameworks/base/services/java/com/android/server/distribute/Sum.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/distribute/Sum.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/distribute/Sum.java	2015-01-27 14:55:53.000000000 +0900
@@ -0,0 +1,28 @@
+package com.android.server.distribute;
+
+public class Sum implements Task<Integer>
+{
+	private final int min, max;
+	
+	public Sum(int min, int max)
+	{
+		this.min = min;
+		this.max = max;
+	}
+
+	public Integer execute()
+	{
+		return sum(min, max);
+	}
+	
+	public static int sum(int min, int max)
+	{
+		int i=0;
+		int result = 0;
+		
+		for(i=min; i<max; i++)
+			result += i;
+		
+		return result;
+	}
+}
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/distribute/TaskExecutor.java AndroidSource/frameworks/base/services/java/com/android/server/distribute/TaskExecutor.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/distribute/TaskExecutor.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/distribute/TaskExecutor.java	2015-01-27 21:54:48.000000000 +0900
@@ -0,0 +1,137 @@
+package com.android.server.distribute;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+import android.util.Log;
+
+public class TaskExecutor extends Thread
+{
+	private static final String TAG = "TaskExecutor";
+	private static final int DISTRIBUTED_COMPUTING_PORT = 55556;
+	
+	long execution_time = 0;
+	
+	ServerSocket serverSocket;
+	Socket socket;
+	
+	ObjectOutputStream outToClient;
+	ObjectInputStream inFromClient;
+	
+	TaskRequest task;
+	Object result;
+	
+	private static boolean isConnected = false;
+	
+	public void terminate()
+	{
+		try
+		{
+			outToClient.close();
+			inFromClient.close();
+			socket.close();
+		}
+		catch(IOException e)
+		{
+			e.printStackTrace();
+		}
+	}
+	
+	//Socket client;
+	@Override
+	public void run()
+	{
+		try
+		{
+			socket = null;
+			serverSocket = new ServerSocket(DISTRIBUTED_COMPUTING_PORT);
+			
+			
+			
+			long start, end;
+			
+			while (!Thread.currentThread().isInterrupted())
+			{
+				Log.d(TAG, "TaskExecutor successfully started!");
+				socket = serverSocket.accept();
+				isConnected = true;
+				Log.d(TAG, socket.getInetAddress() + "connected.");
+				
+				outToClient = new ObjectOutputStream(socket.getOutputStream());
+				inFromClient = new ObjectInputStream(socket.getInputStream());
+				
+				while(isConnected)
+				{
+					task = (TaskRequest)inFromClient.readObject();
+					Log.d(TAG, "Request!!!!");
+					
+					start = System.currentTimeMillis();
+					
+					result = handleTask(task);
+					Log.d(TAG, "result: " + result);
+					
+					end = System.currentTimeMillis();
+					
+					if(result != null)
+						outToClient.writeObject(result);
+					//outToClient.reset();
+					
+					execution_time += (end-start);
+					
+					//outToClient.writeObject(handleTask((TaskRequest)inFromClient.readObject()));
+					
+					/*
+					Class<?> cls = Class.forName(task.name);
+					Object obj = cls.newInstance();
+					
+					Method method = cls.getDeclaredMethod("execute", Integer.class);
+					method.invoke(obj, 4);*/
+				}
+				
+				outToClient.close();
+				inFromClient.close();
+				socket.close();
+				
+				outToClient = null;
+				inFromClient = null;
+				socket = null;
+				task = null;
+				result = null;
+				execution_time = 0;
+				//Toast.makeText(mContext, "Client Connected: " + socket.getInetAddress().getHostAddress(), Toast.LENGTH_SHORT).show();
+				
+			}
+			//socket.close();
+			
+		} 
+		catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} 
+		catch (ClassNotFoundException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+	private Object handleTask(TaskRequest task)
+	{
+		Object result = null;
+		
+		if(task.name.equals("SUM"))
+		{
+			Log.d(TAG, "SUM!!!");
+			result = new Sum((Integer)task.parameters.get(0), (Integer)task.parameters.get(1)).execute();
+		}
+		else if(task.name.equals("BYE"))
+		{
+			Log.d(TAG, "BYE!!!");
+			isConnected = false;
+		}
+		
+		return result;
+	}
+}
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/distribute/Task.java AndroidSource/frameworks/base/services/java/com/android/server/distribute/Task.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/distribute/Task.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/distribute/Task.java	2015-01-27 11:54:29.000000000 +0900
@@ -0,0 +1,6 @@
+package com.android.server.distribute;
+
+public interface Task<T> 
+{
+	T execute();
+}
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/distribute/TaskRequest.java AndroidSource/frameworks/base/services/java/com/android/server/distribute/TaskRequest.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/distribute/TaskRequest.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/distribute/TaskRequest.java	2015-01-27 14:50:57.000000000 +0900
@@ -0,0 +1,17 @@
+package com.android.server.distribute;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+
+public class TaskRequest implements Serializable
+{
+	private static final long serialVersionUID = 1L;
+	public String name;
+	public ArrayList<Object> parameters;
+	
+	public TaskRequest(String name, ArrayList<Object> parameters)
+	{
+		this.name = name;
+		this.parameters = parameters;
+	}
+}
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/location/GpsLocationProvider.java AndroidSource/frameworks/base/services/java/com/android/server/location/GpsLocationProvider.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/location/GpsLocationProvider.java	2016-01-29 15:12:34.499488000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/location/GpsLocationProvider.java	2015-08-11 10:14:32.000000000 +0900
@@ -748,7 +748,7 @@
             if (mEnabled) return;
             mEnabled = true;
         }
-
+        Log.d(TAG, "HELLOOOOO: " + mEnabled);
         sendMessage(ENABLE, 1, null);
     }
 
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/location/RemoteLocationProvider.java AndroidSource/frameworks/base/services/java/com/android/server/location/RemoteLocationProvider.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/location/RemoteLocationProvider.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/location/RemoteLocationProvider.java	2016-03-02 20:32:33.000000000 +0900
@@ -0,0 +1,153 @@
+package com.android.server.location;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+import com.android.internal.location.ProviderProperties;
+import com.android.internal.location.ProviderRequest;
+
+import android.content.Context;
+import android.location.Criteria;
+import android.location.LocationManager;
+import android.location.LocationProvider;
+import android.os.Bundle;
+import android.os.ServiceManager;
+import android.os.WorkSource;
+import android.service.remote.IRemoteService;
+
+public class RemoteLocationProvider implements LocationProviderInterface 
+{
+	//private final String mName;
+    private final ProviderProperties mProperties = new ProviderProperties(
+            false, false, false, false, false, false, false,
+            Criteria.POWER_LOW, Criteria.ACCURACY_COARSE);
+    
+    //private final ILocationManager mLocationManager;
+
+    //private final Location mLocation;
+    private final Bundle mExtras = new Bundle();
+
+    private int mStatus;
+    private long mStatusUpdateTime;
+    private boolean mHasLocation;
+    private boolean mHasStatus;
+    private boolean mEnabled;
+    
+    private IRemoteService mRemoteService;
+
+    private static final String TAG = "RemoteLocationProvider";
+
+    public RemoteLocationProvider()
+    {
+    	mRemoteService = IRemoteService.Stub.asInterface(ServiceManager
+				.getService(Context.REMOTE_SERVICE));
+    }
+    
+    /*public RemoteLocationProvider(String name, ILocationManager locationManager,
+            ProviderProperties properties) {
+        if (properties == null) throw new NullPointerException("properties is null");
+
+        mName = name;
+        mLocationManager = locationManager;
+        mProperties = properties;
+        mLocation = new Location(name);
+    }*/
+
+    @Override
+    public String getName() {
+        return LocationManager.REMOTE_PROVIDER;
+    }
+
+    @Override
+    public ProviderProperties getProperties() {
+        return mProperties;
+    }
+
+    @Override
+    public void disable() {
+        mEnabled = false;
+    }
+
+    @Override
+    public void enable() {
+    	//if(mRemoteService)
+        mEnabled = true;
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return mEnabled;
+    }
+
+    @Override
+    public int getStatus(Bundle extras) {
+        if (mHasStatus) {
+            extras.clear();
+            extras.putAll(mExtras);
+            return mStatus;
+        } else {
+            return LocationProvider.AVAILABLE;
+        }
+    }
+
+    @Override
+    public long getStatusUpdateTime() {
+        //return mStatusUpdateTime;
+    	return -1;
+    }
+
+    /*public void setLocation(Location l) {
+        mLocation.set(l);
+        mHasLocation = true;
+        if (mEnabled) {
+            try {
+                mLocationManager.reportLocation(mLocation, false);
+            } catch (RemoteException e) {
+                Log.e(TAG, "RemoteException calling reportLocation");
+            }
+        }
+    }*/
+
+    /*public void clearLocation() {
+        mHasLocation = false;
+    }
+
+    public void setStatus(int status, Bundle extras, long updateTime) {
+        mStatus = status;
+        mStatusUpdateTime = updateTime;
+        mExtras.clear();
+        if (extras != null) {
+            mExtras.putAll(extras);
+        }
+        mHasStatus = true;
+    }
+
+    public void clearStatus() {
+        mHasStatus = false;
+        mStatusUpdateTime = 0;
+    }*/
+
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        dump(pw, "");
+    }
+
+    public void dump(PrintWriter pw, String prefix) {
+        /*pw.println(prefix + mName);
+        pw.println(prefix + "mHasLocation=" + mHasLocation);
+        pw.println(prefix + "mLocation:");
+        mLocation.dump(new PrintWriterPrinter(pw), prefix + "  ");
+        pw.println(prefix + "mHasStatus=" + mHasStatus);
+        pw.println(prefix + "mStatus=" + mStatus);
+        pw.println(prefix + "mStatusUpdateTime=" + mStatusUpdateTime);
+        pw.println(prefix + "mExtras=" + mExtras);*/
+    }
+
+    @Override
+    public void setRequest(ProviderRequest request, WorkSource source) { }
+
+    @Override
+    public boolean sendExtraCommand(String command, Bundle extras) {
+        return false;
+    }
+}
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/LocationManagerService.java AndroidSource/frameworks/base/services/java/com/android/server/LocationManagerService.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/LocationManagerService.java	2016-01-29 15:12:34.471488000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/LocationManagerService.java	2016-03-02 20:32:10.000000000 +0900
@@ -53,12 +53,15 @@
 import android.os.PowerManager;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.WorkSource;
 import android.provider.Settings;
+import android.service.remote.IRemoteService;
 import android.util.Log;
 import android.util.Slog;
+
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.location.ProviderProperties;
 import com.android.internal.location.ProviderRequest;
@@ -75,6 +78,7 @@
 import com.android.server.location.LocationProviderProxy;
 import com.android.server.location.MockProvider;
 import com.android.server.location.PassiveProvider;
+import com.android.server.location.RemoteLocationProvider;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -147,6 +151,9 @@
     private LocationWorkerHandler mLocationHandler;
     private PassiveProvider mPassiveProvider;  // track passive provider for special cases
     private LocationBlacklist mBlacklist;
+    
+    // ADDED BY JH
+    private IRemoteService mRemoteService;
 
     // --- fields below are protected by mLock ---
     // Set of providers that are explicitly enabled
@@ -197,6 +204,8 @@
         super();
         mContext = context;
         mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
+        mRemoteService = IRemoteService.Stub.asInterface(ServiceManager
+				.getService(Context.REMOTE_SERVICE));
 
         if (D) Log.d(TAG, "Constructed");
 
@@ -353,6 +362,11 @@
             addProviderLocked(gpsProvider);
             mRealProviders.put(LocationManager.GPS_PROVIDER, gpsProvider);
         }
+        
+        // ADDED BY JH
+       /* RemoteLocationProvider remoteProvider = new RemoteLocationProvider();
+        addProviderLocked(remoteProvider);
+        mEnabledProviders.add(remoteProvider.getName());*/
 
         /*
         Load package name(s) containing location provider support.
@@ -1200,6 +1214,7 @@
         }
 
         if (enabled) {
+        	Log.d(TAG, "uPLL provider: " + provider + "enabled: " + enabled);
             p.enable();
             if (listeners > 0) {
                 applyRequirementsLocked(provider);
@@ -1488,6 +1503,7 @@
         }
 
         boolean isProviderEnabled = isAllowedByUserSettingsLocked(name, uid);
+        Log.d(TAG, "Hello: " + isProviderEnabled);
         if (isProviderEnabled) {
             applyRequirementsLocked(name);
         } else {
@@ -1864,6 +1880,18 @@
             Log.w(TAG, "Dropping incomplete location: " + location);
             return;
         }
+        
+        // ADDED BY JH
+        Log.d("APP ", "location start!");
+        try
+		{
+			mRemoteService.sendLocation(location);
+		} catch (RemoteException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+        // ADDED BY JH
 
         mLocationHandler.removeMessages(MSG_LOCATION_CHANGED, location);
         Message m = Message.obtain(mLocationHandler, MSG_LOCATION_CHANGED, location);
@@ -2329,6 +2357,34 @@
         }
     }
 
+    // ADDED BY JH
+    @Override
+	public void setRemoteProviderEnabled(boolean enabled)
+			throws RemoteException
+	{
+    	synchronized (mLock) 
+    	{
+    		Log.d(TAG, "Enabled: " + enabled);
+    		
+    		long identity = Binder.clearCallingIdentity();
+            if (enabled) {
+            	RemoteLocationProvider provider = new RemoteLocationProvider();
+                addProviderLocked(provider);
+                provider.enable();
+                mEnabledProviders.add(provider.getName());
+                mDisabledProviders.remove(provider.getName());
+            } else {
+            	LocationProviderInterface provider = mProvidersByName.get(LocationManager.REMOTE_PROVIDER);
+            	removeProviderLocked(provider);
+                provider.disable();
+                mEnabledProviders.remove(provider.getName());
+                mDisabledProviders.add(provider.getName());
+            }
+            updateProvidersLocked();
+            Binder.restoreCallingIdentity(identity);
+        }
+	}
+    
     private void log(String log) {
         if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Slog.d(TAG, log);
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/remote/Listener.java AndroidSource/frameworks/base/services/java/com/android/server/remote/Listener.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/remote/Listener.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/remote/Listener.java	2016-06-23 20:00:38.000000000 +0900
@@ -0,0 +1,102 @@
+package com.android.server.remote;
+
+import android.content.Context;
+import android.util.Log;
+import android.util.SparseIntArray;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.ArrayList;
+
+public class Listener extends Thread
+{
+	private static final String TAG = "RemoteRequestServer";
+	private static final int SERVERPORT = 55555;
+	
+	private ServerSocket serverSocket;
+	
+	private Thread receiverThread;
+	private Receiver receiver;
+	
+	private final Context mContext;
+	
+	public static SparseIntArray mNodes = new SparseIntArray();
+	private int currentNode = 0;
+	
+	private static ArrayList<String> clientIPs = new ArrayList<String>();
+	private ArrayList<Thread> receiverThreads;
+	
+	public Listener(Context context)
+	{
+		mContext = context;
+		receiverThreads = new ArrayList<Thread>();
+	}
+	
+	public void terminate()
+	{
+		try
+		{
+			if(receiverThreads.size() > 0)
+			{
+				for(Thread t : receiverThreads)
+					t.interrupt();
+			}
+			serverSocket.close();
+			
+		}
+		catch (IOException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+	public static ArrayList<String> getClientIPs(){
+	    return clientIPs;
+	}
+	
+	@Override
+	public void run()
+	{
+		Socket socket = null;
+		
+		try
+		{
+			serverSocket = new ServerSocket(SERVERPORT);
+			
+			while (!Thread.currentThread().isInterrupted())
+			{
+				Log.d(TAG, "RemoteRequestServer successfully started!");
+				socket = serverSocket.accept();
+				socket.setTcpNoDelay(true);
+				socket.setKeepAlive(true);
+				socket.setSoTimeout(0);
+//				Toast.makeText(mContext, "Client Connected: " + socket.getInetAddress().getHostAddress(), Toast.LENGTH_SHORT).show();
+//				ServerIP = serverSocket.getInetAddress().getHostAddress();
+
+				String currentClientIP = socket.getInetAddress().getHostAddress();
+				
+				Log.i(TAG, "Client Connected: " + currentClientIP);
+				
+				clientIPs.add(currentClientIP);
+
+				Log.d(TAG, mNodes.toString());
+				
+				RemoteService.deviceToSN.put(currentClientIP, ++currentNode);
+				
+				receiver = new Receiver(mContext, socket, currentNode);
+				receiverThread = new Thread(receiver);
+				receiverThreads.add(receiverThread);
+				
+				receiverThread.start();
+			}
+			//socket.close();
+			
+		}
+		catch (IOException e)
+		{
+			e.printStackTrace();
+		}
+	}	
+}
\ No newline at end of file
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/remote/MainLooperSpy.java AndroidSource/frameworks/base/services/java/com/android/server/remote/MainLooperSpy.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/remote/MainLooperSpy.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/remote/MainLooperSpy.java	2014-12-27 01:23:50.000000000 +0900
@@ -0,0 +1,48 @@
+package com.android.server.remote;
+
+import java.lang.reflect.Field;
+
+import android.os.Looper;
+import android.os.Message;
+import android.os.MessageQueue;
+import android.util.Log;
+
+public class MainLooperSpy {
+	  private final Field messagesField;
+	  private final Field nextField;
+	  private final MessageQueue mainMessageQueue;
+
+	  public MainLooperSpy() {
+	    try {
+	      Field queueField = Looper.class.getDeclaredField("mQueue");
+	      queueField.setAccessible(true);
+	      messagesField = MessageQueue.class.getDeclaredField("mMessages");
+	      messagesField.setAccessible(true);
+	      nextField = Message.class.getDeclaredField("next");
+	      nextField.setAccessible(true);
+	      Looper mainLooper = Looper.getMainLooper();
+	      mainMessageQueue = (MessageQueue) queueField.get(mainLooper);
+	    } catch (Exception e) {
+	      throw new RuntimeException(e);
+	    }
+	  }
+
+	  public void dumpQueue() {
+	    try {
+	      Message nextMessage = (Message) messagesField.get(mainMessageQueue);
+	      Log.d("MainLooperSpy", "Begin dumping queue");
+	      dumpMessages(nextMessage);
+	      Log.d("MainLooperSpy", "End dumping queue");
+	    } catch (IllegalAccessException e) {
+	      throw new RuntimeException(e);
+	    }
+	  }
+
+	  public void dumpMessages(Message message) throws IllegalAccessException {
+	    if (message != null) {
+	      Log.d("MainLooperSpy", message.toString());
+	      Message next = (Message) nextField.get(message);
+	      dumpMessages(next);
+	    }
+	  }
+	}
\ No newline at end of file
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/remote/ObjectSizeCalculator.java AndroidSource/frameworks/base/services/java/com/android/server/remote/ObjectSizeCalculator.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/remote/ObjectSizeCalculator.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/remote/ObjectSizeCalculator.java	2015-10-22 09:34:34.000000000 +0900
@@ -0,0 +1,190 @@
+package com.android.server.remote;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.HashSet;
+import java.util.Set;
+
+public class ObjectSizeCalculator
+{
+
+	private static final int REFERENCE_SIZE;
+	private static final int HEADER_SIZE;
+	private static final int LONG_SIZE = 8;
+	private static final int INT_SIZE = 4;
+	private static final int BYTE_SIZE = 1;
+	private static final int BOOLEAN_SIZE = 1;
+	private static final int CHAR_SIZE = 2;
+	private static final int SHORT_SIZE = 2;
+	private static final int FLOAT_SIZE = 4;
+	private static final int DOUBLE_SIZE = 8;
+	private static final int ALIGNMENT = 8;
+
+	static
+	{
+		try
+		{
+			if (System.getProperties().get("java.vm.name").toString()
+					.contains("64"))
+			{
+				// java.vm.name is something like “Java HotSpot(TM) 64-Bit
+				// Server VM”
+				REFERENCE_SIZE = 8;
+				HEADER_SIZE = 16;
+			} else
+			{
+				REFERENCE_SIZE = 4;
+				HEADER_SIZE = 8;
+			}
+		} catch (Exception ex)
+		{
+			ex.printStackTrace();
+			throw new AssertionError(ex);
+		}
+	}
+
+	public static long sizeOf(Object o) throws IllegalAccessException
+	{
+		return sizeOf(o, new HashSet());
+	}
+
+	private static long sizeOf(Object o, Set visited)
+			throws IllegalAccessException
+	{
+		if (o == null)
+		{
+			return 0;
+		}
+		ObjectWrapper objectWrapper = new ObjectWrapper(o);
+		if (visited.contains(objectWrapper))
+		{
+			// We have reference graph with cycles.
+			return 0;
+		}
+		visited.add(objectWrapper);
+		long size = HEADER_SIZE;
+		Class clazz = o.getClass();
+		if (clazz.isArray())
+		{
+			if (clazz == long[].class)
+			{
+				long[] objs = (long[]) o;
+				size += objs.length * LONG_SIZE;
+			} else if (clazz == int[].class)
+			{
+				int[] objs = (int[]) o;
+				size += objs.length * INT_SIZE;
+			} else if (clazz == byte[].class)
+			{
+				byte[] objs = (byte[]) o;
+				size += objs.length * BYTE_SIZE;
+			} else if (clazz == boolean[].class)
+			{
+				boolean[] objs = (boolean[]) o;
+				size += objs.length * BOOLEAN_SIZE;
+			} else if (clazz == char[].class)
+			{
+				char[] objs = (char[]) o;
+				size += objs.length * CHAR_SIZE;
+			} else if (clazz == short[].class)
+			{
+				short[] objs = (short[]) o;
+				size += objs.length * SHORT_SIZE;
+			} else if (clazz == float[].class)
+			{
+				float[] objs = (float[]) o;
+				size += objs.length * FLOAT_SIZE;
+			} else if (clazz == double[].class)
+			{
+				double[] objs = (double[]) o;
+				size += objs.length * DOUBLE_SIZE;
+			} else
+			{
+				Object[] objs = (Object[]) o;
+				for (int i = 0; i < objs.length; i++)
+				{
+					size += sizeOf(objs[i], visited) + REFERENCE_SIZE;
+				}
+			}
+			size += INT_SIZE;
+		} else
+		{
+			Field[] fields = o.getClass().getDeclaredFields();
+			for (int i = 0; i < fields.length; i++)
+			{
+				if (Modifier.isStatic(fields[i].getModifiers()))
+				{
+					continue;
+				}
+				fields[i].setAccessible(true);
+				String fieldType = fields[i].getGenericType().toString();
+				if (fieldType.equals("long"))
+				{
+					size += LONG_SIZE;
+				} else if (fieldType.equals("int"))
+				{
+					size += INT_SIZE;
+				} else if (fieldType.equals("byte"))
+				{
+					size += BYTE_SIZE;
+				} else if (fieldType.equals("boolean"))
+				{
+					size += BOOLEAN_SIZE;
+				} else if (fieldType.equals("char"))
+				{
+					size += CHAR_SIZE;
+				} else if (fieldType.equals("short"))
+				{
+					size += SHORT_SIZE;
+				} else if (fieldType.equals("float"))
+				{
+					size += FLOAT_SIZE;
+				} else if (fieldType.equals("double"))
+				{
+					size += DOUBLE_SIZE;
+				} else
+				{
+					size += sizeOf(fields[i].get(o), visited) + REFERENCE_SIZE;
+				}
+			}
+		}
+		if ((size % ALIGNMENT) != 0)
+		{
+			size = ALIGNMENT * (size / ALIGNMENT) + ALIGNMENT;
+		}
+		return size;
+	}
+
+	private static final class ObjectWrapper
+	{
+
+		private Object object;
+
+		public ObjectWrapper(Object object)
+		{
+			this.object = object;
+		}
+
+		@Override
+		public boolean equals(Object obj)
+		{
+			if (obj == this)
+			{
+				return true;
+			}
+			if ((obj == null) || (obj.getClass() != ObjectWrapper.class))
+			{
+				return false;
+			}
+			return object == ((ObjectWrapper) obj).object;
+		}
+
+		@Override
+		public int hashCode()
+		{
+			int hash = 3;
+			hash = 47 * hash + System.identityHashCode(object);
+			return hash;
+		}
+	}
+}
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/remote/Receiver.java AndroidSource/frameworks/base/services/java/com/android/server/remote/Receiver.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/remote/Receiver.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/remote/Receiver.java	2016-09-26 18:10:33.627717490 +0900
@@ -0,0 +1,575 @@
+
+package com.android.server.remote;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.Socket;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+import android.app.ActivityThread;
+import android.app.Instrumentation;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Point;
+import android.hardware.input.IInputManager;
+import android.hardware.input.InputManager;
+import android.location.ILocationManager;
+import android.location.Location;
+import android.location.LocationManager;
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioTrack;
+import android.media.MediaCodec;
+import android.media.MediaFormat;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IVibratorService;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.os.SystemVibrator;
+import android.os.Vibrator;
+import android.service.remote.IRemoteService;
+import android.service.remote.RemoteRequest;
+import android.service.remote.SdPackage;
+import android.util.Log;
+import android.view.Display;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.WindowManager;
+
+public class Receiver implements Runnable {
+    private static final String TAG = "Receiver";
+
+    private Socket clientSocket;
+    private ObjectOutputStream outToClient;
+    private ObjectInputStream inFromClient;
+    private int hashValue;
+    private int sourceDevice;
+
+    // private ObjectOutputStream
+
+    private final Context mContext;
+    private final String mPackageName;
+    private final IVibratorService mService;
+
+    private SystemVibrator mVibratorService;
+    private Vibrator mVibrator;
+
+    private final IInputManager mInputService;
+    private final Instrumentation mInstrumentation;
+    private final ILocationManager mLocationManager;
+    private final IRemoteService mRemoteService;
+
+    // //////////////////////////////////////////////////////
+    private MediaFormat format;
+    private MediaCodec codec;
+    private AudioTrack audioTrack;
+    // variables of format
+    private String mime = "";
+    private int sampleRate = 0, channels = 0, bitrate = 0;
+    private long duration = 0;
+    ByteBuffer[] codecInputBuffers;
+    ByteBuffer[] codecOutputBuffers;
+    // decode start
+    final long TIMEOUT_US = 5000;
+    MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
+    boolean sawInputEOS = false;
+    boolean sawOutputEOS = false;
+    int noOutputCounter = 0;
+    int noOutputCounterLimit = 10;
+    private int test = 0;
+
+    boolean stop = false;
+    long presentationTimeUs = 0;
+    int sampleSize = 0;
+    // /////////////////////////////////////////////
+    
+    private int Xdefault;
+	private int Ydefault;
+
+    // private Object input = null;;
+    private Location location = new Location("");
+
+    // Native Functions
+    native void sendRemoteEvent(int type, int sensor, float[] values, int accuracy, long timestamp,
+            int sourceDevice);
+
+    public Receiver(Context context, Socket clientSocket, int _sourceDevice) {
+        mContext = context;
+        mPackageName = ActivityThread.currentPackageName();
+        mService = IVibratorService.Stub.asInterface(ServiceManager
+                .getService("vibrator"));
+
+        mVibratorService = new SystemVibrator(mContext);
+
+        mInputService = IInputManager.Stub.asInterface(ServiceManager.getService("input"));
+        mInstrumentation = new Instrumentation();
+
+        mLocationManager = ILocationManager.Stub.asInterface(ServiceManager.getService("location"));
+        
+        mRemoteService = IRemoteService.Stub.asInterface(ServiceManager.getService(Context.REMOTE_SERVICE));
+
+        this.clientSocket = clientSocket;
+        hashValue = clientSocket.getInetAddress().getHostAddress().hashCode();
+        this.sourceDevice = _sourceDevice;
+
+        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+		Display display = wm.getDefaultDisplay();
+		Point size = new Point();
+		display.getSize(size);
+		
+		Xdefault = size.x;
+		Ydefault = size.y;
+        
+        Log.d(TAG, "request from: "
+                + this.clientSocket.getInetAddress().getHostAddress());
+
+        try {
+            outToClient = new ObjectOutputStream(
+                    this.clientSocket.getOutputStream());
+            inFromClient = new ObjectInputStream(
+                    this.clientSocket.getInputStream());
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void terminate() 
+    {
+        
+    }
+
+    @Override
+    public void run() {
+        // TODO Auto-generated method stub
+        try {
+            while (!Thread.currentThread().isInterrupted())
+            {
+                Object input = inFromClient.readObject();
+               
+                // request for resources
+                if(input instanceof ResourceRequest)
+                {
+                	// ask RemoteService whether this device is allowed for the resources   
+                	ResourceRequest rr = (ResourceRequest)input;
+                	Log.d(TAG, "Requested: " + Arrays.toString(rr.getRequestedResources()));
+                	RemoteService.waitForResponse.put(clientSocket.getInetAddress().getHostAddress(), outToClient);
+                	mRemoteService.isAllowedForResource(rr.getDeviceName(), clientSocket.getInetAddress().getHostAddress(), rr.getRequestedResources());
+                	//outToClient.writeObject(test);
+                }
+                else if (input instanceof String) {
+                    Log.d(TAG, "String: " + input.toString());
+                    if (input.toString().equals("Hello")) {
+                        Log.d(TAG, "just got Hellooo from client"
+                                + RemoteService.mSensorHandles.toString());
+                        outToClient.writeObject("Gooooood");
+                    }
+                }
+                else if (input instanceof RemoteRequest) {
+                    RemoteRequest request = (RemoteRequest) input;
+
+                    // Log.d(TAG, "Request: " + request.toString());
+
+                    // Handle Request Here!
+                    final long origId = Binder.clearCallingIdentity();
+
+                    try
+                    {
+                        if (request.getType().equalsIgnoreCase("systemcall")) {
+                            if (request.getMethod().compareTo("vibrate") == 0)
+                            {
+//                                Log.d(TAG, "vibrated" + sourceDevice);
+                                mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
+                                mVibrator.vibrate((Long) request.getPara().get(0));
+                                Log.d(TAG, "vibrated: " + sourceDevice);
+//                                mVibratorService.vibrate((Long) request.getPara().get(0));
+                            }
+                            else if (request.getMethod().compareTo("vibrate2") == 0)
+                            {
+                                mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
+                                mVibrator.vibrate((long[]) request.getPara().get(0),
+                                        (Integer) request.getPara().get(1));
+//                                mVibratorService.vibrate((long[]) request.getPara().get(0),
+//                                                (Integer) request.getPara().get(1));
+                            }
+                        }
+                        else if (request.getType().equals("RemoteMusic"))
+                        {
+                            Log.d(TAG, "you are in RemoteRequest, in if RemoteMusic");
+                            RemoteRequest rr = (RemoteRequest) input;
+                            format = new MediaFormat();
+                            try
+                            {
+                                // format = MediaFormat.createAudioFormat(mime,
+                                // sampleRate,
+                                // channels);
+                                // format = ee.getTrackFormat(0);
+                                Log.d(TAG, "the mime is  "
+                                        + (String) rr.getPara().get(0));
+                                format.setString(MediaFormat.KEY_MIME,
+                                        mime = (String) rr.getPara().get(0));
+                                format.setInteger(MediaFormat.KEY_SAMPLE_RATE,
+                                        sampleRate = (Integer) rr.getPara()
+                                                .get(1));
+                                format.setInteger(
+                                        MediaFormat.KEY_CHANNEL_COUNT,
+                                        channels = (Integer) rr.getPara()
+                                                .get(2));
+                                format.setLong(MediaFormat.KEY_DURATION,
+                                        duration = (Long) rr.getPara().get(3));
+
+                            } catch (Exception e)
+                            {
+                                Log.e(TAG,
+                                        "Reading format parameters exception:"
+                                                + e.getMessage());
+                            }
+                            codec = MediaCodec.createDecoderByType("audio/mpeg");
+                            codec.configure(format, null, null, 0);
+                            codec.start();
+
+                            codecInputBuffers = codec.getInputBuffers();
+                            codecOutputBuffers = codec.getOutputBuffers();
+
+                            int channelConfiguration = 0;
+                            if (channels == 1)
+                                channelConfiguration = AudioFormat.CHANNEL_OUT_MONO;
+                            else
+                                channelConfiguration = AudioFormat.CHANNEL_OUT_STEREO;
+
+                            int minSize = AudioTrack.getMinBufferSize(sampleRate,
+                                    channelConfiguration,
+                                    AudioFormat.ENCODING_PCM_16BIT);
+                            audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
+                                    sampleRate, channelConfiguration,
+                                    AudioFormat.ENCODING_PCM_16BIT, minSize,
+                                    AudioTrack.MODE_STREAM);
+                            // feeding
+                            audioTrack.play();
+
+                            Log.d(TAG, "the codec is waiting for you");
+                            test = 0;
+                        }
+                        // music stop
+                        else if (request.getType().equals("StopMusic")) {
+                            Log.d(TAG, "stopping...");
+
+                            if (codec != null)
+                            {
+                                codec.stop();
+                                codec.release();
+                                codec = null;
+                            }
+                            if (audioTrack != null)
+                            {
+                                audioTrack.flush();
+                                audioTrack.release();
+                                audioTrack = null;
+                            }
+                            Log.d(TAG, "music play is done");
+
+                        }
+
+                        // video streaming
+                        else if (request.getType().equalsIgnoreCase("video_streaming"))
+                        {
+                            Log.d(TAG, "11111111111");
+                            if (request.getMethod().equalsIgnoreCase("get_surface")) {
+                                Log.d(TAG, "2222222222");
+                                ComponentName compName = new ComponentName(
+                                        "com.example.surfaceprovider"
+                                        , "com.remote.surfaceprovider.SurfaceProvider");
+                                
+                                Intent intent = new Intent(Intent.ACTION_MAIN);
+                                intent.addCategory("android.intent.category.VIDEO_STREAMING");
+                                intent.setComponent(compName);
+                                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                                
+                                int port = (Integer) request.getPara().get(1);
+                                Log.d(TAG, request.toString() + "  " + port);
+                                intent.putExtra("mode", "video");
+                                intent.putExtra("dcslab", port);
+                                mContext.startActivity(intent);
+
+                                // Intent intent =
+                                // context.getPackageManager().getLaunchIntentForPackage("ParkageName");
+                                // startActivity(intent);
+                            }
+                        }
+                        else if(request.getType().equalsIgnoreCase("request")){
+                            if(request.getMethod().equalsIgnoreCase("motion")){
+                                mRemoteService.connectToServer(clientSocket.getInetAddress().getHostAddress());
+                            }
+                            else if(request.getMethod().equalsIgnoreCase("dummyApp")){
+                            	Log.d(TAG, "HELLO");
+                                ComponentName compName = new ComponentName(
+                                        "com.example.surfaceprovider"
+                                        , "com.remote.surfaceprovider.SurfaceProvider");
+                                
+                                Intent intent = new Intent(Intent.ACTION_MAIN);
+                                intent.addCategory("android.intent.category.VIDEO_STREAMING");
+                                intent.setComponent(compName);
+                                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                                                                
+                                intent.putExtra("mode", "dummyApp");
+                                
+                                mContext.startActivity(intent);
+                            }
+                        }
+                    } finally {
+                        Binder.restoreCallingIdentity(origId);
+                    }
+                } else if (input instanceof RemoteMotionEvent) {
+                    // MotionEvent event = (MotionEvent)input;
+                    RemoteMotionEvent rme = (RemoteMotionEvent) input;
+
+                    // Log.d(TAG, "RemoteMotionEvent: " + rme.toString());
+
+                    /*
+                     * MotionEvent event = MotionEvent.obtain(
+                     * SystemClock.uptimeMillis(), SystemClock.uptimeMillis(),
+                     * rme.getAction(), rme.getX() *
+                     * RemoteRequestHandler.Xdefault, rme.getY() *
+                     * RemoteRequestHandler.Ydefault, 0);
+                     */
+                    /*
+                     * MotionEvent event = MotionEvent.obtain(rme.getDownTime(),
+                     * rme.getEventTime(), rme.getAction(), rme.getX()
+                     * RemoteRequestHandler.Xdefault, rme.getY()
+                     * RemoteRequestHandler.Ydefault, 0);
+                     * event.setSource(rme.getSource());
+                     */
+                    
+                    MotionEvent event = MotionEvent.obtain(
+                            SystemClock.uptimeMillis(),
+                            SystemClock.uptimeMillis(),
+                            rme.getAction(),
+                            rme.getX() * Xdefault,
+                            rme.getY() * Ydefault, sourceDevice << 24);
+
+                    event.setSource(rme.getSource());
+
+//                    Log.d("TouchLatency", "TouchLatency, Node: " + sourceDevice);
+/*                    MotionEvent event;
+                    if (sourceDevice != 1) {
+                        event = MotionEvent.obtain(SystemClock.uptimeMillis(),
+                                SystemClock.uptimeMillis(), rme.getAction(), 500, 500, 0);
+                        event.setSource(rme.getSource());
+                    }
+                    else {
+                        event = MotionEvent.obtain(
+                                SystemClock.uptimeMillis(),
+                                SystemClock.uptimeMillis(),
+                                (rme.getAction() + (sourceDevice << 24)),
+                                rme.getX() * RemoteRequestHandler.Xdefault,
+                                rme.getY() * RemoteRequestHandler.Ydefault, 0);
+
+                        event.setSource(rme.getSource());
+                    }*/
+                    try
+                    {
+                        if (!mInputService.injectInputEvent(event,
+                                InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT))
+                        {
+                            Log.d(TAG, "FAIL!!!!!");
+                        }
+                    } finally
+                    {
+                        event.recycle();
+                    }
+                }
+                /*
+                 * else if(input instanceof RemoteKeyEvent) { }
+                 */
+
+                else if (input instanceof RemoteKeyEvent)
+                {
+                    RemoteKeyEvent rke = (RemoteKeyEvent) input;
+                    // Log.d(TAG, rke.toString());
+
+                    mInstrumentation.sendKeyDownUpSync(rke.getCode());
+                    if (rke.getAction() == KeyEvent.ACTION_DOWN) {
+                        Log.d("KeyLatency", "KeyLatency - server: " + sourceDevice);
+                    }
+                    /*
+                     * KeyEvent event = new KeyEvent(rke.getAction(),
+                     * rke.getCode()); event.setSource(rke.getSource()); try {
+                     * if (!mInputService.injectInputEvent(event,
+                     * InputManager.INJECT_INPUT_EVENT_MODE_ASYNC)) { Log.d(TAG,
+                     * "FAIL!!!!!"); } } finally { event.recycle(); }
+                     */
+                }
+                else if (input instanceof RemoteSensorEvent)
+                {
+                    RemoteSensorEvent rse = (RemoteSensorEvent) input;
+                    // Log.d(TAG, rse.toString());
+                    // Log.d(TAG, )
+
+                    //Log.d(TAG, rse.toString());
+                    
+                    sendRemoteEvent(rse.getType(),
+                    		RemoteService.mSensorHandles.get(rse.getType()),
+                    		rse.getValues(),
+                    		rse.getAccuracy(),
+                    		rse.getTimestamp(),
+                    		sourceDevice);
+
+                    // proximity
+                   /* sendRemoteEvent(21, 21, rse.getValues(),
+                            rse.getAccuracy(),
+                            rse.getTimestamp(),
+                            sourceDevice);*/
+                    //Log.d(TAG, rse.toString() + "source" + sourceDevice);
+
+                }
+
+                else if (input instanceof SdPackage) {
+                    // Log.d(TAG,
+                    // "music play start from request handler (SdPackage)");
+                    noOutputCounter++;
+                    // read a buffer before feeding it to the decoder
+                    if (!sawInputEOS) {
+                        int inputBufIndex = codec.dequeueInputBuffer(TIMEOUT_US);
+                        if (inputBufIndex >= 0) {
+                            ByteBuffer dstBuf = codecInputBuffers[inputBufIndex];
+
+                            SdPackage sdp = (SdPackage) input;
+                            // Log.i(TAG, sdp.toString());
+
+                            sampleSize = sdp.getSampleSize();
+                            byte[] temp_bytearray = new byte[sampleSize];
+                            temp_bytearray = sdp.getSampleData();
+                            // Log.i(TAG, Arrays.toString(temp_bytearray));
+                            dstBuf.clear();
+                            // dstBuf = ByteBuffer.wrap(temp_bytearray);
+                            dstBuf.put(temp_bytearray);
+                            presentationTimeUs = sdp.getPresentationTime();
+
+                            codec.queueInputBuffer(inputBufIndex, 0,
+                                    sampleSize, presentationTimeUs, 0);
+
+                            // Log.d(TAG, "client: queued to inputbuffer " +
+                            // inputBufIndex);
+                            // if (!sawInputEOS) //remote
+                            // extractor.advance(); //remote
+
+                        } else {
+                            // Log.e(TAG, "client: inputBufIndex " +
+                            // inputBufIndex);
+                        }
+                    } // !sawInputEOS
+
+                    // ///////////////////////////////////////////////////////
+                    // MediaCodecInfo df = codec.getCodecInfo();
+                    // byte[] dddd = new byte[8192];
+                    // for(int i=0;i<codecInputBuffers.length;i++){
+                    // for(int j=0;j<codecInputBuffers[i].limit();j++){
+                    // dddd[j] = codecInputBuffers[i].get(j);
+                    // }
+                    // Log.d("debugging", Arrays.toString(dddd));
+                    // }
+
+                    // /////////////////////////////////////////////////////
+
+                    // for (int i = 0; i < codecOutputBuffers.length; i++) {
+                    // Log.d(TAG, String.valueOf(codecOutputBuffers[i]
+                    // .remaining()));
+                    // }
+
+                    // decode to PCM and push it to the AudioTrack player
+                    int res = codec.dequeueOutputBuffer(info, 5000);
+
+                    if (res >= 0) {
+                        int outputBufIndex = res;
+                        ByteBuffer buf = codecOutputBuffers[outputBufIndex];
+                        // ByteBuffer buf =
+                        // codec.getOutputBuffer(outputBufIndex);
+
+                        final byte[] chunk = new byte[info.size];
+                        buf.get(chunk);
+                        buf.clear();
+                        if (chunk.length > 0) {
+                            audioTrack.write(chunk, 0, chunk.length);
+                        }
+
+                        codec.releaseOutputBuffer(outputBufIndex, false);
+
+                        if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
+                            Log.d(TAG, "saw output EOS.");
+                            sawOutputEOS = true;
+                        }
+                    } else if (res == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
+                        Log.d(TAG,
+                                "oh! information of output buffer has been changed");
+                        codecOutputBuffers = codec.getOutputBuffers();
+                        Log.d(TAG, "output buffers have changed.");
+                    } else if (res == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
+                        Log.d(TAG, "oh! the output format changed!");
+                        MediaFormat oformat = codec.getOutputFormat();
+                        Log.d(TAG, "output format has changed to "
+                                + oformat);
+                        Log.d("AudioLatency", "Bravo!!! thank you!! JG and HB !!!!!!! I love you !!");
+                    } else {
+                        Log.d(TAG, "dequeueOutputBuffer returned " + res);
+                    }
+
+                    // Log.d("TAG", String.valueOf(noOutputCounter));
+
+                }
+                else if (input instanceof RemoteLocation)
+                {
+                    RemoteLocation RL = (RemoteLocation) input;
+
+                    location = new Location("");
+
+                    // location.reset();
+                    // location.setProvider(RL.getProvider());
+                    location.setProvider(LocationManager.REMOTE_PROVIDER);
+                    // location.setTime(RL.getTime());
+                    location.setTime(System.currentTimeMillis());
+                    // location.setElapsedRealtimeNanos(RL.getElapsedRealtimeNanos());
+                    location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
+                    location.setLatitude(RL.getLatitude());
+                    location.setLongitude(RL.getLongitude());
+
+                    if (RL.getAltitude() != 0.0f)
+                        location.setAltitude(RL.getAltitude());
+                    if (RL.getSpeed() != 0.0f)
+                        location.setSpeed(RL.getSpeed());
+                    if (RL.getBearing() != 0.0f)
+                        location.setBearing(RL.getBearing());
+                    if (RL.getAccuracy() != 0.0f)
+                        location.setAccuracy(RL.getAccuracy());
+
+                    location.setExtras(RL.getExtras());
+                    location.setIsFromMockProvider(RL.isFromMockProvider());
+
+                    if (location.getExtras() != null)
+                        location.getExtras().putInt("SourceDevice", sourceDevice);
+                    else
+                    {
+                        Bundle bundle = new Bundle();
+                        bundle.putInt("SourceDevice", sourceDevice);
+                        location.setExtras(bundle);
+                    }
+
+                    mLocationManager.reportLocation(location, false);
+                }
+                else
+                    Log.d(TAG, "What is this??");
+
+                // input.
+            }
+
+            clientSocket.close();
+            inFromClient.close();
+            outToClient.close();
+            
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/remote/RemoteKeyEvent.java AndroidSource/frameworks/base/services/java/com/android/server/remote/RemoteKeyEvent.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/remote/RemoteKeyEvent.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/remote/RemoteKeyEvent.java	2016-02-16 20:32:50.000000000 +0900
@@ -0,0 +1,34 @@
+package com.android.server.remote;
+
+import java.io.Serializable;
+
+public class RemoteKeyEvent implements Serializable
+{
+	private static final long serialVersionUID = 1L;
+
+	private final int action;
+	private final int code;
+	private final int source;
+	
+	public RemoteKeyEvent(int action, int code, int source)
+	{
+		this.action = action;
+		this.code = code;
+		this.source = source;
+	}
+	
+	public int getAction()
+	{
+		return action;
+	}
+	
+	public int getCode()
+	{
+		return code;
+	}
+	
+	public int getSource()
+	{
+		return source;
+	}
+}
\ No newline at end of file
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/remote/RemoteLocation.java AndroidSource/frameworks/base/services/java/com/android/server/remote/RemoteLocation.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/remote/RemoteLocation.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/remote/RemoteLocation.java	2016-02-16 20:32:54.000000000 +0900
@@ -0,0 +1,93 @@
+package com.android.server.remote;
+
+import java.io.Serializable;
+
+import android.location.Location;
+import android.os.Bundle;
+
+public class RemoteLocation implements Serializable
+{
+	private static final long serialVersionUID = 1L;
+	
+	private final String mProvider;
+    private final long mTime;
+    private final long mElapsedRealtimeNanos;
+    private final double mLatitude;
+    private final double mLongitude;
+    private final double mAltitude;
+    private final float mSpeed;
+    private final float mBearing;
+    private final float mAccuracy;
+    private final Bundle mExtras;
+    private final boolean mIsFromMockProvider;
+    
+    public RemoteLocation(Location l)
+    {
+    	mProvider = l.getProvider();
+        mTime = l.getTime();
+        mElapsedRealtimeNanos = l.getElapsedRealtimeNanos();
+        mLatitude = l.getLatitude();
+        mLongitude = l.getLongitude();
+        mAltitude = l.getAltitude();
+        mSpeed = l.getSpeed();
+        mBearing = l.getBearing();
+        mAccuracy = l.getAccuracy();
+        mExtras = (l.getExtras() == null) ? null : new Bundle(l.getExtras());
+        mIsFromMockProvider = l.isFromMockProvider();
+    }
+    
+    public String getProvider()
+    {
+    	return mProvider;
+    }
+
+	public long getTime()
+	{
+		return mTime;
+	}
+
+	public long getElapsedRealtimeNanos()
+	{
+		return mElapsedRealtimeNanos;
+	}
+
+	public double getLatitude()
+	{
+		return mLatitude;
+	}
+
+	public double getLongitude()
+	{
+		return mLongitude;
+	}
+
+	public double getAltitude()
+	{
+		return mAltitude;
+	}
+
+	public float getSpeed()
+	{
+		return mSpeed;
+	}
+
+	public float getBearing()
+	{
+		return mBearing;
+	}
+
+	public float getAccuracy()
+	{
+		return mAccuracy;
+	}
+
+	public Bundle getExtras()
+	{
+		return mExtras;
+	}
+
+	public boolean isFromMockProvider()
+	{
+		return mIsFromMockProvider;
+	}
+}
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/remote/RemoteMotionEvent.java AndroidSource/frameworks/base/services/java/com/android/server/remote/RemoteMotionEvent.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/remote/RemoteMotionEvent.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/remote/RemoteMotionEvent.java	2016-02-16 20:32:58.000000000 +0900
@@ -0,0 +1,60 @@
+package com.android.server.remote;
+
+import java.io.Serializable;
+
+public class RemoteMotionEvent implements Serializable
+{
+	private static final long serialVersionUID = 1L;
+	
+	private final long downTime;
+	private final long eventTime;
+	private final float x;
+	private final float y;
+	private final int action;
+	private final int source;
+	
+	public RemoteMotionEvent(long downTime, long eventTime, float x, float y, int action, int source)
+	{
+		this.downTime = downTime;
+		this.eventTime = eventTime;
+		this.x = x;
+		this.y = y;
+		this.action = action;
+		this.source = source;
+	}
+	
+	public long getDownTime()
+	{
+		return downTime;
+	}
+	
+	public long getEventTime()
+	{
+		return eventTime;
+	}
+	
+	public float getX()
+	{
+		return x;
+	}
+	
+	public float getY()
+	{
+		return y;
+	}
+	
+	public int getAction()
+	{
+		return action;
+	}
+	
+	public int getSource()
+	{
+		return source;
+	}
+	
+	public String toString()
+	{
+		return "(" + x + ", " + y + ")";
+	}
+}
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/remote/RemoteSensorEvent.java AndroidSource/frameworks/base/services/java/com/android/server/remote/RemoteSensorEvent.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/remote/RemoteSensorEvent.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/remote/RemoteSensorEvent.java	2016-02-16 20:29:49.000000000 +0900
@@ -0,0 +1,53 @@
+package com.android.server.remote;
+
+import java.io.Serializable;
+
+public class RemoteSensorEvent implements Serializable
+{
+	private static final long serialVersionUID = 1L;
+	
+	private int type;
+	private int sensor;
+	private float values[];
+	private int accuracy;
+	private long timestamp;
+	
+	public RemoteSensorEvent(int type, int sensor, float[] values, int accuracy, long timestamp)
+	{
+		this.type = type;
+		this.sensor = sensor;
+		this.values = values;
+		this.accuracy = accuracy;
+		this.timestamp = timestamp;
+	}
+	
+	public int getType()
+	{
+		return type;
+	}
+	
+	public int getSensor()
+	{
+		return sensor;
+	}
+	
+	public float[] getValues()
+	{
+		return values;
+	}
+	
+	public int getAccuracy()
+	{
+		return accuracy;
+	}
+	
+	public long getTimestamp()
+	{
+		return timestamp;
+	}
+	
+	public String toString()
+	{
+		return "(" + type + ": " + values[0] + ", " + values[1] + ")";
+	}
+}
\ No newline at end of file
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/remote/RemoteService.java AndroidSource/frameworks/base/services/java/com/android/server/remote/RemoteService.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/remote/RemoteService.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/remote/RemoteService.java	2016-09-26 17:23:55.907807739 +0900
@@ -0,0 +1,803 @@
+package com.android.server.remote;
+
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+
+import com.android.server.devicemanager.DeviceManagementService;
+//import android.hardware.SensorEventQueue2;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.hardware.Sensor;
+import android.hardware.SensorEventListener;
+import android.hardware.input.IInputManager;
+import android.hardware.input.InputManager;
+import android.location.ILocationManager;
+import android.location.Location;
+import android.location.LocationManager;
+import android.media.MediaPlayer;
+import android.os.RemoteCallbackList;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.os.Vibrator;
+import android.service.collaboroid.IGeneralMessageListener;
+import android.service.devicemanager.Device;
+import android.service.devicemanager.IDeviceManager;
+import android.service.remote.AppendingObjectOutputStream;
+import android.service.remote.IRemoteService;
+import android.service.remote.RemoteRequest;
+import android.service.remote.SdPackage;
+import android.util.Log;
+import android.util.SparseArray;
+import android.util.SparseIntArray;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+public class RemoteService extends IRemoteService.Stub
+{
+	private static final String TAG = "RemoteService";
+	// private static final int SERVERPORT = 55555;
+
+	// For Settings
+	// private static boolean isEnabled = false;
+	public static boolean ServerOn = false;
+	public static boolean isConnectedToServer = false;
+	
+	private static String serverIP;
+
+	// For Server
+	private Listener server = null;
+	private Thread serverThread = null;
+	private List<String> clientIPs = new ArrayList<String>();
+	/*
+	 * private Socket clientSocket; private ObjectInputStream inFromClient;
+	 */
+
+	// For Client
+	private Thread clientThread = null;
+	private List<String> serverIPs = new ArrayList<String>();
+	
+	// For handling connected devices
+	public static ArrayList<String> connectedDevices;
+	public static HashMap<String, Socket> deviceToSocket;
+	public static HashMap<String, AppendingObjectOutputStream> deviceToOutput;
+    public static SparseArray<ArrayList<AppendingObjectOutputStream>> resourceToOutput;
+    public static HashMap<String, Integer> deviceToSN; // device ip to source device number 
+    
+    /*
+     * devices which wait for response of resource request
+     * device ip to output stream
+     */
+    public static HashMap<String, ObjectOutputStream> waitForResponse;	
+	
+	/*
+	 * private static Socket socketToServer; private static ObjectOutputStream
+	 * out; private static AppendingObjectOutputStream outToServer;
+	 */
+	private Sender mSender;
+	
+	private DeviceManagementService mDeviceService;
+	//private IInputManager im;
+	
+	// for SensorEvent
+	public static SparseIntArray mSensorHandles = new SparseIntArray();
+	public static SparseIntArray mTypeToNumber = new SparseIntArray();
+	public static SparseIntArray mNumberToType = new SparseIntArray();
+	private boolean remoteSensorOn = false;
+	public static SensorEventListener mRemoteListener = null;
+	
+	Context mContext;
+	
+	public static int testValue = 0;
+	
+	// for general message
+	private final RemoteCallbackList<IGeneralMessageListener> mListeners = new RemoteCallbackList<IGeneralMessageListener>();
+	
+	// native functions
+	native void setServerOn(boolean flag);
+	native void sendRemoteEvent(int type, int sensor, float[] values, int accuracy, long timestamp, int sourceDevice);
+
+	public RemoteService(Context context)
+	{
+		mContext = context;
+		mSender = new Sender(context);
+		
+		initRemoteService();
+	}
+	
+	public boolean isServerOn()
+	{
+		return ServerOn;
+	}
+	
+	public void initRemoteService()
+	{
+		connectedDevices = new ArrayList<String>();
+		deviceToOutput = new HashMap<String, AppendingObjectOutputStream>();
+		deviceToSocket = new HashMap<String, Socket>();
+		resourceToOutput = new SparseArray<ArrayList<AppendingObjectOutputStream>>();
+		waitForResponse = new HashMap<String, ObjectOutputStream>();
+		deviceToSN = new HashMap<String, Integer>();
+		
+		for(int i=0; i<Device.RESOURCE_TYPE_SIZE; i++)
+			resourceToOutput.append(i, new ArrayList<AppendingObjectOutputStream>());  
+		
+		mTypeToNumber.put(Sensor.TYPE_ORIENTATION, 0);
+		mTypeToNumber.put(Sensor.TYPE_PROXIMITY, 1);
+		
+		mNumberToType.put(0, Sensor.TYPE_ORIENTATION);
+		mNumberToType.put(1, Sensor.TYPE_PROXIMITY);
+	}
+	
+	public void initConnections()
+	{
+		try 
+		{
+			if(connectedDevices.size() > 0)
+				for(String deviceIP : connectedDevices)
+				{
+					deviceToSocket.get(deviceIP).close();
+					deviceToOutput.get(deviceIP).close();
+		        }
+		}
+		catch (IOException e) 
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		
+		connectedDevices.clear();
+		deviceToOutput.clear();
+		deviceToSocket.clear();
+		//resourceToOutput.clear();
+		waitForResponse.clear();
+		deviceToSN.clear();
+		
+		/////hc
+		clientIPs.clear();
+		
+		for(int i=0; i<Device.RESOURCE_TYPE_SIZE; i++)
+			resourceToOutput.get(i).clear();  
+		
+		mTypeToNumber.clear();
+		mTypeToNumber.put(Sensor.TYPE_ORIENTATION, 0);
+		mTypeToNumber.put(Sensor.TYPE_PROXIMITY, 1);
+		
+		mNumberToType.clear();
+		mNumberToType.put(0, Sensor.TYPE_ORIENTATION);
+		mNumberToType.put(1, Sensor.TYPE_PROXIMITY);
+	}
+	
+	@Override
+	public boolean startServer()
+	{
+		// TODO Auto-generated method stub
+
+		if (!ServerOn)
+		{
+			server = new Listener(mContext);
+			serverThread = new Thread(server);
+			Log.d(TAG, "Starting Listener!");
+			serverThread.start();
+
+			ServerOn = true;
+			//setServerOn(true);
+
+			ILocationManager mLocationManager = ILocationManager.Stub.asInterface(ServiceManager.getService("location"));
+			try
+			{
+				mLocationManager.setRemoteProviderEnabled(true);
+			} catch (RemoteException e)
+			{
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+
+		Log.d(TAG, "startServer - onServer: " + ServerOn);
+
+		return ServerOn;
+	}
+
+	@Override
+	public boolean stopServer()
+	{
+		Log.d(TAG, "HELLO - 0");
+		
+		// TODO Auto-generated method stub
+		if (ServerOn)
+		{
+		    Log.d(TAG, "Stopping Listener: " + serverThread);
+			if (serverThread != null)
+			{
+				server.terminate();
+				serverThread.interrupt();
+
+				ServerOn = false;
+				setServerOn(false);
+				// Settings.System.putString(mContext.getContentResolver(),
+				// "enableRemoteRequest", "false");
+				/*
+				 * } catch (InterruptedException e) { // TODO Auto-generated
+				 * catch block e.printStackTrace(); }
+				 */
+				
+				ILocationManager mLocationManager = ILocationManager.Stub.asInterface(ServiceManager.getService("location"));
+				try
+				{
+					mLocationManager.setRemoteProviderEnabled(false);
+				} catch (RemoteException e)
+				{
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
+		}
+
+		Log.d(TAG, "End stopServer - onServer: " + ServerOn);
+
+		return !ServerOn;
+	}
+
+	@Override
+	public List<String> getClientIPs(){
+	    return clientIPs = Listener.getClientIPs();
+	}
+
+	@Override
+	public List<String> getServerIPs(){
+	    return serverIPs;
+	}
+	
+	@Override
+	public void printServerIPs(){
+	    
+	}
+	
+	@Override
+	public void sendAllrequestVib(RemoteRequest request){
+	    
+	    try{
+	        mSender.sendVib(request);
+	    } catch(IOException e){
+	        e.printStackTrace();
+	    }
+	    
+	}
+	
+	@Override
+	public void sendAllrequest(RemoteRequest request)
+	{
+	    mSender.sendRequestToEveryDevices(request);
+	}
+
+	@Override
+    public void sendAllMusic(int sampleSize, byte[] sampleData, long presentationTime){
+//        Log.d(TAG, "Music testing");
+        
+        SdPackage MDtoSend = new SdPackage(sampleSize, sampleData, presentationTime);
+        
+        mSender.sendMusicData(MDtoSend);
+        
+        /*Collection<AppendingObjectOutputStream> temp = connectedDevices.values();
+        for (AppendingObjectOutputStream outToServer : temp){
+            try {
+                outToServer.writeObject(MDtoSend);
+            } catch (IOException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }*/
+    }
+	
+	@Override
+	public void setConfiguration()
+	{
+		// TODO Auto-generated method stub
+		Log.d(TAG, "RemoteRequesT!!!!");
+	}
+
+	@Override
+	public void setEnabled(boolean isEnabled) throws RemoteException
+	{
+		// TODO Auto-generated method stub
+		// RemoteRequestHandler.isEnabled = isEnabled;
+	}
+
+	@Override
+	public boolean connectToServer(String ip)
+	{
+		
+		
+		return isConnectedToServer;
+	}
+
+	@Override
+	public void disconnectToServer()
+	{
+	    serverIPs.clear();
+        clientIPs.clear();
+        connectedDevices.clear();
+		if (isConnectedToServer)
+		{
+			clientThread.interrupt();
+			
+			// client.terminate();
+			isConnectedToServer = false;
+			// Settings.System.putString(mContext.getContentResolver(),
+			// "enableRemoteRequest", "false");
+			ILocationManager mLocationManager = ILocationManager.Stub.asInterface(ServiceManager.getService("location"));
+			try
+			{
+				mLocationManager.setRemoteProviderEnabled(false);
+			} catch (RemoteException e)
+			{
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+		// }
+		/*
+		 * catch (InterruptedException e) { // TODO Auto-generated catch block
+		 * e.printStackTrace(); }
+		 */
+	}
+	
+	public boolean setRemoteSensorOn(boolean flag, SensorEventListener listener)
+	{
+		remoteSensorOn = flag;
+		mRemoteListener = listener;
+		
+		return remoteSensorOn;
+	}
+	
+	@Override
+	public boolean sendResourceRequests(List<Device> requestDeviceList) throws RemoteException {
+		// TODO Auto-generated method stub
+		mSender.connectToRemoteDevices(requestDeviceList);
+		
+		return true;
+	}
+	
+	@Override
+	/*public int[] isAllowedForResource(String device, int[] resources) throws RemoteException 
+	{
+		// TODO Auto-generated method stub
+		IDeviceManager deviceManager = IDeviceManager.Stub.asInterface(ServiceManager.getService(Context.DEVICE_MANAGEMENT_SERVICE));
+		ArrayList<Integer> allowed = new ArrayList<Integer>();
+		
+		for(int resource : resources)
+			if(deviceManager.isAllowedForResource(device, resource))
+				allowed.add(resource);
+				
+		mSender.addRemoteDevice(allowed, device);
+		int[] ret = new int[allowed.size()];
+		
+		for(int i=0; i<allowed.size(); i++)
+			ret[i] = allowed.get(i);
+		
+		return ret;
+	}*/
+	
+	public boolean isAllowedForResource(String deviceName, String deviceIP, int[] resources) throws RemoteException 
+	{
+		// TODO Auto-generated method stub
+		IDeviceManager deviceManager = IDeviceManager.Stub.asInterface(ServiceManager.getService(Context.DEVICE_MANAGEMENT_SERVICE));
+		
+		deviceManager.showRequestDialog(deviceName, deviceIP, resources);
+		
+		return true;
+	}
+	
+	public boolean respondAllowedResources(String deviceIP, int[] resources)
+	{
+		try {
+			// add remote device
+			mSender.addRemoteDevice(resources, deviceIP);
+			
+			waitForResponse.get(deviceIP).writeObject(resources);
+			waitForResponse.remove(deviceIP);
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return true;
+	}
+	
+	
+	
+	
+	@Override
+	public boolean sendRequest(RemoteRequest request)
+	{
+		if(isConnectedToServer)
+		{
+		}
+		return false;
+	}
+	
+	//for MotionEvent
+	@Override
+	public void sendMotionEvent(MotionEvent event)
+	{
+//		Log.d(TAG, event.toString());
+		if(isConnectedToServer)
+			mSender.sendMotionEvent(event);
+	}
+	
+	// for KeyEvent
+	@Override
+	public void sendKeyEvent(KeyEvent event) throws RemoteException
+	{
+		// TODO Auto-generated method stub
+//		RemoteKeyEvent rke = new RemoteKeyEvent(event.getAction(),
+//				event.getKeyCode(), event.getSource());
+//
+//		if (isConnectedToServer)
+//			client.sendKeyEvent(rke);
+	}
+
+	@Override
+	public void addSensorHandle(int type, int handle)
+	{
+		// TODO Auto-generated method stub
+		Log.d(TAG, mSensorHandles.toString());
+
+		mSensorHandles.put(type, handle);
+	}
+	
+	@Override
+	public void removeSensorHandle(int type)
+	{
+		// TODO Auto-generated method stub
+		Log.d(TAG, "type: " + type);
+		mSensorHandles.delete(type);
+	}
+	
+	@Override
+	public void sendSensorEvent(int type, int sensor, float[] values,
+			int accuracy, long timestamp)
+	{
+		RemoteSensorEvent rse = new RemoteSensorEvent(type, sensor, values,
+				accuracy, timestamp);
+
+		if (isConnectedToServer)
+		    mSender.sendSensorEvent(rse);
+	}
+	
+	@Override
+	public int getVideoPlayers(){
+	    int numberOfPlayers = 0;
+	    if(isConnectedToServer){
+	        numberOfPlayers = resourceToOutput.get(Device.RESOURCE_TYPE_VIDEO).size();
+	    }
+	    return numberOfPlayers;
+	}
+	
+	@Override
+	public void sendVideoSignal(int vport){
+	    if(isConnectedToServer){
+	        mSender.sendVideoSignal(vport);
+	    }
+	}
+	
+	
+	public void sendMusicData(int sampleSize, byte[] sampleData, long presentationTime){
+
+		
+		SdPackage MDtoSend = new SdPackage(sampleSize, sampleData, presentationTime);
+		
+		if(isConnectedToServer){
+		    mSender.sendMusicData(MDtoSend);
+		}
+	}
+	
+	@Override
+	public void sendLocation(Location location)
+	{
+		if(isConnectedToServer)
+			mSender.sendLocation(location);
+	}
+	
+	Object sendRountTripRequest(RemoteRequest request)
+	{
+		return null;
+	}
+
+	@Override
+	public void testOperation() throws RemoteException
+	{
+		Log.d(TAG, "testOperation - START!");
+
+		for(int i=0; i<Device.RESOURCE_TYPE_SIZE; i++)
+			Log.d(TAG, i + " - " + resourceToOutput.get(i).size());
+				
+	}
+	
+	public void playMusic()
+	{
+		Log.d(TAG, "playMusic - START!");
+		MediaPlayer mp = new MediaPlayer();
+		try
+		{
+			mp.setDataSource("/storage/emulated/legacy/Music/sabbun.mp3");
+			mp.prepare();
+		} catch (IllegalArgumentException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (SecurityException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IllegalStateException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e)
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		// mp.start();
+	}
+	
+	public void testMethod(int value)
+	{
+		testValue = value;
+	}
+	
+	@Override  
+	public void testVibrate() throws RemoteException
+	{
+		// TODO Auto-generated method stub
+//	    ArrayList<Object> para = new ArrayList<Object>();
+//	    para.add("100");
+//	    RemoteRequest request = new RemoteRequest("systemCall", "vibrate", para);
+//	    
+//        client.send(request);
+        Vibrator v = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
+        
+        v.vibrate(200);
+		
+	}
+	@Override
+	public void testMusic() throws RemoteException
+	{
+		// TODO Auto-generated method stub
+		
+	}
+	
+	@Override
+	public void testVideo() throws RemoteException
+	{
+		// TODO Auto-generated method stub
+		
+	}
+	
+	@Override
+	public void testTouch() throws RemoteException
+	{
+		// TODO Auto-generated method stub
+		IInputManager mInputService = IInputManager.Stub.asInterface(ServiceManager.getService("input"));
+		
+		MotionEvent event = MotionEvent.obtain(
+				SystemClock.uptimeMillis(),
+				SystemClock.uptimeMillis(), 
+				(MotionEvent.ACTION_DOWN + (1 << 24)),
+				100,
+				100, 0);
+		
+				event.setSource(MotionEvent.TOOL_TYPE_FINGER);
+
+		try
+		{
+			if (!mInputService.injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT))
+			{
+				Log.d(TAG, "FAIL!!!!!");
+			}
+		}
+		finally
+		{
+			event.recycle();
+		}
+		
+		for(int i=1; i<10; i++)
+		{
+			MotionEvent event1 = MotionEvent.obtain(
+					SystemClock.uptimeMillis(),
+					SystemClock.uptimeMillis(), 
+					(MotionEvent.ACTION_MOVE + (1 << 24)),
+					100 * i,
+					100 * i, 0);
+			
+					event1.setSource(MotionEvent.TOOL_TYPE_FINGER);
+	
+			try
+			{
+				if (!mInputService.injectInputEvent(event1, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT))
+				{
+					Log.d(TAG, "FAIL!!!!!");
+				}
+			}
+			finally
+			{
+				event.recycle();
+			}
+		}
+		
+		MotionEvent event2 = MotionEvent.obtain(
+				SystemClock.uptimeMillis(),
+				SystemClock.uptimeMillis(), 
+				(MotionEvent.ACTION_UP + (1 << 24)),
+				900,
+				900, 0);
+		
+				event2.setSource(MotionEvent.TOOL_TYPE_FINGER);
+
+		try
+		{
+			if (!mInputService.injectInputEvent(event2, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT))
+			{
+				Log.d(TAG, "FAIL!!!!!");
+			}
+		}
+		finally
+		{
+			event.recycle();
+		}
+	}
+	
+	@Override
+	public void testKey() throws RemoteException
+	{
+		// TODO Auto-generated method stub
+		
+	}
+	
+	@Override
+	public void testSensor() throws RemoteException
+	{
+		// TODO Auto-generated method stub
+		new Thread(new Runnable()
+		{
+			@Override
+			public void run()
+			{
+				float[] temp;
+				
+				for(int i=0; i<10; i++)
+				{
+					temp = new float[3];
+					temp[0] = 10;
+					temp[1] = 20;
+					temp[2] = 30;
+				
+				
+				//SensorEvent se = new SensorEvent(temp, 0, 0, 0);
+				
+				//Log.d(TAG, remoteSensorOn + " - " + se.toString());
+				
+				//sendRemoteEvent(Sensor.TYPE_REMOTE_SENSOR, Sensor.TYPE_REMOTE_SENSOR, temp, 0, 1000, 1);
+				
+				sendRemoteEvent(3,
+						32, 
+						temp,
+						0, 
+						System.currentTimeMillis(),
+						1);
+				
+				}
+			}
+		}).start();
+	}
+	
+	@Override
+	public void testLocation() throws RemoteException
+	{
+		// TODO Auto-generated method stub
+		new Thread(new Runnable()
+		{
+			@Override
+			public void run()
+			{
+				ILocationManager mLocationManager = ILocationManager.Stub.asInterface(ServiceManager.getService("location"));
+				
+				for(int i=0; i<10; i++)
+				{
+					Location location = new Location(LocationManager.GPS_PROVIDER);
+					//location.setProvider(LocationManager.GPS_PROVIDER);
+					location.setAccuracy(34);
+					location.setTime(System.currentTimeMillis());
+					location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
+					location.setLatitude((Math.random()*10));
+					location.setLongitude((Math.random()*10));
+					
+					try
+					{
+						mLocationManager.reportLocation(location, false);
+					} 
+					catch (RemoteException e)
+					{
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+					
+					try {
+                        Thread.sleep(1000);
+                    } catch (InterruptedException e) {
+                        // TODO Auto-generated catch block
+                        e.printStackTrace();
+                    }
+					
+//					Location location2 = new Location(LocationManager.REMOTE_PROVIDER);
+					//location.setProvider(LocationManager.GPS_PROVIDER);
+//					location2.setAccuracy(34);
+//					location2.setTime(System.currentTimeMillis());
+//					location2.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
+//					location2.setLatitude((10-i)*123.456);
+//					location2.setLongitude((10-i)*123.456);
+//					
+//					try
+//					{
+//						mLocationManager.reportLocation(location2, false);
+//					} 
+//					catch (RemoteException e)
+//					{
+//						// TODO Auto-generated catch block
+//						e.printStackTrace();
+//					}
+					//location.reset();
+				}
+			}
+		}).start();
+	}
+	
+	public void requestMotionEvents() throws RemoteException{
+	    ArrayList<Object> para = new ArrayList<Object>();
+	    RemoteRequest request = new RemoteRequest("request", "motion", para);
+	    sendAllrequest(request);
+	}
+	
+	public void launchDummyApp(){
+	    ArrayList<Object> para = new ArrayList<Object>();
+        RemoteRequest request = new RemoteRequest("request", "dummyApp", para);
+        sendAllrequest(request);
+	}
+	@Override
+	public void registerListener(IGeneralMessageListener listener) throws RemoteException {
+		// TODO Auto-generated method stub
+		mListeners.register(listener);
+	}
+	@Override
+	public void unregisterListener(IGeneralMessageListener listener) throws RemoteException {
+		// TODO Auto-generated method stub
+		mListeners.unregister(listener);
+	}
+	
+	public void sendMessageToListener(String msg)
+	{
+		final int length = mListeners.beginBroadcast();
+		for(int i=0; i<length; i++)
+		{
+			final IGeneralMessageListener listener = mListeners.getBroadcastItem(i);
+			if(listener != null)
+			{
+				try {
+					listener.onMessageReceived(msg);
+				} catch (RemoteException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
+		}
+		mListeners.finishBroadcast();
+	}
+}
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/remote/ResourceRequest.java AndroidSource/frameworks/base/services/java/com/android/server/remote/ResourceRequest.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/remote/ResourceRequest.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/remote/ResourceRequest.java	2016-06-22 20:40:33.000000000 +0900
@@ -0,0 +1,27 @@
+package com.android.server.remote;
+
+import java.io.Serializable;
+
+public class ResourceRequest implements Serializable
+{
+	private static final long serialVersionUID = 1L;
+	
+	private String deviceName;
+	private int[] resources;
+	
+	public ResourceRequest(String dn, int[] rs)
+	{
+		deviceName = dn;
+		resources = rs;
+	}
+	
+	public String getDeviceName()
+	{
+		return deviceName;
+	}
+
+	public int[] getRequestedResources()
+	{
+		return resources;
+	}
+}
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/remote/Sender2.java AndroidSource/frameworks/base/services/java/com/android/server/remote/Sender2.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/remote/Sender2.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/remote/Sender2.java	2016-02-18 10:38:19.000000000 +0900
@@ -0,0 +1,277 @@
+package com.android.server.remote;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import android.content.Context;
+import android.graphics.Point;
+import android.location.Location;
+import android.service.devicemanager.Device;
+import android.service.remote.AppendingObjectOutputStream;
+import android.service.remote.RemoteRequest;
+import android.service.remote.SdPackage;
+import android.util.Log;
+import android.util.SparseArray;
+import android.view.Display;
+import android.view.MotionEvent;
+import android.view.WindowManager;
+
+public class Sender2 implements Runnable
+{
+	private static final String TAG = "RemoteService_Sender";
+    private static final int SERVERPORT = 55555;
+	
+    private ArrayList<String> connectedDevices;
+    private HashMap<String, AppendingObjectOutputStream> deviceToOutput;
+    
+    private SparseArray<ArrayList<AppendingObjectOutputStream>> resourceToOutput;
+    
+    private int Xdefault;
+	private int Ydefault;
+	
+	public Sender2(Context context)
+	{
+		connectedDevices = new ArrayList<String>();
+		deviceToOutput = new HashMap<String, AppendingObjectOutputStream>();
+		resourceToOutput = new SparseArray<ArrayList<AppendingObjectOutputStream>>();
+		
+		WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+		Display display = wm.getDefaultDisplay();
+		Point size = new Point();
+		display.getSize(size);
+		
+		Xdefault = size.x;
+		Ydefault = size.y;
+	}
+	
+	// for resource request
+	public boolean connectToRemoteDevice(Device device)
+	{
+		try 
+		{
+			InetAddress deviceAddr;
+			Socket socketToDevice;
+			AppendingObjectOutputStream outToDevice;
+	    
+			deviceAddr = InetAddress.getByName(device.ipaddress);
+	        socketToDevice = new Socket(deviceAddr, SERVERPORT);
+	        socketToDevice.setTcpNoDelay(true);
+	        socketToDevice.setKeepAlive(true);
+	        socketToDevice.setSoTimeout(0);
+	        // serverIPs.add(serverAddr.getHostAddress());
+	        
+	        ObjectOutputStream out = new ObjectOutputStream(socketToDevice
+	                .getOutputStream());
+	        ObjectInputStream in = new ObjectInputStream(socketToDevice.getInputStream());
+	
+	        out.writeObject(device.askedResources);
+	        int[] responseFromServer = (int[])in.readObject();
+	
+	        if (responseFromServer.length > 0)
+	        {
+	            Log.d(TAG, "Successfully connected to: " + deviceAddr
+	            		+ "allowed: " + responseFromServer.toString());
+	            RemoteService.isConnectedToServer = true;
+	            outToDevice = new AppendingObjectOutputStream(socketToDevice.getOutputStream());
+	            
+	            connectedDevices.add(device.ipaddress);
+	            RemoteService.deviceToSocket.put(device.ipaddress, socketToDevice);
+	            deviceToOutput.put(device.ipaddress, outToDevice);
+	        }
+	        else
+	        	socketToDevice.close();
+        
+		} catch (UnknownHostException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (ClassNotFoundException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+		
+		return true;
+	}
+	
+	// for communication
+	public boolean connectToRemoteDevice(String deviceIP)
+	{
+		try 
+		{
+			InetAddress deviceAddr;
+			Socket socketToDevice;
+			AppendingObjectOutputStream outToDevice;
+	    
+			deviceAddr = InetAddress.getByName(deviceIP);
+	        socketToDevice = new Socket(deviceAddr, SERVERPORT);
+	        socketToDevice.setTcpNoDelay(true);
+	        socketToDevice.setKeepAlive(true);
+	        socketToDevice.setSoTimeout(0);
+	        // serverIPs.add(serverAddr.getHostAddress());
+	        
+	        ObjectOutputStream out = new ObjectOutputStream(socketToDevice
+	                .getOutputStream());
+	        ObjectInputStream in = new ObjectInputStream(socketToDevice.getInputStream());
+	
+	        out.writeObject("Hello");
+	        String responseFromServer = in.readObject().toString();
+	
+	        if (responseFromServer.equals("Gooooood"))
+	        {
+	            Log.d(TAG, "Successfully connected to: " + deviceAddr);
+	            RemoteService.isConnectedToServer = true;
+	            outToDevice = new AppendingObjectOutputStream(socketToDevice.getOutputStream());
+	            
+	            connectedDevices.add(deviceIP);
+	            RemoteService.deviceToSocket.put(deviceIP, socketToDevice);
+	            deviceToOutput.put(deviceIP, outToDevice);
+	        }
+	        else
+	        	socketToDevice.close();
+        
+		} catch (UnknownHostException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (ClassNotFoundException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+		
+		return true;
+	}
+	
+	public boolean connectToRemoteDevices(List<Device> devices)
+	{
+		for(Device device : devices)
+			connectToRemoteDevice(device);
+	        
+		return true;
+	}
+	
+	public boolean disconnectAllDevices()
+	{
+		try 
+		{
+			for(String device : connectedDevices)
+			{
+				RemoteService.deviceToSocket.get(device).close();
+				deviceToOutput.get(device).close();
+	        }
+			RemoteService.deviceToSocket.clear();
+			deviceToOutput.clear();
+		}
+		catch (IOException e) 
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		
+		return true;
+	}
+	
+	public boolean addRemoteDevice(ArrayList<Integer> resources, String deviceIP)
+	{
+		if(!RemoteService.deviceToSocket.containsKey(deviceIP))
+			connectToRemoteDevice(deviceIP);
+		
+		for(int resource : resources)
+		{
+			if(resourceToOutput.get(resource) == null)
+				resourceToOutput.put(resource, new ArrayList<AppendingObjectOutputStream>());  
+		
+			resourceToOutput.get(resource).add(deviceToOutput.get(deviceIP));
+		}
+		return true;
+	}
+	
+	public boolean sendRequest(RemoteRequest request)
+	{
+		
+        return true;
+	}
+	
+	public void sendMotionEvent(MotionEvent event)
+	{
+		float x = event.getX();
+		float y = event.getY();
+		
+		RemoteMotionEvent rme = new RemoteMotionEvent(event.getDownTime(),
+				event.getEventTime(), x / Xdefault, y / Ydefault,
+				event.getAction(), event.getSource());
+
+		try 
+		{
+			for (AppendingObjectOutputStream output : resourceToOutput.get(Device.RESOURCE_TYPE_TOUCH))
+				output.writeObject(rme);
+		} 
+		catch (IOException e) 
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+	public void sendSensorEvent(RemoteSensorEvent rse)
+	{
+		try 
+		{
+			for (AppendingObjectOutputStream output : resourceToOutput.get(Device.RESOURCE_TYPE_SENSOR))
+				output.writeObject(rse);
+		} 
+		catch (IOException e) 
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+	public void sendLocation(Location location)
+	{
+		// TODO Auto-generated method stub
+		RemoteLocation RL = new RemoteLocation(location);
+		
+		try 
+		{
+			for (AppendingObjectOutputStream output : resourceToOutput.get(Device.RESOURCE_TYPE_LOCATION))
+				output.writeObject(RL);
+		} 
+		catch (IOException e) 
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+	public void sendMusicData(SdPackage MDtoSend)
+	{
+		try 
+		{
+			for (AppendingObjectOutputStream output : resourceToOutput.get(Device.RESOURCE_TYPE_AUDIO))
+				output.writeObject(MDtoSend);
+		} 
+		catch (IOException e) 
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+	@Override
+	public void run() 
+	{
+		// TODO Auto-generated method stub
+		
+	}
+}
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/remote/Sender_.java AndroidSource/frameworks/base/services/java/com/android/server/remote/Sender_.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/remote/Sender_.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/remote/Sender_.java	2016-06-23 21:44:46.000000000 +0900
@@ -0,0 +1,137 @@
+package com.android.server.remote;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import android.service.devicemanager.Device;
+import android.service.remote.AppendingObjectOutputStream;
+import android.util.Log;
+
+public class Sender_ implements Runnable
+{
+	private static final String TAG = "RemoteService_Sender";
+    private static final int SERVERPORT = 55555;
+    
+	String dstAddr;
+	int[] resourceTypes;
+	boolean isRequest;
+	
+	private String myName;
+	
+	// native functions
+	native void setServerOn(boolean flag);
+	
+	public Sender_(String myName, String deviceIP)
+	{
+		this.myName = myName;
+		dstAddr = deviceIP;
+		isRequest = false;
+	}
+	
+	public Sender_(String myName, String deviceIP, int[] resources)
+	{
+		this.myName = myName;
+		dstAddr = deviceIP;
+		isRequest = true;
+		ArrayList<Integer> temp = new ArrayList<Integer>();
+		
+		for(int i=0; i<Device.RESOURCE_TYPE_SIZE; i++)
+			if(resources[i] == 1)
+				temp.add(i);
+		
+		resourceTypes = new int[temp.size()];
+		
+		for(int i=0; i<temp.size(); i++)
+			resourceTypes[i] = temp.get(i);
+	}
+	
+	@Override
+	public void run() {
+		// TODO Auto-generated method stub
+		try 
+		{
+			InetAddress deviceAddr;
+			Socket socketToDevice;
+			AppendingObjectOutputStream outToDevice;
+	    
+			deviceAddr = InetAddress.getByName(dstAddr);
+	        socketToDevice = new Socket(deviceAddr, SERVERPORT);
+	        socketToDevice.setTcpNoDelay(true);
+	        socketToDevice.setKeepAlive(true);
+	        socketToDevice.setSoTimeout(0);
+	        // serverIPs.add(serverAddr.getHostAddress());
+	        
+	        ObjectOutputStream out = new ObjectOutputStream(socketToDevice
+	                .getOutputStream());
+	        ObjectInputStream in = new ObjectInputStream(socketToDevice.getInputStream());
+	
+	        if(isRequest)
+	        {
+	        	out.writeObject(new ResourceRequest(myName, resourceTypes));
+	        	int[] responseFromServer = (int[])in.readObject();
+	        	Log.d(TAG, "Allowed: " + Arrays.toString(responseFromServer));
+	        	
+	        	if (responseFromServer.length > 0)
+		        {
+	        		if(responseFromServer.length != resourceTypes.length)
+	        			Log.d(TAG, "ask != allowed");
+	        		
+	        		for(int i : responseFromServer)
+	    				if(i == Device.RESOURCE_TYPE_SENSOR)
+	    				{
+	    					setServerOn(true);
+	    					break;
+	    				}
+	        		
+		            Log.d(TAG, "Successfully connected to: " + deviceAddr);
+		            RemoteService.isConnectedToServer = true;
+		            outToDevice = new AppendingObjectOutputStream(socketToDevice.getOutputStream());
+		            
+		            RemoteService.connectedDevices.add(dstAddr);
+		            RemoteService.deviceToSocket.put(dstAddr, socketToDevice);
+		            RemoteService.deviceToOutput.put(dstAddr, outToDevice);
+		            
+		            for(String addr : RemoteService.connectedDevices)
+		            	Log.d(TAG, "connected: " + addr);
+		        }
+		        else
+		        	socketToDevice.close();
+	        }
+	        else
+	        {
+	        	out.writeObject("Hello");
+	        	String responseFromServer = in.readObject().toString();
+	        	
+	        	if (responseFromServer.equals("Gooooood"))
+		        {
+		            Log.d(TAG, "Successfully connected to: " + deviceAddr);
+		            RemoteService.isConnectedToServer = true;
+		            outToDevice = new AppendingObjectOutputStream(socketToDevice.getOutputStream());
+		            
+		            RemoteService.connectedDevices.add(dstAddr);
+		            RemoteService.deviceToSocket.put(dstAddr, socketToDevice);
+		            RemoteService.deviceToOutput.put(dstAddr, outToDevice);
+		        }
+		        else
+		        	socketToDevice.close();
+	        }
+	        
+	    } catch (UnknownHostException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (ClassNotFoundException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+	}
+
+}
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/remote/Sender.java AndroidSource/frameworks/base/services/java/com/android/server/remote/Sender.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/remote/Sender.java	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/remote/Sender.java	2016-09-26 17:16:10.571822749 +0900
@@ -0,0 +1,322 @@
+package com.android.server.remote;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import android.content.Context;
+import android.graphics.Point;
+import android.location.Location;
+import android.os.Build;
+import android.provider.Settings.Secure;
+import android.service.devicemanager.Device;
+import android.service.remote.AppendingObjectOutputStream;
+import android.service.remote.RemoteRequest;
+import android.service.remote.SdPackage;
+import android.util.Log;
+import android.util.SparseArray;
+import android.view.Display;
+import android.view.MotionEvent;
+import android.view.WindowManager;
+
+public class Sender
+{
+	private static final String TAG = "RemoteService_Sender";
+    private static final int SERVERPORT = 55555;
+	
+    private int Xdefault;
+	private int Ydefault;
+	
+	/*private ArrayList<String> connectedDevices = RemoteService.connectedDevices;
+	private HashMap<String, Socket> deviceToSocket = RemoteService.deviceToSocket;
+	private HashMap<String, AppendingObjectOutputStream> deviceToOutput = RemoteService.deviceToOutput;
+    private SparseArray<ArrayList<AppendingObjectOutputStream>> resourceToOutput = RemoteService.resourceToOutput;*/
+    
+    private Thread connectionThread;
+    private Sender_ mSender;
+    
+    private String myName;
+	
+	public Sender(Context context)
+	{
+		WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+		Display display = wm.getDefaultDisplay();
+		Point size = new Point();
+		display.getSize(size);
+		
+		Xdefault = size.x;
+		Ydefault = size.y;
+		
+		//myName = capitalize(Secure.getString(context.getContentResolver(),
+	    //            Secure.ANDROID_ID));
+		
+		myName = capitalize(Build.SERIAL); 
+	}
+	
+	// for resource request
+	public boolean connectToRemoteDevice(Device device)
+	{
+		mSender = new Sender_(myName, device.ipaddress, device.askedResources);
+		connectionThread = new Thread(mSender);
+		connectionThread.start();
+		
+		return true;
+	}
+	
+	// for communication
+	public boolean connectToRemoteDevice(String deviceIP)
+	{
+		mSender = new Sender_(myName, deviceIP);
+		connectionThread = new Thread(mSender);
+		connectionThread.start();
+		
+		return true;
+	}
+	
+	public boolean connectToRemoteDevices(List<Device> devices)
+	{
+		for(Device device : devices)
+			connectToRemoteDevice(device);
+	        
+		return true;
+	}
+	
+	public boolean disconnectAllDevices()
+	{
+		try 
+		{
+			for(String device : RemoteService.connectedDevices)
+			{
+				RemoteService.deviceToSocket.get(device).close();
+				RemoteService.deviceToOutput.get(device).close();
+	        }
+			RemoteService.deviceToSocket.clear();
+			RemoteService.deviceToOutput.clear();
+		}
+		catch (IOException e) 
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		
+		return true;
+	}
+	
+	public boolean addRemoteDevice(ArrayList<Integer> resourceTypes, String deviceIP)
+	{
+		if(!RemoteService.deviceToSocket.containsKey(deviceIP))
+		{
+			connectToRemoteDevice(deviceIP);
+			try {
+				connectionThread.join();
+			} catch (InterruptedException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+		
+		for(int resourceType : resourceTypes)
+		{
+			if(RemoteService.deviceToOutput.get(deviceIP) != null)
+				RemoteService.resourceToOutput.get(resourceType).add(RemoteService.deviceToOutput.get(deviceIP));
+			else
+				Log.d(TAG, resourceType + " is NULL!!!!!!!!");
+			
+		}
+		
+		return true;
+	}
+	
+	public boolean addRemoteDevice(int[] resourceTypes, String deviceIP)
+	{
+		if(!RemoteService.deviceToSocket.containsKey(deviceIP))
+		{
+			connectToRemoteDevice(deviceIP);
+			try {
+				connectionThread.join();
+			} catch (InterruptedException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+		
+		for(int resourceType : resourceTypes)
+		{
+			if(RemoteService.deviceToOutput.get(deviceIP) != null)
+				RemoteService.resourceToOutput.get(resourceType).add(RemoteService.deviceToOutput.get(deviceIP));
+			else
+				Log.d(TAG, resourceType + " is NULL!!!!!!!!");
+			
+		}
+		
+		return true;
+	}
+	
+	public boolean respondAllowedResources(String deviceIP, int[] resources)
+	{
+		if(RemoteService.deviceToOutput.get(deviceIP) != null)
+		{
+			try 
+			{
+				AppendingObjectOutputStream output = RemoteService.deviceToOutput.get(deviceIP);
+				output.writeObject(resources);
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			return true;
+		}
+		return false;
+	}
+	
+	public boolean sendRequestToEveryDevices(RemoteRequest request)
+	{
+		try 
+		{
+			for(String deviceIP : RemoteService.connectedDevices)
+				RemoteService.deviceToOutput.get(deviceIP).writeObject(request);
+			
+			
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return true;
+    }
+	
+	public void sendVib(RemoteRequest request) throws IOException{
+	    
+	    for (AppendingObjectOutputStream output : RemoteService.resourceToOutput.get(Device.RESOURCE_TYPE_VIBRATOR))
+        {
+            if(output == null)
+                Log.d(TAG, "NULL!!!!!!!!");
+            else
+                output.writeObject(request);
+        }
+	}
+	
+	
+	public void sendMotionEvent(MotionEvent event)
+	{
+		//Log.d(TAG, "1: " + event.toString());
+		
+		float x = event.getX();
+		float y = event.getY();
+		
+		RemoteMotionEvent rme = new RemoteMotionEvent(event.getDownTime(),
+				event.getEventTime(), x / Xdefault, y / Ydefault,
+				event.getAction(), event.getSource());
+		
+		
+
+		try 
+		{
+			//Log.d(TAG, "2: " + RemoteService.resourceToOutput.get(Device.RESOURCE_TYPE_TOUCH).size());
+			
+			for (AppendingObjectOutputStream output : RemoteService.resourceToOutput.get(Device.RESOURCE_TYPE_TOUCH))
+			{
+				if(output == null)
+					Log.d(TAG, "NULL!!!!!!!!");
+				else
+					output.writeObject(rme);
+			}
+		} 
+		catch (IOException e) 
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+	public void sendSensorEvent(RemoteSensorEvent rse)
+	{
+		try 
+		{
+			//Log.d(TAG, rse.toString());
+			
+			for (AppendingObjectOutputStream output : RemoteService.resourceToOutput.get(Device.RESOURCE_TYPE_SENSOR))
+				output.writeObject(rse);
+		} 
+		catch (IOException e) 
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+	public void sendLocation(Location location)
+	{
+		// TODO Auto-generated method stub
+		RemoteLocation RL = new RemoteLocation(location);
+		
+		try 
+		{
+			for (AppendingObjectOutputStream output : RemoteService.resourceToOutput.get(Device.RESOURCE_TYPE_LOCATION))
+				output.writeObject(RL);
+		} 
+		catch (IOException e) 
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+	public void sendMusicData(SdPackage MDtoSend)
+	{
+		try 
+		{
+			for (AppendingObjectOutputStream output : RemoteService.resourceToOutput.get(Device.RESOURCE_TYPE_AUDIO))
+				output.writeObject(MDtoSend);
+		} 
+		catch (IOException e) 
+		{
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+	public void sendVideoSignal(int vport){
+	    Log.d(TAG, "VideoSignal: " + vport);
+	    
+	    RemoteRequest request = new RemoteRequest();
+	    ArrayList<Object> vInfo = new ArrayList<Object>();
+	    vInfo.add(0, vport);
+	    vInfo.add(1, vport);
+	    request.set("video_streaming", "get_surface", vInfo);
+	    
+	    for(AppendingObjectOutputStream output : RemoteService.resourceToOutput.get(Device.RESOURCE_TYPE_VIDEO)){
+	        if(output == null){
+	            Log.d(TAG, "NULL!!!!!!");
+	        }
+	        else{
+	            try {
+                    output.writeObject(request);
+                } catch (IOException e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+	        }
+	        
+	        vport = vport + 2;
+	        vInfo.set(1, vport);
+	    }
+	}
+	
+	private String capitalize(String s) {
+        if (s == null || s.length() == 0) {
+            return "";
+        }
+        char first = s.charAt(0);
+        if (Character.isUpperCase(first)) {
+            return s;
+        } else {
+            return Character.toUpperCase(first) + s.substring(1);
+        }
+    }
+}
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/SystemServer.java AndroidSource/frameworks/base/services/java/com/android/server/SystemServer.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/SystemServer.java	2016-01-29 15:12:34.475488000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/SystemServer.java	2016-03-02 20:48:02.000000000 +0900
@@ -53,6 +53,7 @@
 import com.android.server.am.BatteryStatsService;
 import com.android.server.content.ContentService;
 import com.android.server.display.DisplayManagerService;
+import com.android.server.distribute.DistributedComputingService;
 import com.android.server.dreams.DreamManagerService;
 import com.android.server.input.InputManagerService;
 import com.android.server.media.MediaRouterService;
@@ -65,6 +66,8 @@
 import com.android.server.power.PowerManagerService;
 import com.android.server.power.ShutdownThread;
 import com.android.server.print.PrintManagerService;
+import com.android.server.devicemanager.DeviceManagementService;
+import com.android.server.remote.RemoteService;
 import com.android.server.search.SearchManagerService;
 import com.android.server.usb.UsbService;
 import com.android.server.wifi.WifiService;
@@ -157,6 +160,12 @@
         TelephonyRegistry telephonyRegistry = null;
         ConsumerIrService consumerIr = null;
 
+        // ADDED BY JH
+        RemoteService remoteService = null;
+        DeviceManagementService deviceService = null;
+        DistributedComputingService distributedcomputing = null;
+        // ADDED BY JH
+
         // Create a handler thread just for the window manager to enjoy.
         HandlerThread wmHandlerThread = new HandlerThread("WindowManager");
         wmHandlerThread.start();
@@ -289,6 +298,44 @@
             consumerIr = new ConsumerIrService(context);
             ServiceManager.addService(Context.CONSUMER_IR_SERVICE, consumerIr);
 
+            // ADDED BY JH
+            try
+			{
+				Slog.i(TAG, "Recommender Service");
+				deviceService = new DeviceManagementService(context);
+				ServiceManager.addService(Context.DEVICE_MANAGEMENT_SERVICE,
+						deviceService);
+			}
+			catch (Throwable e)
+			{
+				reportWtf("starting Recommender Service", e);
+			}
+            
+            try
+			{
+				Slog.i(TAG, "Remote Service");
+				remoteService = new RemoteService(context);
+				ServiceManager.addService(Context.REMOTE_SERVICE,
+						remoteService);
+			}
+			catch (Throwable e)
+			{
+				reportWtf("REMOTE REQUEST MANAGER FAILURE", e);
+			}
+            
+            try
+			{
+				Slog.i(TAG, "DistributedComputing Service");
+				distributedcomputing = new DistributedComputingService(context);
+				ServiceManager.addService(Context.DISTRIBUTED_COMPUTING_SERVICE,
+						distributedcomputing);
+			}
+			catch (Throwable e)
+			{
+				reportWtf("DISTRIBUTED COMPUTING FAILURE", e);
+			}
+			// ADDED BY JH
+            
             // only initialize the power service after we have started the
             // lights service, content providers and the battery service.
             power.init(context, lights, ActivityManagerService.self(), battery,
@@ -378,7 +425,7 @@
                 } catch (Throwable e) {
                     reportWtf("starting Accessibility Manager", e);
                 }
-            }
+		    }
         }
 
         try {
diff -urN Original_4.4.4_r1/frameworks/base/services/java/com/android/server/VibratorService.java AndroidSource/frameworks/base/services/java/com/android/server/VibratorService.java
--- Original_4.4.4_r1/frameworks/base/services/java/com/android/server/VibratorService.java	2016-01-29 15:12:34.479488000 +0900
+++ AndroidSource/frameworks/base/services/java/com/android/server/VibratorService.java	2016-02-16 20:22:55.000000000 +0900
@@ -16,6 +16,13 @@
 
 package com.android.server;
 
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.ListIterator;
+
+import com.android.internal.app.IAppOpsService;
+import com.android.internal.app.IBatteryStats;
+
 import android.app.AppOpsManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -25,13 +32,13 @@
 import android.database.ContentObserver;
 import android.hardware.input.InputManager;
 import android.os.BatteryStats;
+import android.os.Binder;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.IVibratorService;
 import android.os.PowerManager;
 import android.os.Process;
 import android.os.RemoteException;
-import android.os.IBinder;
-import android.os.Binder;
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
@@ -39,16 +46,10 @@
 import android.os.WorkSource;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
+import android.util.Log;
 import android.util.Slog;
 import android.view.InputDevice;
 
-import com.android.internal.app.IAppOpsService;
-import com.android.internal.app.IBatteryStats;
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.ListIterator;
-
 public class VibratorService extends IVibratorService.Stub
         implements InputManager.InputDeviceListener {
     private static final String TAG = "VibratorService";
@@ -63,6 +64,8 @@
     private final IAppOpsService mAppOpsService;
     private final IBatteryStats mBatteryStatsService;
     private InputManager mIm;
+    
+
 
     volatile VibrateThread mThread;
 
@@ -152,6 +155,8 @@
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_SCREEN_OFF);
         context.registerReceiver(mIntentReceiver, filter);
+        
+
     }
 
     public void systemReady() {
@@ -192,7 +197,8 @@
     }
 
     public void vibrate(int uid, String packageName, long milliseconds, IBinder token) {
-        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.VIBRATE)
+        
+    	if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.VIBRATE)
                 != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Requires VIBRATE permission");
         }
@@ -220,6 +226,8 @@
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
+        
+
     }
 
     private boolean isAll0(long[] pattern) {
@@ -234,7 +242,7 @@
 
     public void vibratePattern(int uid, String packageName, long[] pattern, int repeat,
             IBinder token) {
-        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.VIBRATE)
+    	if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.VIBRATE)
                 != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Requires VIBRATE permission");
         }
@@ -264,7 +272,9 @@
             } catch (RemoteException e) {
                 return;
             }
-
+            
+            Log.d("VibLatency", "VibVib");
+            
             synchronized (mVibrations) {
                 removeVibrationLocked(token);
                 doCancelVibrateLocked();
diff -urN Original_4.4.4_r1/frameworks/base/services/jni/Android.mk AndroidSource/frameworks/base/services/jni/Android.mk
--- Original_4.4.4_r1/frameworks/base/services/jni/Android.mk	2016-01-29 15:12:34.519488000 +0900
+++ AndroidSource/frameworks/base/services/jni/Android.mk	2015-01-12 10:39:51.000000000 +0900
@@ -18,6 +18,7 @@
     com_android_server_location_GpsLocationProvider.cpp \
     com_android_server_location_FlpHardwareProvider.cpp \
     com_android_server_connectivity_Vpn.cpp \
+    com_android_server_remote_RequestHandler.cpp \
     onload.cpp
 
 LOCAL_C_INCLUDES += \
diff -urN Original_4.4.4_r1/frameworks/base/services/jni/com_android_server_remote_RequestHandler.cpp AndroidSource/frameworks/base/services/jni/com_android_server_remote_RequestHandler.cpp
--- Original_4.4.4_r1/frameworks/base/services/jni/com_android_server_remote_RequestHandler.cpp	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/base/services/jni/com_android_server_remote_RequestHandler.cpp	2016-09-23 16:53:07.473090667 +0900
@@ -0,0 +1,167 @@
+#define LOG_TAG "RemoteRequestJNI"
+
+#include "utils/Log.h"
+
+#include "jni.h"
+#include "JNIHelp.h"
+#include "android_os_MessageQueue.h"
+#include "android_runtime/AndroidRuntime.h"
+
+#include <gui/Sensor.h>
+#include <gui/SensorManager.h>
+#include <utils/Log.h>
+
+
+namespace android
+{
+
+//mutable sp<ISensorServer> mSensorServer;
+
+/*static void initSensorServer(JNIEnv *env, jobject clazz)
+{
+	const String16 name("sensorservice");
+	for (int i = 0; i < 4; i++) {
+		status_t err = getService(name, &mSensorServer);
+		if (err == NAME_NOT_FOUND) {
+			usleep(250000);
+			continue;
+		}
+		if (err != NO_ERROR) {
+			return err;
+		}
+	}
+}*/
+
+static jint nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jobject eventQ, jobject msgQ, jfloatArray scratch)
+{
+    /*SensorManager& mgr(SensorManager::getInstance());
+    sp<SensorEventQueue> queue(mgr.createEventQueue());
+
+    sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ);
+    if (messageQueue == NULL) {
+        jniThrowRuntimeException(env, "MessageQueue is not initialized.");
+        return 0;
+    }
+
+    sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQ, scratch);
+    receiver->incStrong((void*)nativeInitSensorEventQueue);
+    return jint(receiver.get());*/
+	return 1;
+}
+
+static void sendRemoteEvent(JNIEnv *env, jobject clazz, jint type, jint sensor, jfloatArray data, jint status, jlong timestamp, jint sourcedevice)
+{
+    // ALOGI("vibratorOff\n");
+    //vibrator_off();
+	//ALOGD("sendTestEvent!!!!!!!");
+	//mSensorServer->sendTestEvent(NULL, NULL);
+
+	//ALOGD("sensor:%d, data:%f,%f,%f, timestamp:%lld", sensor, data[0], data[1], data[2], timestamp);
+
+	float* values = (float *)env->GetFloatArrayElements(data, 0);
+	int64_t time = (int64_t)timestamp;
+
+
+	//ADDED BY JH
+//	ALOGD("type:%d, sensor:%d, data:%8f,%8f,%8f, timestamp:%lld, sourceDevice:%d", type, sensor, values[0], values[1], values[2], time, sourcedevice);
+
+	SensorManager& mgr(SensorManager::getInstance());
+	//sp<SensorEventQueue> queue(mgr.createEventQueue());
+	mgr.sendRemoteEvent(type, sensor, values, status, time, sourcedevice);
+	/*Sensor const* const* sensorList;
+	size_t count = mgr.getSensorList(&sensorList);*/
+
+	//ALOGD("count=%d", count);
+
+
+
+	//JNIEnv* env = AndroidRuntime::getJNIEnv();
+
+	/*env->CallVoidMethod(mReceiverObject,
+						gBaseEventQueueClassInfo.dispatchSensorEvent,
+						sensor,
+						data,
+						status,
+						timestamp,
+						100);*/
+
+
+	if (env->ExceptionCheck()) {
+		ALOGE("Exception dispatching input event.");
+		//return 1;
+	}
+
+
+	env->ReleaseFloatArrayElements(data, values, 0);
+	//return 1;
+
+}
+
+static void setServerOn(JNIEnv *env, jobject clazz, jboolean flag)
+{
+	SensorManager& mgr(SensorManager::getInstance());
+	//sp<SensorEventQueue> queue(mgr.createEventQueue());
+	mgr.setServerOn((bool)flag);
+}
+
+static JNINativeMethod gRemoteServiceMethods[] = {
+    //{ "vibratorExists", "()Z", (void*)vibratorExists },
+    //{ "vibratorOn", "(J)V", (void*)vibratorOn },
+	{ "sendRemoteEvent", "(II[FIJI)V", (void*)sendRemoteEvent },
+    { "setServerOn", "(Z)V", (void*)setServerOn }
+};
+
+static JNINativeMethod gReceiverMethods[] = {
+    //{ "vibratorExists", "()Z", (void*)vibratorExists },
+    //{ "vibratorOn", "(J)V", (void*)vibratorOn },
+    { "sendRemoteEvent", "(II[FIJI)V", (void*)sendRemoteEvent }
+};
+
+static JNINativeMethod gSenderMethods[] = {
+    //{ "vibratorExists", "()Z", (void*)vibratorExists },
+    //{ "vibratorOn", "(J)V", (void*)vibratorOn },
+	{ "setServerOn", "(Z)V", (void*)setServerOn }
+};
+
+
+
+#define FIND_CLASS(var, className) \
+        var = env->FindClass(className); \
+        LOG_FATAL_IF(! var, "Unable to find class " className); \
+        var = jclass(env->NewGlobalRef(var));
+
+#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
+        var = env->GetMethodID(clazz, methodName, methodDescriptor); \
+        LOG_FATAL_IF(! var, "Unable to find method " methodName);
+
+int register_android_server_remote_RequestHandler(JNIEnv *env)
+{
+	jniRegisterNativeMethods(env, "com/android/server/remote/RemoteService",
+			gRemoteServiceMethods, NELEM(gRemoteServiceMethods));
+
+	jniRegisterNativeMethods(env, "com/android/server/remote/Receiver",
+			gReceiverMethods, NELEM(gReceiverMethods));
+
+	jniRegisterNativeMethods(env, "com/android/server/remote/Sender_",
+			gSenderMethods, NELEM(gSenderMethods));
+
+	/*jniRegisterNativeMethods(env, "android/hardware/SystemSensorManager",
+	        gSystemSensorManagerMethods, NELEM(gSystemSensorManagerMethods));*/
+
+	/*jniRegisterNativeMethods(env, "android/hardware/SystemSensorManager$BaseEventQueue",
+			gBaseEventQueueMethods, NELEM(gBaseEventQueueMethods));*/
+
+	/*FIND_CLASS(gBaseEventQueueClassInfo.clazz, "android/hardware/SystemSensorManager$BaseEventQueue");
+
+	GET_METHOD_ID(gBaseEventQueueClassInfo.dispatchSensorEvent,
+			gBaseEventQueueClassInfo.clazz,
+			"dispatchSensorEvent", "(I[FIJI)V");
+
+	GET_METHOD_ID(gBaseEventQueueClassInfo.dispatchFlushCompleteEvent,
+				  gBaseEventQueueClassInfo.clazz,
+				  "dispatchFlushCompleteEvent", "(I)V");*/
+
+	return 0;
+}
+};
+
diff -urN Original_4.4.4_r1/frameworks/base/services/jni/onload.cpp AndroidSource/frameworks/base/services/jni/onload.cpp
--- Original_4.4.4_r1/frameworks/base/services/jni/onload.cpp	2016-01-29 15:12:34.519488000 +0900
+++ AndroidSource/frameworks/base/services/jni/onload.cpp	2015-01-13 10:53:27.000000000 +0900
@@ -36,6 +36,7 @@
 int register_android_server_location_FlpHardwareProvider(JNIEnv* env);
 int register_android_server_connectivity_Vpn(JNIEnv* env);
 int register_android_server_AssetAtlasService(JNIEnv* env);
+int register_android_server_remote_RequestHandler(JNIEnv* env);
 };
 
 using namespace android;
@@ -67,6 +68,7 @@
     register_android_server_connectivity_Vpn(env);
     register_android_server_AssetAtlasService(env);
     register_android_server_ConsumerIrService(env);
+    register_android_server_remote_RequestHandler(env);
 
 
     return JNI_VERSION_1_4;
diff -urN Original_4.4.4_r1/frameworks/compile/libbcc/.git/HEAD AndroidSource/frameworks/compile/libbcc/.git/HEAD
--- Original_4.4.4_r1/frameworks/compile/libbcc/.git/HEAD	2016-01-29 15:12:35.199488000 +0900
+++ AndroidSource/frameworks/compile/libbcc/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-c952d877069bbb322d8b8362232e0c07a7e8ad1e
Binary files Original_4.4.4_r1/frameworks/compile/libbcc/.git/index and AndroidSource/frameworks/compile/libbcc/.git/index differ
diff -urN Original_4.4.4_r1/frameworks/compile/mclinker/.git/HEAD AndroidSource/frameworks/compile/mclinker/.git/HEAD
--- Original_4.4.4_r1/frameworks/compile/mclinker/.git/HEAD	2016-01-29 15:12:35.263488000 +0900
+++ AndroidSource/frameworks/compile/mclinker/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-89a5648fcb366adb25b75aa69a7ad9a34842dd17
Binary files Original_4.4.4_r1/frameworks/compile/mclinker/.git/index and AndroidSource/frameworks/compile/mclinker/.git/index differ
diff -urN Original_4.4.4_r1/frameworks/compile/slang/.git/HEAD AndroidSource/frameworks/compile/slang/.git/HEAD
--- Original_4.4.4_r1/frameworks/compile/slang/.git/HEAD	2016-01-29 15:12:35.315488000 +0900
+++ AndroidSource/frameworks/compile/slang/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-ac71e8c3b3edca77a561377b1f24447a3c2ac3a5
Binary files Original_4.4.4_r1/frameworks/compile/slang/.git/index and AndroidSource/frameworks/compile/slang/.git/index differ
diff -urN "Original_4.4.4_r1/frameworks/compile/slang/tests/P_str_escape/str\\\\escape.rs" "AndroidSource/frameworks/compile/slang/tests/P_str_escape/str\\\\escape.rs"
--- "Original_4.4.4_r1/frameworks/compile/slang/tests/P_str_escape/str\\\\escape.rs"	2016-01-29 15:12:35.331488000 +0900
+++ "AndroidSource/frameworks/compile/slang/tests/P_str_escape/str\\\\escape.rs"	1970-01-01 09:00:00.000000000 +0900
@@ -1,2 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(foo)
diff -urN Original_4.4.4_r1/frameworks/ex/.git/HEAD AndroidSource/frameworks/ex/.git/HEAD
--- Original_4.4.4_r1/frameworks/ex/.git/HEAD	2016-01-29 15:12:35.355488000 +0900
+++ AndroidSource/frameworks/ex/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-ce2b95ae200332495b348be07f77fe60b6c23dcc
Binary files Original_4.4.4_r1/frameworks/ex/.git/index and AndroidSource/frameworks/ex/.git/index differ
diff -urN Original_4.4.4_r1/frameworks/mff/.git/HEAD AndroidSource/frameworks/mff/.git/HEAD
--- Original_4.4.4_r1/frameworks/mff/.git/HEAD	2016-01-29 15:12:35.403488000 +0900
+++ AndroidSource/frameworks/mff/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-b9669b8540a1e5c953374d53b115514335e23c27
Binary files Original_4.4.4_r1/frameworks/mff/.git/index and AndroidSource/frameworks/mff/.git/index differ
diff -urN Original_4.4.4_r1/frameworks/ml/.git/HEAD AndroidSource/frameworks/ml/.git/HEAD
--- Original_4.4.4_r1/frameworks/ml/.git/HEAD	2016-01-29 15:12:35.423488000 +0900
+++ AndroidSource/frameworks/ml/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-5072d507df1fd827ac7b15900c1f113949f76f12
Binary files Original_4.4.4_r1/frameworks/ml/.git/index and AndroidSource/frameworks/ml/.git/index differ
diff -urN Original_4.4.4_r1/frameworks/native/.git/HEAD AndroidSource/frameworks/native/.git/HEAD
--- Original_4.4.4_r1/frameworks/native/.git/HEAD	2016-01-29 15:12:35.447488000 +0900
+++ AndroidSource/frameworks/native/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-9c7db08049e1d36c2f60dd703f27c432bc8cfbc5
Binary files Original_4.4.4_r1/frameworks/native/.git/index and AndroidSource/frameworks/native/.git/index differ
diff -urN Original_4.4.4_r1/frameworks/native/include/gui/ISensorServer.h AndroidSource/frameworks/native/include/gui/ISensorServer.h
--- Original_4.4.4_r1/frameworks/native/include/gui/ISensorServer.h	2016-01-29 15:12:35.455488000 +0900
+++ AndroidSource/frameworks/native/include/gui/ISensorServer.h	2015-07-13 13:40:59.000000000 +0900
@@ -38,6 +38,8 @@
 
     virtual Vector<Sensor> getSensorList() = 0;
     virtual sp<ISensorEventConnection> createSensorEventConnection() = 0;
+    virtual void sendRemoteEvent(int32_t type, int32_t sensor, float* data, int8_t status, int64_t timestamp, int32_t sourcedevice) = 0;
+    virtual void setServerOn(bool flag) = 0;
 };
 
 // ----------------------------------------------------------------------------
diff -urN Original_4.4.4_r1/frameworks/native/include/gui/SensorManager.h AndroidSource/frameworks/native/include/gui/SensorManager.h
--- Original_4.4.4_r1/frameworks/native/include/gui/SensorManager.h	2016-01-29 15:12:35.455488000 +0900
+++ AndroidSource/frameworks/native/include/gui/SensorManager.h	2015-07-13 13:39:20.000000000 +0900
@@ -54,6 +54,8 @@
     ssize_t getSensorList(Sensor const* const** list) const;
     Sensor const* getDefaultSensor(int type);
     sp<SensorEventQueue> createEventQueue();
+    void sendRemoteEvent(int32_t type, int32_t sensor, float* data, int8_t status, int64_t timestamp, int32_t sourcedevice);
+    void setServerOn(bool flag);
 
 private:
     // DeathRecipient interface
diff -urN Original_4.4.4_r1/frameworks/native/include/input/Input.h AndroidSource/frameworks/native/include/input/Input.h
--- Original_4.4.4_r1/frameworks/native/include/input/Input.h	2016-01-29 15:12:35.459488000 +0900
+++ AndroidSource/frameworks/native/include/input/Input.h	2015-08-04 10:03:28.000000000 +0900
@@ -323,6 +323,12 @@
 
     virtual int32_t getType() const { return AINPUT_EVENT_TYPE_MOTION; }
 
+    // ADDED BY JH
+	//inline int32_t getSourceDevice() const { return mSourceDevice; }
+
+	//inline void setSourceDevice(int32_t sourceDevice) { mSourceDevice = sourceDevice; }
+	// ADDED BY JH
+
     inline int32_t getAction() const { return mAction; }
 
     inline int32_t getActionMasked() const { return mAction & AMOTION_EVENT_ACTION_MASK; }
@@ -497,9 +503,28 @@
 
     ssize_t findPointerIndex(int32_t pointerId) const;
 
+    /*void initialize(
+			int32_t deviceId,
+			int32_t source,
+			int32_t action,
+			int32_t flags,
+			int32_t edgeFlags,
+			int32_t metaState,
+			int32_t buttonState,
+			float xOffset,
+			float yOffset,
+			float xPrecision,
+			float yPrecision,
+			nsecs_t downTime,
+			nsecs_t eventTime,
+			size_t pointerCount,
+			const PointerProperties* pointerProperties,
+			const PointerCoords* pointerCoords);*/
+
     void initialize(
             int32_t deviceId,
             int32_t source,
+            //int32_t sourceDevice,
             int32_t action,
             int32_t flags,
             int32_t edgeFlags,
@@ -549,6 +574,8 @@
     }
 
 protected:
+    // ADDED BY JH
+    //int32_t mSourceDevice;
     int32_t mAction;
     int32_t mFlags;
     int32_t mEdgeFlags;
diff -urN Original_4.4.4_r1/frameworks/native/include/input/InputTransport.h AndroidSource/frameworks/native/include/input/InputTransport.h
--- Original_4.4.4_r1/frameworks/native/include/input/InputTransport.h	2016-01-29 15:12:35.459488000 +0900
+++ AndroidSource/frameworks/native/include/input/InputTransport.h	2015-08-04 12:04:20.000000000 +0900
@@ -76,6 +76,7 @@
             nsecs_t eventTime;
             int32_t deviceId;
             int32_t source;
+            int32_t sourceDevice;
             int32_t action;
             int32_t flags;
             int32_t metaState;
@@ -223,6 +224,7 @@
             uint32_t seq,
             int32_t deviceId,
             int32_t source,
+            //int32_t sourceDevice,
             int32_t action,
             int32_t flags,
             int32_t edgeFlags,
diff -urN Original_4.4.4_r1/frameworks/native/libs/gui/ISensorServer.cpp AndroidSource/frameworks/native/libs/gui/ISensorServer.cpp
--- Original_4.4.4_r1/frameworks/native/libs/gui/ISensorServer.cpp	2016-01-29 15:12:35.463488000 +0900
+++ AndroidSource/frameworks/native/libs/gui/ISensorServer.cpp	2015-07-13 13:41:10.000000000 +0900
@@ -47,7 +47,7 @@
 
     virtual Vector<Sensor> getSensorList()
     {
-        Parcel data, reply;
+    	Parcel data, reply;
         data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
         remote()->transact(GET_SENSOR_LIST, data, &reply);
         Sensor s;
@@ -68,6 +68,16 @@
         remote()->transact(CREATE_SENSOR_EVENT_CONNECTION, data, &reply);
         return interface_cast<ISensorEventConnection>(reply.readStrongBinder());
     }
+
+    virtual void sendRemoteEvent(int32_t type, int32_t sensor, float* data, int8_t status, int64_t timestamp, int32_t sourcedevice)
+    {
+    	ALOGD("Hello I'm ISensorServer!!");
+    }
+
+    virtual void setServerOn(bool flag)
+	{
+		ALOGD("Hello I'm ISensorServer!!");
+	}
 };
 
 IMPLEMENT_META_INTERFACE(SensorServer, "android.gui.SensorServer");
diff -urN Original_4.4.4_r1/frameworks/native/libs/gui/SensorManager.cpp AndroidSource/frameworks/native/libs/gui/SensorManager.cpp
--- Original_4.4.4_r1/frameworks/native/libs/gui/SensorManager.cpp	2016-01-29 15:12:35.463488000 +0900
+++ AndroidSource/frameworks/native/libs/gui/SensorManager.cpp	2015-07-13 13:33:51.000000000 +0900
@@ -103,7 +103,7 @@
 
 ssize_t SensorManager::getSensorList(Sensor const* const** list) const
 {
-    Mutex::Autolock _l(mLock);
+	Mutex::Autolock _l(mLock);
     status_t err = assertStateLocked();
     if (err < 0) {
         return ssize_t(err);
@@ -129,7 +129,7 @@
 
 sp<SensorEventQueue> SensorManager::createEventQueue()
 {
-    sp<SensorEventQueue> queue;
+	sp<SensorEventQueue> queue;
 
     Mutex::Autolock _l(mLock);
     while (assertStateLocked() == NO_ERROR) {
@@ -146,5 +146,25 @@
     return queue;
 }
 
+void SensorManager::sendRemoteEvent(int32_t type, int32_t sensor, float* data, int8_t status, int64_t timestamp, int32_t sourcedevice)
+{
+	Mutex::Autolock _l(mLock);
+	while (assertStateLocked() == NO_ERROR)
+	{
+		mSensorServer->sendRemoteEvent(type, sensor, data, status, timestamp, sourcedevice);
+		break;
+	}
+}
+
+void SensorManager::setServerOn(bool flag)
+{
+	Mutex::Autolock _l(mLock);
+	while (assertStateLocked() == NO_ERROR)
+	{
+		mSensorServer->setServerOn(flag);
+		break;
+	}
+}
+
 // ----------------------------------------------------------------------------
 }; // namespace android
diff -urN Original_4.4.4_r1/frameworks/native/libs/input/Input.cpp AndroidSource/frameworks/native/libs/input/Input.cpp
--- Original_4.4.4_r1/frameworks/native/libs/input/Input.cpp	2016-01-29 15:12:35.463488000 +0900
+++ AndroidSource/frameworks/native/libs/input/Input.cpp	2015-08-04 10:01:44.000000000 +0900
@@ -280,7 +280,6 @@
 
 
 // --- MotionEvent ---
-
 void MotionEvent::initialize(
         int32_t deviceId,
         int32_t source,
@@ -316,8 +315,49 @@
     addSample(eventTime, pointerCoords);
 }
 
+/*void MotionEvent::initialize(
+        int32_t deviceId,
+        int32_t source,
+        int32_t sourceDevice,
+        int32_t action,
+        int32_t flags,
+        int32_t edgeFlags,
+        int32_t metaState,
+        int32_t buttonState,
+        float xOffset,
+        float yOffset,
+        float xPrecision,
+        float yPrecision,
+        nsecs_t downTime,
+        nsecs_t eventTime,
+        size_t pointerCount,
+        const PointerProperties* pointerProperties,
+        const PointerCoords* pointerCoords) {
+    InputEvent::initialize(deviceId, source);
+    mSourceDevice = sourceDevice;
+    ALOGD("init2: %d", mSourceDevice);
+    mAction = action;
+    mFlags = flags;
+    mEdgeFlags = edgeFlags;
+    mMetaState = metaState;
+    mButtonState = buttonState;
+    mXOffset = xOffset;
+    mYOffset = yOffset;
+    mXPrecision = xPrecision;
+    mYPrecision = yPrecision;
+    mDownTime = downTime;
+    mPointerProperties.clear();
+    mPointerProperties.appendArray(pointerProperties, pointerCount);
+    mSampleEventTimes.clear();
+    mSamplePointerCoords.clear();
+    addSample(eventTime, pointerCoords);
+}*/
+
 void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
     InputEvent::initialize(other->mDeviceId, other->mSource);
+    // ADDED BY JH
+    //mSourceDevice = other->mSourceDevice;
+    //ALOGD("copyFrom: %d", mSourceDevice);
     mAction = other->mAction;
     mFlags = other->mFlags;
     mEdgeFlags = other->mEdgeFlags;
@@ -496,6 +536,9 @@
 
     mDeviceId = parcel->readInt32();
     mSource = parcel->readInt32();
+    // ADDED BY JH
+    //mSourceDevice = parcel->readInt32();
+    //ALOGD("mSourceDevice-read in cpp: %d", mSourceDevice);
     mAction = parcel->readInt32();
     mFlags = parcel->readInt32();
     mEdgeFlags = parcel->readInt32();
@@ -543,6 +586,9 @@
 
     parcel->writeInt32(mDeviceId);
     parcel->writeInt32(mSource);
+    // ADDED BY JH
+    //parcel->writeInt32(mSourceDevice);
+    //ALOGD("mSourceDevice-write in cpp: %d", mSourceDevice);
     parcel->writeInt32(mAction);
     parcel->writeInt32(mFlags);
     parcel->writeInt32(mEdgeFlags);
@@ -591,7 +637,6 @@
     return false;
 }
 
-
 // --- PooledInputEventFactory ---
 
 PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
diff -urN Original_4.4.4_r1/frameworks/native/libs/input/InputTransport.cpp AndroidSource/frameworks/native/libs/input/InputTransport.cpp
--- Original_4.4.4_r1/frameworks/native/libs/input/InputTransport.cpp	2016-01-29 15:12:35.463488000 +0900
+++ AndroidSource/frameworks/native/libs/input/InputTransport.cpp	2015-08-04 10:02:59.000000000 +0900
@@ -281,6 +281,7 @@
         uint32_t seq,
         int32_t deviceId,
         int32_t source,
+        //int32_t sourceDevice,
         int32_t action,
         int32_t flags,
         int32_t edgeFlags,
@@ -322,6 +323,7 @@
     msg.body.motion.seq = seq;
     msg.body.motion.deviceId = deviceId;
     msg.body.motion.source = source;
+    //msg.body.motion.sourceDevice = sourceDevice;
     msg.body.motion.action = action;
     msg.body.motion.flags = flags;
     msg.body.motion.edgeFlags = edgeFlags;
@@ -486,7 +488,8 @@
             MotionEvent* motionEvent = factory->createMotionEvent();
             if (! motionEvent) return NO_MEMORY;
 
-            updateTouchState(&mMsg);
+            //ALOGD("InputTransport-consume: %d",mMsg.body.motion.sourceDevice);
+
             initializeMotionEvent(motionEvent, &mMsg);
             *outSeq = mMsg.body.motion.seq;
             *outEvent = motionEvent;
@@ -902,9 +905,11 @@
         pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
     }
 
+    //ALOGD("inputTransport-initializeMotionEvent: %d", msg->body.motion.sourceDevice);
     event->initialize(
             msg->body.motion.deviceId,
             msg->body.motion.source,
+            //msg->body.motion.sourceDevice,
             msg->body.motion.action,
             msg->body.motion.flags,
             msg->body.motion.edgeFlags,
diff -urN Original_4.4.4_r1/frameworks/native/services/sensorservice/Android.mk AndroidSource/frameworks/native/services/sensorservice/Android.mk
--- Original_4.4.4_r1/frameworks/native/services/sensorservice/Android.mk	2016-01-29 15:12:35.519488000 +0900
+++ AndroidSource/frameworks/native/services/sensorservice/Android.mk	2015-11-18 13:51:48.000000000 +0900
@@ -12,7 +12,8 @@
     SensorDevice.cpp \
     SensorFusion.cpp \
     SensorInterface.cpp \
-    SensorService.cpp
+    SensorService.cpp \
+    RemoteSensor.cpp
 
 LOCAL_CFLAGS:= -DLOG_TAG=\"SensorService\"
 
diff -urN Original_4.4.4_r1/frameworks/native/services/sensorservice/Android.mk~ AndroidSource/frameworks/native/services/sensorservice/Android.mk~
--- Original_4.4.4_r1/frameworks/native/services/sensorservice/Android.mk~	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/native/services/sensorservice/Android.mk~	2015-01-09 01:03:55.000000000 +0900
@@ -0,0 +1,51 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	BatteryService.cpp \
+	CorrectedGyroSensor.cpp \
+    Fusion.cpp \
+    GravitySensor.cpp \
+    LinearAccelerationSensor.cpp \
+    OrientationSensor.cpp \
+    RotationVectorSensor.cpp \
+    SensorDevice.cpp \
+    SensorFusion.cpp \
+    SensorInterface.cpp \
+    SensorService.cpp
+
+LOCAL_CFLAGS:= -DLOG_TAG=\"SensorService\"
+
+LOCAL_CFLAGS += -fvisibility=hidden
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+	libhardware \
+	libhardware_legacy \
+	libutils \
+	liblog \
+	libbinder \
+	libui \
+	libgui
+
+LOCAL_MODULE:= libsensorservice
+
+include $(BUILD_SHARED_LIBRARY)
+
+#####################################################################
+# build executable
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	main_sensorservice.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libsensorservice \
+	libbinder \
+	libutils
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE:= sensorservice
+
+include $(BUILD_EXECUTABLE)
diff -urN Original_4.4.4_r1/frameworks/native/services/sensorservice/RemoteSensor.cpp AndroidSource/frameworks/native/services/sensorservice/RemoteSensor.cpp
--- Original_4.4.4_r1/frameworks/native/services/sensorservice/RemoteSensor.cpp	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/native/services/sensorservice/RemoteSensor.cpp	2015-11-04 22:24:51.000000000 +0900
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#include <stdint.h>
+#include <math.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+
+#include <hardware/sensors.h>
+
+#include "RemoteSensor.h"
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+RemoteSensor::RemoteSensor()
+    : mSensorDevice(SensorDevice::getInstance()),
+      mSensorFusion(SensorFusion::getInstance())
+{
+}
+
+bool RemoteSensor::process(sensors_event_t* outEvent,
+        const sensors_event_t& event)
+{
+ 	return true;
+}
+
+status_t RemoteSensor::activate(void* ident, bool enabled) {
+    return mSensorFusion.activate(ident, enabled);
+}
+
+status_t RemoteSensor::setDelay(void* ident, int handle, int64_t ns) {
+    return mSensorFusion.setDelay(ident, ns);
+}
+
+Sensor RemoteSensor::getSensor() const {
+    sensor_t hwSensor;
+    hwSensor.name       = "Remote Sensor";
+    hwSensor.vendor     = "AOSP";
+    hwSensor.version    = 3;
+    hwSensor.handle     = 21;
+    hwSensor.type       = 21;
+    hwSensor.maxRange   = 1;
+    hwSensor.resolution = 1.0f / (1<<24);
+    hwSensor.power      = mSensorFusion.getPowerUsage();
+    hwSensor.minDelay   = mSensorFusion.getMinDelay();
+    Sensor sensor(&hwSensor);
+    return sensor;
+}
+}; // namespace android
+
diff -urN Original_4.4.4_r1/frameworks/native/services/sensorservice/RemoteSensor.h AndroidSource/frameworks/native/services/sensorservice/RemoteSensor.h
--- Original_4.4.4_r1/frameworks/native/services/sensorservice/RemoteSensor.h	1970-01-01 09:00:00.000000000 +0900
+++ AndroidSource/frameworks/native/services/sensorservice/RemoteSensor.h	2015-11-04 21:17:17.000000000 +0900
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#ifndef ANDROID_REMOTE_SENSOR_SENSOR_H
+#define ANDROID_REMOTE_SENSOR_SENSOR_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <gui/Sensor.h>
+
+#include "SensorDevice.h"
+#include "SensorInterface.h"
+
+#include "Fusion.h"
+#include "SensorFusion.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+// ---------------------------------------------------------------------------
+
+class RemoteSensor : public SensorInterface {
+    SensorDevice& mSensorDevice;
+    SensorFusion& mSensorFusion;
+
+public:
+    RemoteSensor();
+    virtual bool process(sensors_event_t* outEvent,
+            const sensors_event_t& event);
+    virtual status_t activate(void* ident, bool enabled);
+    virtual status_t setDelay(void* ident, int handle, int64_t ns);
+    virtual Sensor getSensor() const;
+    virtual bool isVirtual() const { return true; }
+};
+
+}; // namespace android
+
+#endif // ANDROID_ROTATION_VECTOR_SENSOR_H
diff -urN Original_4.4.4_r1/frameworks/native/services/sensorservice/SensorService.cpp AndroidSource/frameworks/native/services/sensorservice/SensorService.cpp
--- Original_4.4.4_r1/frameworks/native/services/sensorservice/SensorService.cpp	2016-01-29 15:12:35.523488000 +0900
+++ AndroidSource/frameworks/native/services/sensorservice/SensorService.cpp	2016-06-23 21:59:35.000000000 +0900
@@ -40,15 +40,23 @@
 #include <hardware/sensors.h>
 #include <hardware_legacy/power.h>
 
+//#include <android/log.h>
+
 #include "BatteryService.h"
 #include "CorrectedGyroSensor.h"
 #include "GravitySensor.h"
 #include "LinearAccelerationSensor.h"
 #include "OrientationSensor.h"
 #include "RotationVectorSensor.h"
+#include "RemoteSensor.h"
 #include "SensorFusion.h"
 #include "SensorService.h"
 
+/*
+ #define  LOG_TAG    "NativeSenserService"
+ #define  ALOG(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
+ */
+
 namespace android {
 // ---------------------------------------------------------------------------
 
@@ -63,892 +71,954 @@
 
 const char* SensorService::WAKE_LOCK_NAME = "SensorService";
 
-SensorService::SensorService()
-    : mInitCheck(NO_INIT)
-{
+SensorService::SensorService() :
+		mInitCheck(NO_INIT) {
 }
 
-void SensorService::onFirstRef()
-{
-    ALOGD("nuSensorService starting...");
-
-    SensorDevice& dev(SensorDevice::getInstance());
+void SensorService::onFirstRef() {
+	ALOGD("nuSensorService starting...");
 
-    if (dev.initCheck() == NO_ERROR) {
-        sensor_t const* list;
-        ssize_t count = dev.getSensorList(&list);
-        if (count > 0) {
-            ssize_t orientationIndex = -1;
-            bool hasGyro = false;
-            uint32_t virtualSensorsNeeds =
-                    (1<<SENSOR_TYPE_GRAVITY) |
-                    (1<<SENSOR_TYPE_LINEAR_ACCELERATION) |
-                    (1<<SENSOR_TYPE_ROTATION_VECTOR);
-
-            mLastEventSeen.setCapacity(count);
-            for (ssize_t i=0 ; i<count ; i++) {
-                registerSensor( new HardwareSensor(list[i]) );
-                switch (list[i].type) {
-                    case SENSOR_TYPE_ORIENTATION:
-                        orientationIndex = i;
-                        break;
-                    case SENSOR_TYPE_GYROSCOPE:
-                    case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
-                        hasGyro = true;
-                        break;
-                    case SENSOR_TYPE_GRAVITY:
-                    case SENSOR_TYPE_LINEAR_ACCELERATION:
-                    case SENSOR_TYPE_ROTATION_VECTOR:
-                        virtualSensorsNeeds &= ~(1<<list[i].type);
-                        break;
-                }
-            }
-
-            // it's safe to instantiate the SensorFusion object here
-            // (it wants to be instantiated after h/w sensors have been
-            // registered)
-            const SensorFusion& fusion(SensorFusion::getInstance());
-
-            // build the sensor list returned to users
-            mUserSensorList = mSensorList;
-
-            if (hasGyro) {
-                Sensor aSensor;
-
-                // Add Android virtual sensors if they're not already
-                // available in the HAL
-
-                aSensor = registerVirtualSensor( new RotationVectorSensor() );
-                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
-                    mUserSensorList.add(aSensor);
-                }
-
-                aSensor = registerVirtualSensor( new GravitySensor(list, count) );
-                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) {
-                    mUserSensorList.add(aSensor);
-                }
-
-                aSensor = registerVirtualSensor( new LinearAccelerationSensor(list, count) );
-                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) {
-                    mUserSensorList.add(aSensor);
-                }
-
-                aSensor = registerVirtualSensor( new OrientationSensor() );
-                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
-                    // if we are doing our own rotation-vector, also add
-                    // the orientation sensor and remove the HAL provided one.
-                    mUserSensorList.replaceAt(aSensor, orientationIndex);
-                }
-
-                // virtual debugging sensors are not added to mUserSensorList
-                registerVirtualSensor( new CorrectedGyroSensor(list, count) );
-                registerVirtualSensor( new GyroDriftSensor() );
-            }
-
-            // debugging sensor list
-            mUserSensorListDebug = mSensorList;
-
-            mSocketBufferSize = SOCKET_BUFFER_SIZE_NON_BATCHED;
-            FILE *fp = fopen("/proc/sys/net/core/wmem_max", "r");
-            char line[128];
-            if (fp != NULL && fgets(line, sizeof(line), fp) != NULL) {
-                line[sizeof(line) - 1] = '\0';
-                sscanf(line, "%u", &mSocketBufferSize);
-                if (mSocketBufferSize > MAX_SOCKET_BUFFER_SIZE_BATCHED) {
-                    mSocketBufferSize = MAX_SOCKET_BUFFER_SIZE_BATCHED;
-                }
-            }
-            ALOGD("Max socket buffer size %u", mSocketBufferSize);
-            if (fp) {
-                fclose(fp);
-            }
-
-            run("SensorService", PRIORITY_URGENT_DISPLAY);
-            mInitCheck = NO_ERROR;
-        }
-    }
-}
+	SensorDevice& dev(SensorDevice::getInstance());
 
-Sensor SensorService::registerSensor(SensorInterface* s)
-{
-    sensors_event_t event;
-    memset(&event, 0, sizeof(event));
-
-    const Sensor sensor(s->getSensor());
-    // add to the sensor list (returned to clients)
-    mSensorList.add(sensor);
-    // add to our handle->SensorInterface mapping
-    mSensorMap.add(sensor.getHandle(), s);
-    // create an entry in the mLastEventSeen array
-    mLastEventSeen.add(sensor.getHandle(), event);
-
-    return sensor;
-}
-
-Sensor SensorService::registerVirtualSensor(SensorInterface* s)
-{
-    Sensor sensor = registerSensor(s);
-    mVirtualSensorList.add( s );
-    return sensor;
-}
-
-SensorService::~SensorService()
-{
-    for (size_t i=0 ; i<mSensorMap.size() ; i++)
-        delete mSensorMap.valueAt(i);
+	if (dev.initCheck() == NO_ERROR) {
+		sensor_t const* list;
+		ssize_t count = dev.getSensorList(&list);
+		if (count > 0) {
+			ssize_t orientationIndex = -1;
+			bool hasGyro = false;
+			uint32_t virtualSensorsNeeds = (1 << SENSOR_TYPE_GRAVITY)
+					| (1 << SENSOR_TYPE_LINEAR_ACCELERATION)
+					| (1 << SENSOR_TYPE_ROTATION_VECTOR);
+
+			mLastEventSeen.setCapacity(count);
+			for (ssize_t i = 0; i < count; i++) {
+				registerSensor(new HardwareSensor(list[i]));
+				switch (list[i].type) {
+				case SENSOR_TYPE_ORIENTATION:
+					orientationIndex = i;
+					break;
+				case SENSOR_TYPE_GYROSCOPE:
+				case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
+					hasGyro = true;
+					break;
+				case SENSOR_TYPE_GRAVITY:
+				case SENSOR_TYPE_LINEAR_ACCELERATION:
+				case SENSOR_TYPE_ROTATION_VECTOR:
+					virtualSensorsNeeds &= ~(1 << list[i].type);
+					break;
+				}
+			}
+
+			// it's safe to instantiate the SensorFusion object here
+			// (it wants to be instantiated after h/w sensors have been
+			// registered)
+			const SensorFusion& fusion(SensorFusion::getInstance());
+
+			// build the sensor list returned to users
+			mUserSensorList = mSensorList;
+
+			if (hasGyro) {
+				Sensor aSensor;
+
+				// Add Android virtual sensors if they're not already
+				// available in the HAL
+
+				aSensor = registerVirtualSensor(new RotationVectorSensor());
+				if (virtualSensorsNeeds & (1 << SENSOR_TYPE_ROTATION_VECTOR)) {
+					mUserSensorList.add(aSensor);
+				}
+
+				aSensor = registerVirtualSensor(new GravitySensor(list, count));
+				if (virtualSensorsNeeds & (1 << SENSOR_TYPE_GRAVITY)) {
+					mUserSensorList.add(aSensor);
+				}
+
+				aSensor = registerVirtualSensor(
+						new LinearAccelerationSensor(list, count));
+				if (virtualSensorsNeeds
+						& (1 << SENSOR_TYPE_LINEAR_ACCELERATION)) {
+					mUserSensorList.add(aSensor);
+				}
+
+				aSensor = registerVirtualSensor(new OrientationSensor());
+				if (virtualSensorsNeeds & (1 << SENSOR_TYPE_ROTATION_VECTOR)) {
+					// if we are doing our own rotation-vector, also add
+					// the orientation sensor and remove the HAL provided one.
+					mUserSensorList.replaceAt(aSensor, orientationIndex);
+				}
+
+				// virtual debugging sensors are not added to mUserSensorList
+				registerVirtualSensor(new CorrectedGyroSensor(list, count));
+				registerVirtualSensor(new GyroDriftSensor());
+
+				registerVirtualSensor(new RemoteSensor());
+			}
+
+			// debugging sensor list
+			mUserSensorListDebug = mSensorList;
+
+			mSocketBufferSize = SOCKET_BUFFER_SIZE_NON_BATCHED;
+			FILE *fp = fopen("/proc/sys/net/core/wmem_max", "r");
+			char line[128];
+			if (fp != NULL && fgets(line, sizeof(line), fp) != NULL) {
+				line[sizeof(line) - 1] = '\0';
+				sscanf(line, "%u", &mSocketBufferSize);
+				if (mSocketBufferSize > MAX_SOCKET_BUFFER_SIZE_BATCHED) {
+					mSocketBufferSize = MAX_SOCKET_BUFFER_SIZE_BATCHED;
+				}
+			}
+			ALOGD("Max socket buffer size %u", mSocketBufferSize);
+			if (fp) {
+				fclose(fp);
+			}
+
+			// ADDED FOR COLLABOROID
+			mServerOn = false;
+
+			run("SensorService", PRIORITY_URGENT_DISPLAY);
+			mInitCheck = NO_ERROR;
+		}
+	}
+}
+
+Sensor SensorService::registerSensor(SensorInterface* s) {
+	sensors_event_t event;
+	memset(&event, 0, sizeof(event));
+
+	const Sensor sensor(s->getSensor());
+	// add to the sensor list (returned to clients)
+	mSensorList.add(sensor);
+	// add to our handle->SensorInterface mapping
+	mSensorMap.add(sensor.getHandle(), s);
+	// create an entry in the mLastEventSeen array
+	mLastEventSeen.add(sensor.getHandle(), event);
+
+	return sensor;
+}
+
+Sensor SensorService::registerVirtualSensor(SensorInterface* s) {
+	Sensor sensor = registerSensor(s);
+	mVirtualSensorList.add(s);
+	return sensor;
+}
+
+SensorService::~SensorService() {
+	for (size_t i = 0; i < mSensorMap.size(); i++)
+		delete mSensorMap.valueAt(i);
 }
 
 static const String16 sDump("android.permission.DUMP");
 
-status_t SensorService::dump(int fd, const Vector<String16>& args)
-{
-    String8 result;
-    if (!PermissionCache::checkCallingPermission(sDump)) {
-        result.appendFormat("Permission Denial: "
-                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
-                IPCThreadState::self()->getCallingPid(),
-                IPCThreadState::self()->getCallingUid());
-    } else {
-        Mutex::Autolock _l(mLock);
-        result.append("Sensor List:\n");
-        for (size_t i=0 ; i<mSensorList.size() ; i++) {
-            const Sensor& s(mSensorList[i]);
-            const sensors_event_t& e(mLastEventSeen.valueFor(s.getHandle()));
-            result.appendFormat(
-                    "%-48s| %-32s | 0x%08x | ",
-                    s.getName().string(),
-                    s.getVendor().string(),
-                    s.getHandle());
-
-            if (s.getMinDelay() > 0) {
-                result.appendFormat(
-                    "maxRate=%7.2fHz | ", 1e6f / s.getMinDelay());
-            } else {
-                result.append(s.getMinDelay() == 0
-                        ? "on-demand         | "
-                        : "one-shot          | ");
-            }
-            if (s.getFifoMaxEventCount() > 0) {
-                result.appendFormat("getFifoMaxEventCount=%d events | ", s.getFifoMaxEventCount());
-            } else {
-                result.append("no batching support | ");
-            }
-
-            switch (s.getType()) {
-                case SENSOR_TYPE_ROTATION_VECTOR:
-                case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
-                    result.appendFormat(
-                            "last=<%5.1f,%5.1f,%5.1f,%5.1f,%5.1f>\n",
-                            e.data[0], e.data[1], e.data[2], e.data[3], e.data[4]);
-                    break;
-                case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
-                case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
-                    result.appendFormat(
-                            "last=<%5.1f,%5.1f,%5.1f,%5.1f,%5.1f,%5.1f>\n",
-                            e.data[0], e.data[1], e.data[2], e.data[3], e.data[4], e.data[5]);
-                    break;
-                case SENSOR_TYPE_GAME_ROTATION_VECTOR:
-                    result.appendFormat(
-                            "last=<%5.1f,%5.1f,%5.1f,%5.1f>\n",
-                            e.data[0], e.data[1], e.data[2], e.data[3]);
-                    break;
-                case SENSOR_TYPE_SIGNIFICANT_MOTION:
-                case SENSOR_TYPE_STEP_DETECTOR:
-                    result.appendFormat( "last=<%f>\n", e.data[0]);
-                    break;
-                case SENSOR_TYPE_STEP_COUNTER:
-                    result.appendFormat( "last=<%llu>\n", e.u64.step_counter);
-                    break;
-                default:
-                    // default to 3 values
-                    result.appendFormat(
-                            "last=<%5.1f,%5.1f,%5.1f>\n",
-                            e.data[0], e.data[1], e.data[2]);
-                    break;
-            }
-        }
-        SensorFusion::getInstance().dump(result);
-        SensorDevice::getInstance().dump(result);
-
-        result.append("Active sensors:\n");
-        for (size_t i=0 ; i<mActiveSensors.size() ; i++) {
-            int handle = mActiveSensors.keyAt(i);
-            result.appendFormat("%s (handle=0x%08x, connections=%d)\n",
-                    getSensorName(handle).string(),
-                    handle,
-                    mActiveSensors.valueAt(i)->getNumConnections());
-        }
-
-        result.appendFormat("%u Max Socket Buffer size\n", mSocketBufferSize);
-        result.appendFormat("%d active connections\n", mActiveConnections.size());
-
-        for (size_t i=0 ; i < mActiveConnections.size() ; i++) {
-            sp<SensorEventConnection> connection(mActiveConnections[i].promote());
-            if (connection != 0) {
-                result.appendFormat("Connection Number: %d \n", i);
-                connection->dump(result);
-            }
-        }
-    }
-    write(fd, result.string(), result.size());
-    return NO_ERROR;
-}
-
-void SensorService::cleanupAutoDisabledSensor(const sp<SensorEventConnection>& connection,
-        sensors_event_t const* buffer, const int count) {
-    SensorInterface* sensor;
-    status_t err = NO_ERROR;
-    for (int i=0 ; i<count ; i++) {
-        int handle = buffer[i].sensor;
-        int type = buffer[i].type;
-        if (type == SENSOR_TYPE_SIGNIFICANT_MOTION) {
-            if (connection->hasSensor(handle)) {
-                sensor = mSensorMap.valueFor(handle);
-                if (sensor != NULL) {
-                    sensor->autoDisable(connection.get(), handle);
-                }
-                cleanupWithoutDisable(connection, handle);
-            }
-        }
-    }
-}
-
-bool SensorService::threadLoop()
-{
-    ALOGD("nuSensorService thread starting...");
-
-    // each virtual sensor could generate an event per "real" event, that's why we need
-    // to size numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT.
-    // in practice, this is too aggressive, but guaranteed to be enough.
-    const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
-    const size_t numEventMax = minBufferSize / (1 + mVirtualSensorList.size());
-
-    sensors_event_t buffer[minBufferSize];
-    sensors_event_t scratch[minBufferSize];
-    SensorDevice& device(SensorDevice::getInstance());
-    const size_t vcount = mVirtualSensorList.size();
-
-    ssize_t count;
-    bool wakeLockAcquired = false;
-    const int halVersion = device.getHalDeviceVersion();
-    do {
-        count = device.poll(buffer, numEventMax);
-        if (count<0) {
-            ALOGE("sensor poll failed (%s)", strerror(-count));
-            break;
-        }
-
-        // Poll has returned. Hold a wakelock.
-        // Todo(): add a flag to the sensors definitions to indicate
-        // the sensors which can wake up the AP
-        for (int i = 0; i < count; i++) {
-            if (buffer[i].type == SENSOR_TYPE_SIGNIFICANT_MOTION) {
-                 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
-                 wakeLockAcquired = true;
-                 break;
-            }
-        }
-
-        recordLastValue(buffer, count);
-
-        // handle virtual sensors
-        if (count && vcount) {
-            sensors_event_t const * const event = buffer;
-            const DefaultKeyedVector<int, SensorInterface*> virtualSensors(
-                    getActiveVirtualSensors());
-            const size_t activeVirtualSensorCount = virtualSensors.size();
-            if (activeVirtualSensorCount) {
-                size_t k = 0;
-                SensorFusion& fusion(SensorFusion::getInstance());
-                if (fusion.isEnabled()) {
-                    for (size_t i=0 ; i<size_t(count) ; i++) {
-                        fusion.process(event[i]);
-                    }
-                }
-                for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++) {
-                    for (size_t j=0 ; j<activeVirtualSensorCount ; j++) {
-                        if (count + k >= minBufferSize) {
-                            ALOGE("buffer too small to hold all events: "
-                                    "count=%u, k=%u, size=%u",
-                                    count, k, minBufferSize);
-                            break;
-                        }
-                        sensors_event_t out;
-                        SensorInterface* si = virtualSensors.valueAt(j);
-                        if (si->process(&out, event[i])) {
-                            buffer[count + k] = out;
-                            k++;
-                        }
-                    }
-                }
-                if (k) {
-                    // record the last synthesized values
-                    recordLastValue(&buffer[count], k);
-                    count += k;
-                    // sort the buffer by time-stamps
-                    sortEventBuffer(buffer, count);
-                }
-            }
-        }
-
-        // handle backward compatibility for RotationVector sensor
-        if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) {
-            for (int i = 0; i < count; i++) {
-                if (buffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) {
-                    // All the 4 components of the quaternion should be available
-                    // No heading accuracy. Set it to -1
-                    buffer[i].data[4] = -1;
-                }
-            }
-        }
-
-        // send our events to clients...
-        const SortedVector< wp<SensorEventConnection> > activeConnections(
-                getActiveConnections());
-        size_t numConnections = activeConnections.size();
-        for (size_t i=0 ; i<numConnections ; i++) {
-            sp<SensorEventConnection> connection(
-                    activeConnections[i].promote());
-            if (connection != 0) {
-                connection->sendEvents(buffer, count, scratch);
-                // Some sensors need to be auto disabled after the trigger
-                cleanupAutoDisabledSensor(connection, buffer, count);
-            }
-        }
-
-        // We have read the data, upper layers should hold the wakelock.
-        if (wakeLockAcquired) release_wake_lock(WAKE_LOCK_NAME);
-    } while (count >= 0 || Thread::exitPending());
-
-    ALOGW("Exiting SensorService::threadLoop => aborting...");
-    abort();
-    return false;
-}
-
-void SensorService::recordLastValue(
-        const sensors_event_t* buffer, size_t count) {
-    Mutex::Autolock _l(mLock);
-    const sensors_event_t* last = NULL;
-    for (size_t i = 0; i < count; i++) {
-        const sensors_event_t* event = &buffer[i];
-        if (event->type != SENSOR_TYPE_META_DATA) {
-            if (last && event->sensor != last->sensor) {
-                mLastEventSeen.editValueFor(last->sensor) = *last;
-            }
-            last = event;
-        }
-    }
-    if (last) {
-        mLastEventSeen.editValueFor(last->sensor) = *last;
-    }
-}
-
-void SensorService::sortEventBuffer(sensors_event_t* buffer, size_t count)
-{
-    struct compar {
-        static int cmp(void const* lhs, void const* rhs) {
-            sensors_event_t const* l = static_cast<sensors_event_t const*>(lhs);
-            sensors_event_t const* r = static_cast<sensors_event_t const*>(rhs);
-            return l->timestamp - r->timestamp;
-        }
-    };
-    qsort(buffer, count, sizeof(sensors_event_t), compar::cmp);
-}
-
-SortedVector< wp<SensorService::SensorEventConnection> >
-SensorService::getActiveConnections() const
-{
-    Mutex::Autolock _l(mLock);
-    return mActiveConnections;
-}
-
-DefaultKeyedVector<int, SensorInterface*>
-SensorService::getActiveVirtualSensors() const
-{
-    Mutex::Autolock _l(mLock);
-    return mActiveVirtualSensors;
+status_t SensorService::dump(int fd, const Vector<String16>& args) {
+	String8 result;
+	if (!PermissionCache::checkCallingPermission(sDump)) {
+		result.appendFormat("Permission Denial: "
+				"can't dump SurfaceFlinger from pid=%d, uid=%d\n",
+				IPCThreadState::self()->getCallingPid(),
+				IPCThreadState::self()->getCallingUid());
+	} else {
+		Mutex::Autolock _l(mLock);
+		result.append("Sensor List:\n");
+		for (size_t i = 0; i < mSensorList.size(); i++) {
+			const Sensor& s(mSensorList[i]);
+			const sensors_event_t& e(mLastEventSeen.valueFor(s.getHandle()));
+			result.appendFormat("%-48s| %-32s | 0x%08x | ",
+					s.getName().string(), s.getVendor().string(),
+					s.getHandle());
+
+			if (s.getMinDelay() > 0) {
+				result.appendFormat("maxRate=%7.2fHz | ",
+						1e6f / s.getMinDelay());
+			} else {
+				result.append(
+						s.getMinDelay() == 0 ?
+								"on-demand         | " :
+								"one-shot          | ");
+			}
+			if (s.getFifoMaxEventCount() > 0) {
+				result.appendFormat("getFifoMaxEventCount=%d events | ",
+						s.getFifoMaxEventCount());
+			} else {
+				result.append("no batching support | ");
+			}
+
+			switch (s.getType()) {
+			case SENSOR_TYPE_ROTATION_VECTOR:
+			case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
+				result.appendFormat("last=<%5.1f,%5.1f,%5.1f,%5.1f,%5.1f>\n",
+						e.data[0], e.data[1], e.data[2], e.data[3], e.data[4]);
+				break;
+			case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
+			case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
+				result.appendFormat(
+						"last=<%5.1f,%5.1f,%5.1f,%5.1f,%5.1f,%5.1f>\n",
+						e.data[0], e.data[1], e.data[2], e.data[3], e.data[4],
+						e.data[5]);
+				break;
+			case SENSOR_TYPE_GAME_ROTATION_VECTOR:
+				result.appendFormat("last=<%5.1f,%5.1f,%5.1f,%5.1f>\n",
+						e.data[0], e.data[1], e.data[2], e.data[3]);
+				break;
+			case SENSOR_TYPE_SIGNIFICANT_MOTION:
+			case SENSOR_TYPE_STEP_DETECTOR:
+				result.appendFormat("last=<%f>\n", e.data[0]);
+				break;
+			case SENSOR_TYPE_STEP_COUNTER:
+				result.appendFormat("last=<%llu>\n", e.u64.step_counter);
+				break;
+			default:
+				// default to 3 values
+				result.appendFormat("last=<%5.1f,%5.1f,%5.1f>\n", e.data[0],
+						e.data[1], e.data[2]);
+				break;
+			}
+		}
+		SensorFusion::getInstance().dump(result);
+		SensorDevice::getInstance().dump(result);
+
+		result.append("Active sensors:\n");
+		for (size_t i = 0; i < mActiveSensors.size(); i++) {
+			int handle = mActiveSensors.keyAt(i);
+			result.appendFormat("%s (handle=0x%08x, connections=%d)\n",
+					getSensorName(handle).string(), handle,
+					mActiveSensors.valueAt(i)->getNumConnections());
+		}
+
+		result.appendFormat("%u Max Socket Buffer size\n", mSocketBufferSize);
+		result.appendFormat("%d active connections\n",
+				mActiveConnections.size());
+
+		for (size_t i = 0; i < mActiveConnections.size(); i++) {
+			sp<SensorEventConnection> connection(
+					mActiveConnections[i].promote());
+			if (connection != 0) {
+				result.appendFormat("Connection Number: %d \n", i);
+				connection->dump(result);
+			}
+		}
+	}
+	write(fd, result.string(), result.size());
+	return NO_ERROR;
+}
+
+void SensorService::cleanupAutoDisabledSensor(
+		const sp<SensorEventConnection>& connection,
+		sensors_event_t const* buffer, const int count) {
+	SensorInterface* sensor;
+	status_t err = NO_ERROR;
+	for (int i = 0; i < count; i++) {
+		int handle = buffer[i].sensor;
+		int type = buffer[i].type;
+		if (type == SENSOR_TYPE_SIGNIFICANT_MOTION) {
+			if (connection->hasSensor(handle)) {
+				sensor = mSensorMap.valueFor(handle);
+				if (sensor != NULL) {
+					sensor->autoDisable(connection.get(), handle);
+				}
+				cleanupWithoutDisable(connection, handle);
+			}
+		}
+	}
+}
+
+bool SensorService::threadLoop() {
+	ALOGD("nuSensorService thread starting...");
+
+	// each virtual sensor could generate an event per "real" event, that's why we need
+	// to size numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT.
+	// in practice, this is too aggressive, but guaranteed to be enough.
+	const size_t minBufferSize =
+			SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
+	const size_t numEventMax = minBufferSize / (1 + mVirtualSensorList.size());
+
+	sensors_event_t buffer[minBufferSize];
+	sensors_event_t scratch[minBufferSize];
+	SensorDevice& device(SensorDevice::getInstance());
+	const size_t vcount = mVirtualSensorList.size();
+
+	ssize_t count;
+	bool wakeLockAcquired = false;
+	const int halVersion = device.getHalDeviceVersion();
+	do {
+		count = device.poll(buffer, numEventMax);
+		if (count < 0) {
+			ALOGE("sensor poll failed (%s)", strerror(-count));
+			break;
+		}
+
+		// Poll has returned. Hold a wakelock.
+		// Todo(): add a flag to the sensors definitions to indicate
+		// the sensors which can wake up the AP
+		for (int i = 0; i < count; i++) {
+			if (buffer[i].type == SENSOR_TYPE_SIGNIFICANT_MOTION) {
+				acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
+				wakeLockAcquired = true;
+				break;
+			}
+		}
+
+		recordLastValue(buffer, count);
+
+		// handle virtual sensors
+		if (count && vcount) {
+			sensors_event_t const * const event = buffer;
+			const DefaultKeyedVector<int, SensorInterface*> virtualSensors(
+					getActiveVirtualSensors());
+			const size_t activeVirtualSensorCount = virtualSensors.size();
+			if (activeVirtualSensorCount) {
+				size_t k = 0;
+				SensorFusion& fusion(SensorFusion::getInstance());
+				if (fusion.isEnabled()) {
+					for (size_t i = 0; i < size_t(count); i++) {
+						fusion.process(event[i]);
+					}
+				}
+				for (size_t i = 0; i < size_t(count) && k < minBufferSize;
+						i++) {
+					for (size_t j = 0; j < activeVirtualSensorCount; j++) {
+						if (count + k >= minBufferSize) {
+							ALOGE("buffer too small to hold all events: "
+							"count=%u, k=%u, size=%u", count, k, minBufferSize);
+							break;
+						}
+						sensors_event_t out;
+						SensorInterface* si = virtualSensors.valueAt(j);
+						if (si->process(&out, event[i])) {
+							buffer[count + k] = out;
+							k++;
+						}
+					}
+				}
+				if (k) {
+					// record the last synthesized values
+					recordLastValue(&buffer[count], k);
+					count += k;
+					// sort the buffer by time-stamps
+					sortEventBuffer(buffer, count);
+				}
+			}
+		}
+
+		// handle backward compatibility for RotationVector sensor
+		if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) {
+			for (int i = 0; i < count; i++) {
+				if (buffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) {
+					// All the 4 components of the quaternion should be available
+					// No heading accuracy. Set it to -1
+					buffer[i].data[4] = -1;
+				}
+			}
+		}
+
+		// ADDED FOR COLLABOROID
+		if(mServerOn)
+		{
+			//if(buffer[0].type == 3)
+				//ALOGD("type:%d, sensor:%d", buffer[0].type, buffer[0].sensor);
+
+			continue;
+		}
+
+		// send our events to clients...
+		const SortedVector<wp<SensorEventConnection> > activeConnections(
+				getActiveConnections());
+		size_t numConnections = activeConnections.size();
+		for (size_t i = 0; i < numConnections; i++) {
+			sp<SensorEventConnection> connection(
+					activeConnections[i].promote());
+			if (connection != 0) {
+				connection->sendEvents(buffer, count, scratch);
+				// Some sensors need to be auto disabled after the trigger
+				cleanupAutoDisabledSensor(connection, buffer, count);
+			}
+		}
+
+		// We have read the data, upper layers should hold the wakelock.
+		if (wakeLockAcquired)
+			release_wake_lock(WAKE_LOCK_NAME);
+	} while (count >= 0 || Thread::exitPending());
+
+	ALOGW("Exiting SensorService::threadLoop => aborting...");
+	abort();
+	return false;
+}
+
+// ADDED FOR COLLABOROID
+void SensorService::sendRemoteEvent(int32_t type, int32_t sensor, float* data, int8_t status, int64_t timestamp, int32_t sourcedevice)
+{
+	//ALOGD("sensor:%d, data:%f,%f,%f, timestamp:%lld", sensor, data[0], data[1], data[2], timestamp);
+
+	/*const size_t minBufferSize =
+				SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;*/
+	sensors_event_t buffer[1];
+	sensors_event_t scratch[1];
+	//size_t count = 10;
+
+	/*for(size_t i=0; i<10; i++)
+	{
+		memset(&buffer[i], 0, sizeof(buffer[i]));
+		buffer[i].type = SENSOR_TYPE_LIGHT;
+		buffer[i].sensor = SENSOR_TYPE_LIGHT;
+	}*/
+	memset(&buffer[0], 0, sizeof(buffer));
+
+	buffer[0].type = type;
+	buffer[0].sensor = sensor;
+	memcpy(buffer[0].data, data, 16*sizeof(float));
+	buffer[0].orientation.status = status;
+	buffer[0].gyro.status = status;
+	buffer[0].timestamp = timestamp;
+	buffer[0].reserved0 = sourcedevice;
+
+
+	const SortedVector<wp<SensorEventConnection> > activeConnections(getActiveConnections());
+	size_t numConnections = activeConnections.size();
+	for (size_t i = 0; i < numConnections; i++) {
+		sp<SensorEventConnection> connection(activeConnections[i].promote());
+		if (connection != 0) {
+			connection->sendEvents(buffer, 1, scratch);
+			// Some sensors need to be auto disabled after the trigger
+			cleanupAutoDisabledSensor(connection, buffer, 1);
+		}
+	}
+
+	//free(buffer);
+	/*if (wakeLockAcquired)
+		release_wake_lock(WAKE_LOCK_NAME);*/
+}
+
+void SensorService::setServerOn(bool flag)
+{
+	if(flag)
+		ALOGE("true");
+	else if(!flag)
+		ALOGE("false");
+
+	mServerOn = flag;
+}
+// ADDED FOR COLLABOROID
+
+void SensorService::recordLastValue(const sensors_event_t* buffer,
+		size_t count) {
+	Mutex::Autolock _l(mLock);
+	const sensors_event_t* last = NULL;
+	for (size_t i = 0; i < count; i++) {
+		const sensors_event_t* event = &buffer[i];
+		if (event->type != SENSOR_TYPE_META_DATA) {
+			if (last && event->sensor != last->sensor) {
+				mLastEventSeen.editValueFor(last->sensor) = *last;
+			}
+			last = event;
+		}
+	}
+	if (last) {
+		mLastEventSeen.editValueFor(last->sensor) = *last;
+	}
+}
+
+void SensorService::sortEventBuffer(sensors_event_t* buffer, size_t count) {
+	struct compar {
+		static int cmp(void const* lhs, void const* rhs) {
+			sensors_event_t const* l = static_cast<sensors_event_t const*>(lhs);
+			sensors_event_t const* r = static_cast<sensors_event_t const*>(rhs);
+			return l->timestamp - r->timestamp;
+		}
+	};
+	qsort(buffer, count, sizeof(sensors_event_t), compar::cmp);
+}
+
+SortedVector<wp<SensorService::SensorEventConnection> > SensorService::getActiveConnections() const {
+	Mutex::Autolock _l(mLock);
+	return mActiveConnections;
+}
+
+DefaultKeyedVector<int, SensorInterface*> SensorService::getActiveVirtualSensors() const {
+	Mutex::Autolock _l(mLock);
+	return mActiveVirtualSensors;
 }
 
 String8 SensorService::getSensorName(int handle) const {
-    size_t count = mUserSensorList.size();
-    for (size_t i=0 ; i<count ; i++) {
-        const Sensor& sensor(mUserSensorList[i]);
-        if (sensor.getHandle() == handle) {
-            return sensor.getName();
-        }
-    }
-    String8 result("unknown");
-    return result;
+	size_t count = mUserSensorList.size();
+	for (size_t i = 0; i < count; i++) {
+		const Sensor& sensor(mUserSensorList[i]);
+		if (sensor.getHandle() == handle) {
+			return sensor.getName();
+		}
+	}
+	String8 result("unknown");
+	return result;
 }
 
 bool SensorService::isVirtualSensor(int handle) const {
-    SensorInterface* sensor = mSensorMap.valueFor(handle);
-    return sensor->isVirtual();
-}
-
-Vector<Sensor> SensorService::getSensorList()
-{
-    char value[PROPERTY_VALUE_MAX];
-    property_get("debug.sensors", value, "0");
-    if (atoi(value)) {
-        return mUserSensorListDebug;
-    }
-    return mUserSensorList;
+	SensorInterface* sensor = mSensorMap.valueFor(handle);
+	return sensor->isVirtual();
 }
 
-sp<ISensorEventConnection> SensorService::createSensorEventConnection()
-{
-    uid_t uid = IPCThreadState::self()->getCallingUid();
-    sp<SensorEventConnection> result(new SensorEventConnection(this, uid));
-    return result;
-}
-
-void SensorService::cleanupConnection(SensorEventConnection* c)
-{
-    Mutex::Autolock _l(mLock);
-    const wp<SensorEventConnection> connection(c);
-    size_t size = mActiveSensors.size();
-    ALOGD_IF(DEBUG_CONNECTIONS, "%d active sensors", size);
-    for (size_t i=0 ; i<size ; ) {
-        int handle = mActiveSensors.keyAt(i);
-        if (c->hasSensor(handle)) {
-            ALOGD_IF(DEBUG_CONNECTIONS, "%i: disabling handle=0x%08x", i, handle);
-            SensorInterface* sensor = mSensorMap.valueFor( handle );
-            ALOGE_IF(!sensor, "mSensorMap[handle=0x%08x] is null!", handle);
-            if (sensor) {
-                sensor->activate(c, false);
-            }
-        }
-        SensorRecord* rec = mActiveSensors.valueAt(i);
-        ALOGE_IF(!rec, "mActiveSensors[%d] is null (handle=0x%08x)!", i, handle);
-        ALOGD_IF(DEBUG_CONNECTIONS,
-                "removing connection %p for sensor[%d].handle=0x%08x",
-                c, i, handle);
-
-        if (rec && rec->removeConnection(connection)) {
-            ALOGD_IF(DEBUG_CONNECTIONS, "... and it was the last connection");
-            mActiveSensors.removeItemsAt(i, 1);
-            mActiveVirtualSensors.removeItem(handle);
-            delete rec;
-            size--;
-        } else {
-            i++;
-        }
-    }
-    mActiveConnections.remove(connection);
-    BatteryService::cleanup(c->getUid());
+Vector<Sensor> SensorService::getSensorList() {
+	char value[PROPERTY_VALUE_MAX];
+	property_get("debug.sensors", value, "0");
+	if (atoi(value)) {
+		return mUserSensorListDebug;
+	}
+	return mUserSensorList;
+}
+
+sp<ISensorEventConnection> SensorService::createSensorEventConnection() {
+	uid_t uid = IPCThreadState::self()->getCallingUid();
+	sp<SensorEventConnection> result(new SensorEventConnection(this, uid));
+	return result;
+}
+
+void SensorService::cleanupConnection(SensorEventConnection* c) {
+	Mutex::Autolock _l(mLock);
+	const wp<SensorEventConnection> connection(c);
+	size_t size = mActiveSensors.size();
+	ALOGD_IF(DEBUG_CONNECTIONS, "%d active sensors", size);
+	for (size_t i = 0; i < size;) {
+		int handle = mActiveSensors.keyAt(i);
+		if (c->hasSensor(handle)) {
+			ALOGD_IF(DEBUG_CONNECTIONS,
+					"%i: disabling handle=0x%08x", i, handle);
+			SensorInterface* sensor = mSensorMap.valueFor(handle);
+			ALOGE_IF(!sensor, "mSensorMap[handle=0x%08x] is null!", handle);
+			if (sensor) {
+				sensor->activate(c, false);
+			}
+		}
+		SensorRecord* rec = mActiveSensors.valueAt(i);
+		ALOGE_IF(!rec,
+				"mActiveSensors[%d] is null (handle=0x%08x)!", i, handle);
+		ALOGD_IF(DEBUG_CONNECTIONS,
+				"removing connection %p for sensor[%d].handle=0x%08x", c, i, handle);
+
+		if (rec && rec->removeConnection(connection)) {
+			ALOGD_IF(DEBUG_CONNECTIONS, "... and it was the last connection");
+			mActiveSensors.removeItemsAt(i, 1);
+			mActiveVirtualSensors.removeItem(handle);
+			delete rec;
+			size--;
+		} else {
+			i++;
+		}
+	}
+	mActiveConnections.remove(connection);
+	BatteryService::cleanup(c->getUid());
 }
 
 status_t SensorService::enable(const sp<SensorEventConnection>& connection,
-        int handle, nsecs_t samplingPeriodNs,  nsecs_t maxBatchReportLatencyNs, int reservedFlags)
-{
-    if (mInitCheck != NO_ERROR)
-        return mInitCheck;
-
-    SensorInterface* sensor = mSensorMap.valueFor(handle);
-    if (sensor == NULL) {
-        return BAD_VALUE;
-    }
-    Mutex::Autolock _l(mLock);
-    SensorRecord* rec = mActiveSensors.valueFor(handle);
-    if (rec == 0) {
-        rec = new SensorRecord(connection);
-        mActiveSensors.add(handle, rec);
-        if (sensor->isVirtual()) {
-            mActiveVirtualSensors.add(handle, sensor);
-        }
-    } else {
-        if (rec->addConnection(connection)) {
-            // this sensor is already activated, but we are adding a
-            // connection that uses it. Immediately send down the last
-            // known value of the requested sensor if it's not a
-            // "continuous" sensor.
-            if (sensor->getSensor().getMinDelay() == 0) {
-                sensors_event_t scratch;
-                sensors_event_t& event(mLastEventSeen.editValueFor(handle));
-                if (event.version == sizeof(sensors_event_t)) {
-                    connection->sendEvents(&event, 1);
-                }
-            }
-        }
-    }
-
-    if (connection->addSensor(handle)) {
-        BatteryService::enableSensor(connection->getUid(), handle);
-        // the sensor was added (which means it wasn't already there)
-        // so, see if this connection becomes active
-        if (mActiveConnections.indexOf(connection) < 0) {
-            mActiveConnections.add(connection);
-        }
-    } else {
-        ALOGW("sensor %08x already enabled in connection %p (ignoring)",
-            handle, connection.get());
-    }
-
-    nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
-    if (samplingPeriodNs < minDelayNs) {
-        samplingPeriodNs = minDelayNs;
-    }
-
-    ALOGD_IF(DEBUG_CONNECTIONS, "Calling batch handle==%d flags=%d rate=%lld timeout== %lld",
-             handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs);
-
-    status_t err = sensor->batch(connection.get(), handle, reservedFlags, samplingPeriodNs,
-                                 maxBatchReportLatencyNs);
-    if (err == NO_ERROR) {
-        connection->setFirstFlushPending(handle, true);
-        status_t err_flush = sensor->flush(connection.get(), handle);
-        // Flush may return error if the sensor is not activated or the underlying h/w sensor does
-        // not support flush.
-        if (err_flush != NO_ERROR) {
-            connection->setFirstFlushPending(handle, false);
-        }
-    }
-
-    if (err == NO_ERROR) {
-        ALOGD_IF(DEBUG_CONNECTIONS, "Calling activate on %d", handle);
-        err = sensor->activate(connection.get(), true);
-    }
-
-    if (err != NO_ERROR) {
-        // batch/activate has failed, reset our state.
-        cleanupWithoutDisableLocked(connection, handle);
-    }
-    return err;
+		int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
+		int reservedFlags) {
+	if (mInitCheck != NO_ERROR)
+		return mInitCheck;
+
+	SensorInterface* sensor = mSensorMap.valueFor(handle);
+	if (sensor == NULL) {
+		return BAD_VALUE;
+	}
+	Mutex::Autolock _l(mLock);
+	SensorRecord* rec = mActiveSensors.valueFor(handle);
+	if (rec == 0) {
+		rec = new SensorRecord(connection);
+		mActiveSensors.add(handle, rec);
+		if (sensor->isVirtual()) {
+			mActiveVirtualSensors.add(handle, sensor);
+		}
+	} else {
+		if (rec->addConnection(connection)) {
+			// this sensor is already activated, but we are adding a
+			// connection that uses it. Immediately send down the last
+			// known value of the requested sensor if it's not a
+			// "continuous" sensor.
+			if (sensor->getSensor().getMinDelay() == 0) {
+				sensors_event_t scratch;
+				sensors_event_t& event(mLastEventSeen.editValueFor(handle));
+				if (event.version == sizeof(sensors_event_t)) {
+					connection->sendEvents(&event, 1);
+				}
+			}
+		}
+	}
+
+	if (connection->addSensor(handle)) {
+		BatteryService::enableSensor(connection->getUid(), handle);
+		// the sensor was added (which means it wasn't already there)
+		// so, see if this connection becomes active
+		if (mActiveConnections.indexOf(connection) < 0) {
+			mActiveConnections.add(connection);
+		}
+	} else {
+		ALOGW(
+				"sensor %08x already enabled in connection %p (ignoring)", handle, connection.get());
+	}
+
+	nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
+	if (samplingPeriodNs < minDelayNs) {
+		samplingPeriodNs = minDelayNs;
+	}
+
+	ALOGD_IF(DEBUG_CONNECTIONS,
+			"Calling batch handle==%d flags=%d rate=%lld timeout== %lld", handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs);
+
+	status_t err = sensor->batch(connection.get(), handle, reservedFlags,
+			samplingPeriodNs, maxBatchReportLatencyNs);
+	if (err == NO_ERROR) {
+		connection->setFirstFlushPending(handle, true);
+		status_t err_flush = sensor->flush(connection.get(), handle);
+		// Flush may return error if the sensor is not activated or the underlying h/w sensor does
+		// not support flush.
+		if (err_flush != NO_ERROR) {
+			connection->setFirstFlushPending(handle, false);
+		}
+	}
+
+	if (err == NO_ERROR) {
+		ALOGD_IF(DEBUG_CONNECTIONS, "Calling activate on %d", handle);
+		err = sensor->activate(connection.get(), true);
+	}
+
+	if (err != NO_ERROR) {
+		// batch/activate has failed, reset our state.
+		cleanupWithoutDisableLocked(connection, handle);
+	}
+	return err;
 }
 
 status_t SensorService::disable(const sp<SensorEventConnection>& connection,
-        int handle)
-{
-    if (mInitCheck != NO_ERROR)
-        return mInitCheck;
-
-    Mutex::Autolock _l(mLock);
-    status_t err = cleanupWithoutDisableLocked(connection, handle);
-    if (err == NO_ERROR) {
-        SensorInterface* sensor = mSensorMap.valueFor(handle);
-        err = sensor ? sensor->activate(connection.get(), false) : status_t(BAD_VALUE);
-    }
-    return err;
+		int handle) {
+	if (mInitCheck != NO_ERROR)
+		return mInitCheck;
+
+	Mutex::Autolock _l(mLock);
+	status_t err = cleanupWithoutDisableLocked(connection, handle);
+	if (err == NO_ERROR) {
+		SensorInterface* sensor = mSensorMap.valueFor(handle);
+		err = sensor ?
+				sensor->activate(connection.get(), false) : status_t(BAD_VALUE);
+	}
+	return err;
 }
 
 status_t SensorService::cleanupWithoutDisable(
-        const sp<SensorEventConnection>& connection, int handle) {
-    Mutex::Autolock _l(mLock);
-    return cleanupWithoutDisableLocked(connection, handle);
+		const sp<SensorEventConnection>& connection, int handle) {
+	Mutex::Autolock _l(mLock);
+	return cleanupWithoutDisableLocked(connection, handle);
 }
 
 status_t SensorService::cleanupWithoutDisableLocked(
-        const sp<SensorEventConnection>& connection, int handle) {
-    SensorRecord* rec = mActiveSensors.valueFor(handle);
-    if (rec) {
-        // see if this connection becomes inactive
-        if (connection->removeSensor(handle)) {
-            BatteryService::disableSensor(connection->getUid(), handle);
-        }
-        if (connection->hasAnySensor() == false) {
-            mActiveConnections.remove(connection);
-        }
-        // see if this sensor becomes inactive
-        if (rec->removeConnection(connection)) {
-            mActiveSensors.removeItem(handle);
-            mActiveVirtualSensors.removeItem(handle);
-            delete rec;
-        }
-        return NO_ERROR;
-    }
-    return BAD_VALUE;
-}
+		const sp<SensorEventConnection>& connection, int handle) {
+	SensorRecord* rec = mActiveSensors.valueFor(handle);
+	if (rec) {
+		// see if this connection becomes inactive
+		if (connection->removeSensor(handle)) {
+			BatteryService::disableSensor(connection->getUid(), handle);
+		}
+		if (connection->hasAnySensor() == false) {
+			mActiveConnections.remove(connection);
+		}
+		// see if this sensor becomes inactive
+		if (rec->removeConnection(connection)) {
+			mActiveSensors.removeItem(handle);
+			mActiveVirtualSensors.removeItem(handle);
+			delete rec;
+		}
+		return NO_ERROR;
+	}
+	return BAD_VALUE;
+}
+
+status_t SensorService::setEventRate(
+		const sp<SensorEventConnection>& connection, int handle, nsecs_t ns) {
+	if (mInitCheck != NO_ERROR)
+		return mInitCheck;
+
+	SensorInterface* sensor = mSensorMap.valueFor(handle);
+	if (!sensor)
+		return BAD_VALUE;
+
+	if (ns < 0)
+		return BAD_VALUE;
+
+	nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
+	if (ns < minDelayNs) {
+		ns = minDelayNs;
+	}
 
-status_t SensorService::setEventRate(const sp<SensorEventConnection>& connection,
-        int handle, nsecs_t ns)
-{
-    if (mInitCheck != NO_ERROR)
-        return mInitCheck;
-
-    SensorInterface* sensor = mSensorMap.valueFor(handle);
-    if (!sensor)
-        return BAD_VALUE;
-
-    if (ns < 0)
-        return BAD_VALUE;
-
-    nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
-    if (ns < minDelayNs) {
-        ns = minDelayNs;
-    }
-
-    return sensor->setDelay(connection.get(), handle, ns);
+	return sensor->setDelay(connection.get(), handle, ns);
 }
 
 status_t SensorService::flushSensor(const sp<SensorEventConnection>& connection,
-                                    int handle) {
-  if (mInitCheck != NO_ERROR) return mInitCheck;
-  SensorInterface* sensor = mSensorMap.valueFor(handle);
-  if (sensor == NULL) {
-      return BAD_VALUE;
-  }
-  if (sensor->getSensor().getType() == SENSOR_TYPE_SIGNIFICANT_MOTION) {
-      ALOGE("flush called on Significant Motion sensor");
-      return INVALID_OPERATION;
-  }
-  return sensor->flush(connection.get(), handle);
+		int handle) {
+	if (mInitCheck != NO_ERROR)
+		return mInitCheck;
+	SensorInterface* sensor = mSensorMap.valueFor(handle);
+	if (sensor == NULL) {
+		return BAD_VALUE;
+	}
+	if (sensor->getSensor().getType() == SENSOR_TYPE_SIGNIFICANT_MOTION) {
+		ALOGE("flush called on Significant Motion sensor");
+		return INVALID_OPERATION;
+	}
+	return sensor->flush(connection.get(), handle);
 }
 // ---------------------------------------------------------------------------
 
 SensorService::SensorRecord::SensorRecord(
-        const sp<SensorEventConnection>& connection)
-{
-    mConnections.add(connection);
+		const sp<SensorEventConnection>& connection) {
+	mConnections.add(connection);
 }
 
 bool SensorService::SensorRecord::addConnection(
-        const sp<SensorEventConnection>& connection)
-{
-    if (mConnections.indexOf(connection) < 0) {
-        mConnections.add(connection);
-        return true;
-    }
-    return false;
+		const sp<SensorEventConnection>& connection) {
+	if (mConnections.indexOf(connection) < 0) {
+		mConnections.add(connection);
+		return true;
+	}
+	return false;
 }
 
 bool SensorService::SensorRecord::removeConnection(
-        const wp<SensorEventConnection>& connection)
-{
-    ssize_t index = mConnections.indexOf(connection);
-    if (index >= 0) {
-        mConnections.removeItemsAt(index, 1);
-    }
-    return mConnections.size() ? false : true;
+		const wp<SensorEventConnection>& connection) {
+	ssize_t index = mConnections.indexOf(connection);
+	if (index >= 0) {
+		mConnections.removeItemsAt(index, 1);
+	}
+	return mConnections.size() ? false : true;
 }
 
 // ---------------------------------------------------------------------------
 
 SensorService::SensorEventConnection::SensorEventConnection(
-        const sp<SensorService>& service, uid_t uid)
-    : mService(service), mUid(uid)
-{
-    const SensorDevice& device(SensorDevice::getInstance());
-    if (device.getHalDeviceVersion() >= SENSORS_DEVICE_API_VERSION_1_1) {
-        // Increase socket buffer size to 1MB for batching capabilities.
-        mChannel = new BitTube(service->mSocketBufferSize);
-    } else {
-        mChannel = new BitTube(SOCKET_BUFFER_SIZE_NON_BATCHED);
-    }
-}
-
-SensorService::SensorEventConnection::~SensorEventConnection()
-{
-    ALOGD_IF(DEBUG_CONNECTIONS, "~SensorEventConnection(%p)", this);
-    mService->cleanupConnection(this);
+		const sp<SensorService>& service, uid_t uid) :
+		mService(service), mUid(uid) {
+	const SensorDevice& device(SensorDevice::getInstance());
+	if (device.getHalDeviceVersion() >= SENSORS_DEVICE_API_VERSION_1_1) {
+		// Increase socket buffer size to 1MB for batching capabilities.
+		mChannel = new BitTube(service->mSocketBufferSize);
+	} else {
+		mChannel = new BitTube(SOCKET_BUFFER_SIZE_NON_BATCHED);
+	}
+}
+
+SensorService::SensorEventConnection::~SensorEventConnection() {
+	ALOGD_IF(DEBUG_CONNECTIONS, "~SensorEventConnection(%p)", this);
+	mService->cleanupConnection(this);
 }
 
-void SensorService::SensorEventConnection::onFirstRef()
-{
+void SensorService::SensorEventConnection::onFirstRef() {
 }
 
 void SensorService::SensorEventConnection::dump(String8& result) {
-    Mutex::Autolock _l(mConnectionLock);
-    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
-        const FlushInfo& flushInfo = mSensorInfo.valueAt(i);
-        result.appendFormat("\t %s | status: %s | pending flush events %d\n",
-                            mService->getSensorName(mSensorInfo.keyAt(i)).string(),
-                            flushInfo.mFirstFlushPending ? "First flush pending" :
-                                                           "active",
-                            flushInfo.mPendingFlushEventsToSend);
-    }
+	Mutex::Autolock _l(mConnectionLock);
+	for (size_t i = 0; i < mSensorInfo.size(); ++i) {
+		const FlushInfo& flushInfo = mSensorInfo.valueAt(i);
+		result.appendFormat("\t %s | status: %s | pending flush events %d\n",
+				mService->getSensorName(mSensorInfo.keyAt(i)).string(),
+				flushInfo.mFirstFlushPending ? "First flush pending" : "active",
+				flushInfo.mPendingFlushEventsToSend);
+	}
 }
 
 bool SensorService::SensorEventConnection::addSensor(int32_t handle) {
-    Mutex::Autolock _l(mConnectionLock);
-    if (mSensorInfo.indexOfKey(handle) < 0) {
-        mSensorInfo.add(handle, FlushInfo());
-        return true;
-    }
-    return false;
+	Mutex::Autolock _l(mConnectionLock);
+	if (mSensorInfo.indexOfKey(handle) < 0) {
+		mSensorInfo.add(handle, FlushInfo());
+		return true;
+	}
+	return false;
 }
 
 bool SensorService::SensorEventConnection::removeSensor(int32_t handle) {
-    Mutex::Autolock _l(mConnectionLock);
-    if (mSensorInfo.removeItem(handle) >= 0) {
-        return true;
-    }
-    return false;
+	Mutex::Autolock _l(mConnectionLock);
+	if (mSensorInfo.removeItem(handle) >= 0) {
+		return true;
+	}
+	return false;
 }
 
 bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const {
-    Mutex::Autolock _l(mConnectionLock);
-    return mSensorInfo.indexOfKey(handle) >= 0;
+	Mutex::Autolock _l(mConnectionLock);
+	return mSensorInfo.indexOfKey(handle) >= 0;
 }
 
 bool SensorService::SensorEventConnection::hasAnySensor() const {
-    Mutex::Autolock _l(mConnectionLock);
-    return mSensorInfo.size() ? true : false;
+	Mutex::Autolock _l(mConnectionLock);
+	return mSensorInfo.size() ? true : false;
 }
 
 void SensorService::SensorEventConnection::setFirstFlushPending(int32_t handle,
-                                bool value) {
-    Mutex::Autolock _l(mConnectionLock);
-    ssize_t index = mSensorInfo.indexOfKey(handle);
-    if (index >= 0) {
-        FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
-        flushInfo.mFirstFlushPending = value;
-    }
+		bool value) {
+	Mutex::Autolock _l(mConnectionLock);
+	ssize_t index = mSensorInfo.indexOfKey(handle);
+	if (index >= 0) {
+		FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
+		flushInfo.mFirstFlushPending = value;
+	}
 }
 
 status_t SensorService::SensorEventConnection::sendEvents(
-        sensors_event_t const* buffer, size_t numEvents,
-        sensors_event_t* scratch)
-{
-    // filter out events not for this connection
-    size_t count = 0;
-
-    if (scratch) {
-        Mutex::Autolock _l(mConnectionLock);
-        size_t i=0;
-        while (i<numEvents) {
-            int32_t curr = buffer[i].sensor;
-            if (buffer[i].type == SENSOR_TYPE_META_DATA) {
-                ALOGD_IF(DEBUG_CONNECTIONS, "flush complete event sensor==%d ",
-                         buffer[i].meta_data.sensor);
-                // Setting curr to the correct sensor to ensure the sensor events per connection are
-                // filtered correctly. buffer[i].sensor is zero for meta_data events.
-                curr = buffer[i].meta_data.sensor;
-            }
-            ssize_t index = mSensorInfo.indexOfKey(curr);
-            if (index >= 0 && mSensorInfo[index].mFirstFlushPending == true &&
-                buffer[i].type == SENSOR_TYPE_META_DATA) {
-                // This is the first flush before activate is called. Events can now be sent for
-                // this sensor on this connection.
-                ALOGD_IF(DEBUG_CONNECTIONS, "First flush event for sensor==%d ",
-                         buffer[i].meta_data.sensor);
-                mSensorInfo.editValueAt(index).mFirstFlushPending = false;
-            }
-            if (index >= 0 && mSensorInfo[index].mFirstFlushPending == false)  {
-                do {
-                    scratch[count++] = buffer[i++];
-                } while ((i<numEvents) && ((buffer[i].sensor == curr) ||
-                         (buffer[i].type == SENSOR_TYPE_META_DATA  &&
-                          buffer[i].meta_data.sensor == curr)));
-            } else {
-                i++;
-            }
-        }
-    } else {
-        scratch = const_cast<sensors_event_t *>(buffer);
-        count = numEvents;
-    }
-
-    // Send pending flush events (if any) before sending events from the cache.
-    {
-        ASensorEvent flushCompleteEvent;
-        flushCompleteEvent.type = SENSOR_TYPE_META_DATA;
-        flushCompleteEvent.sensor = 0;
-        Mutex::Autolock _l(mConnectionLock);
-        // Loop through all the sensors for this connection and check if there are any pending
-        // flush complete events to be sent.
-        for (size_t i = 0; i < mSensorInfo.size(); ++i) {
-            FlushInfo& flushInfo = mSensorInfo.editValueAt(i);
-            while (flushInfo.mPendingFlushEventsToSend > 0) {
-                flushCompleteEvent.meta_data.sensor = mSensorInfo.keyAt(i);
-                ssize_t size = SensorEventQueue::write(mChannel, &flushCompleteEvent, 1);
-                if (size < 0) {
-                    // ALOGW("dropping %d events on the floor", count);
-                    countFlushCompleteEventsLocked(scratch, count);
-                    return size;
-                }
-                ALOGD_IF(DEBUG_CONNECTIONS, "sent dropped flush complete event==%d ",
-                         flushCompleteEvent.meta_data.sensor);
-                flushInfo.mPendingFlushEventsToSend--;
-            }
-        }
-    }
-
-    // Early return if there are no events for this connection.
-    if (count == 0) {
-        return status_t(NO_ERROR);
-    }
-
-    // NOTE: ASensorEvent and sensors_event_t are the same type
-    ssize_t size = SensorEventQueue::write(mChannel,
-            reinterpret_cast<ASensorEvent const*>(scratch), count);
-    if (size == -EAGAIN) {
-        // the destination doesn't accept events anymore, it's probably
-        // full. For now, we just drop the events on the floor.
-        // ALOGW("dropping %d events on the floor", count);
-        Mutex::Autolock _l(mConnectionLock);
-        countFlushCompleteEventsLocked(scratch, count);
-        return size;
-    }
+		sensors_event_t const* buffer, size_t numEvents,
+		sensors_event_t* scratch) {
+	/*ALOGD("%d\n", numEvents);
+	for (size_t i = 0; i < numEvents; i++) {
+		ALOGD(
+				"buffer%d\t%lld\t%8f\t%8f\t%8f\n", buffer[i].type, buffer[i].timestamp, buffer[i].data[0], buffer[i].data[1], buffer[i].data[2]);
+		ALOGD(
+				"scratch%d\t%lld\t%8f\t%8f\t%8f\n", scratch[i].type, scratch[i].timestamp, scratch[i].data[0], scratch[i].data[1], scratch[i].data[2]);
+		//ALOGD("HELLO?!");
+	}*/
+
+	// filter out events not for this connection
+	size_t count = 0;
+
+	if (scratch) {
+		Mutex::Autolock _l(mConnectionLock);
+		size_t i = 0;
+		while (i < numEvents) {
+			int32_t curr = buffer[i].sensor;
+			if (buffer[i].type == SENSOR_TYPE_META_DATA) {
+				ALOGD_IF(DEBUG_CONNECTIONS,
+						"flush complete event sensor==%d ", buffer[i].meta_data.sensor);
+				// Setting curr to the correct sensor to ensure the sensor events per connection are
+				// filtered correctly. buffer[i].sensor is zero for meta_data events.
+				curr = buffer[i].meta_data.sensor;
+			}
+			ssize_t index = mSensorInfo.indexOfKey(curr);
+			if (index >= 0&& mSensorInfo[index].mFirstFlushPending == true &&
+			buffer[i].type == SENSOR_TYPE_META_DATA) {
+			// This is the first flush before activate is called. Events can now be sent for
+			// this sensor on this connection.
+ALOGD_IF			(DEBUG_CONNECTIONS, "First flush event for sensor==%d ",
+					buffer[i].meta_data.sensor);
+			mSensorInfo.editValueAt(index).mFirstFlushPending = false;
+		}
+			if (index >= 0 && mSensorInfo[index].mFirstFlushPending == false) {
+				do {
+					scratch[count++] = buffer[i++];
+				} while ((i < numEvents)
+						&& ((buffer[i].sensor == curr)
+								|| (buffer[i].type == SENSOR_TYPE_META_DATA
+										&& buffer[i].meta_data.sensor == curr)));
+			} else {
+				i++;
+			}
+		}
+	} else {
+		scratch = const_cast<sensors_event_t *>(buffer);
+		count = numEvents;
+	}
+
+	// Send pending flush events (if any) before sending events from the cache.
+	{
+		ASensorEvent flushCompleteEvent;
+		flushCompleteEvent.type = SENSOR_TYPE_META_DATA;
+		flushCompleteEvent.sensor = 0;
+		Mutex::Autolock _l(mConnectionLock);
+		// Loop through all the sensors for this connection and check if there are any pending
+		// flush complete events to be sent.
+		for (size_t i = 0; i < mSensorInfo.size(); ++i) {
+			FlushInfo& flushInfo = mSensorInfo.editValueAt(i);
+			while (flushInfo.mPendingFlushEventsToSend > 0) {
+				flushCompleteEvent.meta_data.sensor = mSensorInfo.keyAt(i);
+				ssize_t size = SensorEventQueue::write(mChannel,
+						&flushCompleteEvent, 1);
+				if (size < 0) {
+					// ALOGW("dropping %d events on the floor", count);
+					countFlushCompleteEventsLocked(scratch, count);
+					return size;
+				}
+				ALOGD_IF(DEBUG_CONNECTIONS,
+						"sent dropped flush complete event==%d ", flushCompleteEvent.meta_data.sensor);
+				flushInfo.mPendingFlushEventsToSend--;
+			}
+		}
+	}
+
+	// Early return if there are no events for this connection.
+	if (count == 0) {
+		return status_t(NO_ERROR);
+	}
+
+	// NOTE: ASensorEvent and sensors_event_t are the same type
+	ssize_t size = SensorEventQueue::write(mChannel,
+			reinterpret_cast<ASensorEvent const*>(scratch), count);
+	if (size == -EAGAIN) {
+		// the destination doesn't accept events anymore, it's probably
+		// full. For now, we just drop the events on the floor.
+		// ALOGW("dropping %d events on the floor", count);
+		Mutex::Autolock _l(mConnectionLock);
+		countFlushCompleteEventsLocked(scratch, count);
+		return size;
+	}
 
-    return size < 0 ? status_t(size) : status_t(NO_ERROR);
+	return size < 0 ? status_t(size) : status_t(NO_ERROR);
 }
 
 void SensorService::SensorEventConnection::countFlushCompleteEventsLocked(
-                sensors_event_t* scratch, const int numEventsDropped) {
-    ALOGD_IF(DEBUG_CONNECTIONS, "dropping %d events ", numEventsDropped);
-    // Count flushComplete events in the events that are about to the dropped. These will be sent
-    // separately before the next batch of events.
-    for (int j = 0; j < numEventsDropped; ++j) {
-        if (scratch[j].type == SENSOR_TYPE_META_DATA) {
-            FlushInfo& flushInfo = mSensorInfo.editValueFor(scratch[j].meta_data.sensor);
-            flushInfo.mPendingFlushEventsToSend++;
-            ALOGD_IF(DEBUG_CONNECTIONS, "increment pendingFlushCount %d",
-                     flushInfo.mPendingFlushEventsToSend);
-        }
-    }
-    return;
-}
-
-sp<BitTube> SensorService::SensorEventConnection::getSensorChannel() const
-{
-    return mChannel;
-}
-
-status_t SensorService::SensorEventConnection::enableDisable(
-        int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
-        int reservedFlags)
-{
-    status_t err;
-    if (enabled) {
-        err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,
-                               reservedFlags);
-    } else {
-        err = mService->disable(this, handle);
-    }
-    return err;
-}
-
-status_t SensorService::SensorEventConnection::setEventRate(
-        int handle, nsecs_t samplingPeriodNs)
-{
-    return mService->setEventRate(this, handle, samplingPeriodNs);
-}
-
-status_t  SensorService::SensorEventConnection::flush() {
-    SensorDevice& dev(SensorDevice::getInstance());
-    const int halVersion = dev.getHalDeviceVersion();
-    Mutex::Autolock _l(mConnectionLock);
-    status_t err(NO_ERROR);
-    // Loop through all sensors for this connection and call flush on each of them.
-    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
-        const int handle = mSensorInfo.keyAt(i);
-        if (halVersion < SENSORS_DEVICE_API_VERSION_1_1 || mService->isVirtualSensor(handle)) {
-            // For older devices just increment pending flush count which will send a trivial
-            // flush complete event.
-            FlushInfo& flushInfo = mSensorInfo.editValueFor(handle);
-            flushInfo.mPendingFlushEventsToSend++;
-        } else {
-            status_t err_flush = mService->flushSensor(this, handle);
-            if (err_flush != NO_ERROR) {
-                ALOGE("Flush error handle=%d %s", handle, strerror(-err_flush));
-            }
-            err = (err_flush != NO_ERROR) ? err_flush : err;
-        }
-    }
-    return err;
+		sensors_event_t* scratch, const int numEventsDropped) {
+	ALOGD_IF(DEBUG_CONNECTIONS, "dropping %d events ", numEventsDropped);
+	// Count flushComplete events in the events that are about to the dropped. These will be sent
+	// separately before the next batch of events.
+	for (int j = 0; j < numEventsDropped; ++j) {
+		if (scratch[j].type == SENSOR_TYPE_META_DATA) {
+			FlushInfo& flushInfo = mSensorInfo.editValueFor(
+					scratch[j].meta_data.sensor);
+			flushInfo.mPendingFlushEventsToSend++;
+			ALOGD_IF(DEBUG_CONNECTIONS,
+					"increment pendingFlushCount %d", flushInfo.mPendingFlushEventsToSend);
+		}
+	}
+	return;
+}
+
+sp<BitTube> SensorService::SensorEventConnection::getSensorChannel() const {
+	return mChannel;
+}
+
+status_t SensorService::SensorEventConnection::enableDisable(int handle,
+		bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
+		int reservedFlags) {
+	status_t err;
+	if (enabled) {
+		err = mService->enable(this, handle, samplingPeriodNs,
+				maxBatchReportLatencyNs, reservedFlags);
+	} else {
+		err = mService->disable(this, handle);
+	}
+	return err;
+}
+
+status_t SensorService::SensorEventConnection::setEventRate(int handle,
+		nsecs_t samplingPeriodNs) {
+	return mService->setEventRate(this, handle, samplingPeriodNs);
+}
+
+status_t SensorService::SensorEventConnection::flush() {
+	SensorDevice& dev(SensorDevice::getInstance());
+	const int halVersion = dev.getHalDeviceVersion();
+	Mutex::Autolock _l(mConnectionLock);
+	status_t err(NO_ERROR);
+	// Loop through all sensors for this connection and call flush on each of them.
+	for (size_t i = 0; i < mSensorInfo.size(); ++i) {
+		const int handle = mSensorInfo.keyAt(i);
+		if (halVersion < SENSORS_DEVICE_API_VERSION_1_1
+				|| mService->isVirtualSensor(handle)) {
+			// For older devices just increment pending flush count which will send a trivial
+			// flush complete event.
+			FlushInfo& flushInfo = mSensorInfo.editValueFor(handle);
+			flushInfo.mPendingFlushEventsToSend++;
+		} else {
+			status_t err_flush = mService->flushSensor(this, handle);
+			if (err_flush != NO_ERROR) {
+				ALOGE("Flush error handle=%d %s", handle, strerror(-err_flush));
+			}
+			err = (err_flush != NO_ERROR) ? err_flush : err;
+		}
+	}
+	return err;
 }
 
 // ---------------------------------------------------------------------------
-}; // namespace android
+}
+;
+// namespace android
 
diff -urN Original_4.4.4_r1/frameworks/native/services/sensorservice/SensorService.h AndroidSource/frameworks/native/services/sensorservice/SensorService.h
--- Original_4.4.4_r1/frameworks/native/services/sensorservice/SensorService.h	2016-01-29 15:12:35.523488000 +0900
+++ AndroidSource/frameworks/native/services/sensorservice/SensorService.h	2016-06-23 20:07:05.000000000 +0900
@@ -142,6 +142,9 @@
     void cleanupAutoDisabledSensor(const sp<SensorEventConnection>& connection,
             sensors_event_t const* buffer, const int count);
 
+    // ADDED BY JAEHUN
+    //void sendTestEvent(sensors_event_t* buffer, size_t count);
+
     // constants
     Vector<Sensor> mSensorList;
     Vector<Sensor> mUserSensorListDebug;
@@ -151,6 +154,9 @@
     status_t mInitCheck;
     size_t mSocketBufferSize;
 
+    // ADDED BY JH
+    bool mServerOn;
+
     // protected by mLock
     mutable Mutex mLock;
     DefaultKeyedVector<int, SensorRecord*> mActiveSensors;
@@ -167,6 +173,10 @@
     status_t disable(const sp<SensorEventConnection>& connection, int handle);
     status_t setEventRate(const sp<SensorEventConnection>& connection, int handle, nsecs_t ns);
     status_t flushSensor(const sp<SensorEventConnection>& connection, int handle);
+
+    // ADDED FOR COLLABOROID
+    void sendRemoteEvent(int32_t type, int32_t sensor, float* data, int8_t status, int64_t timestamp, int32_t sourcedevice);
+    void setServerOn(bool flag);
 };
 
 // ---------------------------------------------------------------------------
diff -urN Original_4.4.4_r1/frameworks/opt/calendar/.git/HEAD AndroidSource/frameworks/opt/calendar/.git/HEAD
--- Original_4.4.4_r1/frameworks/opt/calendar/.git/HEAD	2016-01-29 15:12:35.739488000 +0900
+++ AndroidSource/frameworks/opt/calendar/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-03b18577f8f8f799e87a62b8e03889ddacf6daa2
Binary files Original_4.4.4_r1/frameworks/opt/calendar/.git/index and AndroidSource/frameworks/opt/calendar/.git/index differ
diff -urN Original_4.4.4_r1/frameworks/opt/carddav/.git/HEAD AndroidSource/frameworks/opt/carddav/.git/HEAD
--- Original_4.4.4_r1/frameworks/opt/carddav/.git/HEAD	2016-01-29 15:12:35.759488000 +0900
+++ AndroidSource/frameworks/opt/carddav/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-f08aa2df132dd8dc32a0013d3750137d9dd9280a
Binary files Original_4.4.4_r1/frameworks/opt/carddav/.git/index and AndroidSource/frameworks/opt/carddav/.git/index differ
diff -urN Original_4.4.4_r1/frameworks/opt/colorpicker/.git/HEAD AndroidSource/frameworks/opt/colorpicker/.git/HEAD
--- Original_4.4.4_r1/frameworks/opt/colorpicker/.git/HEAD	2016-01-29 15:12:35.783488000 +0900
+++ AndroidSource/frameworks/opt/colorpicker/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-bd624b68751a0bc3255e46e3a49c7032588b2385
Binary files Original_4.4.4_r1/frameworks/opt/colorpicker/.git/index and AndroidSource/frameworks/opt/colorpicker/.git/index differ
diff -urN Original_4.4.4_r1/frameworks/opt/datetimepicker/.git/HEAD AndroidSource/frameworks/opt/datetimepicker/.git/HEAD
--- Original_4.4.4_r1/frameworks/opt/datetimepicker/.git/HEAD	2016-01-29 15:12:35.807488000 +0900
+++ AndroidSource/frameworks/opt/datetimepicker/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-1100c53593ce64b58dc191d06e2aa1da9f6b84fb
Binary files Original_4.4.4_r1/frameworks/opt/datetimepicker/.git/index and AndroidSource/frameworks/opt/datetimepicker/.git/index differ
diff -urN Original_4.4.4_r1/frameworks/opt/emoji/.git/HEAD AndroidSource/frameworks/opt/emoji/.git/HEAD
--- Original_4.4.4_r1/frameworks/opt/emoji/.git/HEAD	2016-01-29 15:12:35.835488000 +0900
+++ AndroidSource/frameworks/opt/emoji/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-dbbe673145107e99883f62bafd70c5f43f11065c
Binary files Original_4.4.4_r1/frameworks/opt/emoji/.git/index and AndroidSource/frameworks/opt/emoji/.git/index differ
diff -urN Original_4.4.4_r1/frameworks/opt/inputmethodcommon/.git/HEAD AndroidSource/frameworks/opt/inputmethodcommon/.git/HEAD
--- Original_4.4.4_r1/frameworks/opt/inputmethodcommon/.git/HEAD	2016-01-29 15:12:35.859488000 +0900
+++ AndroidSource/frameworks/opt/inputmethodcommon/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-df9dd39c2047992a43b64e13bb0fc348a1630f3b
Binary files Original_4.4.4_r1/frameworks/opt/inputmethodcommon/.git/index and AndroidSource/frameworks/opt/inputmethodcommon/.git/index differ
diff -urN Original_4.4.4_r1/frameworks/opt/mailcommon/.git/HEAD AndroidSource/frameworks/opt/mailcommon/.git/HEAD
--- Original_4.4.4_r1/frameworks/opt/mailcommon/.git/HEAD	2016-01-29 15:12:35.879488000 +0900
+++ AndroidSource/frameworks/opt/mailcommon/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-15ecba0f8258e3c7d88defdad014c3f3a86d44e9
Binary files Original_4.4.4_r1/frameworks/opt/mailcommon/.git/index and AndroidSource/frameworks/opt/mailcommon/.git/index differ
diff -urN Original_4.4.4_r1/frameworks/opt/mms/.git/HEAD AndroidSource/frameworks/opt/mms/.git/HEAD
--- Original_4.4.4_r1/frameworks/opt/mms/.git/HEAD	2016-01-29 15:12:35.923488000 +0900
+++ AndroidSource/frameworks/opt/mms/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-ee25d0e52b2d7e6f6604e1e16c7d98c406ca9f41
Binary files Original_4.4.4_r1/frameworks/opt/mms/.git/index and AndroidSource/frameworks/opt/mms/.git/index differ
diff -urN Original_4.4.4_r1/frameworks/opt/net/voip/.git/HEAD AndroidSource/frameworks/opt/net/voip/.git/HEAD
--- Original_4.4.4_r1/frameworks/opt/net/voip/.git/HEAD	2016-01-29 15:12:35.947488000 +0900
+++ AndroidSource/frameworks/opt/net/voip/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-b51ed34abbb70994da221c545678d9dc5fe88141
Binary files Original_4.4.4_r1/frameworks/opt/net/voip/.git/index and AndroidSource/frameworks/opt/net/voip/.git/index differ
diff -urN Original_4.4.4_r1/frameworks/opt/photoviewer/.git/HEAD AndroidSource/frameworks/opt/photoviewer/.git/HEAD
--- Original_4.4.4_r1/frameworks/opt/photoviewer/.git/HEAD	2016-01-29 15:12:35.971488000 +0900
+++ AndroidSource/frameworks/opt/photoviewer/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-38a4f0ef3dbe5a350cf243281b9562c6a6bf8ee5
Binary files Original_4.4.4_r1/frameworks/opt/photoviewer/.git/index and AndroidSource/frameworks/opt/photoviewer/.git/index differ
diff -urN Original_4.4.4_r1/frameworks/opt/telephony/.git/HEAD AndroidSource/frameworks/opt/telephony/.git/HEAD
--- Original_4.4.4_r1/frameworks/opt/telephony/.git/HEAD	2016-01-29 15:12:36.035488000 +0900
+++ AndroidSource/frameworks/opt/telephony/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-c187f0e9bfb897405d6c41f669fc2aadacb0ee1e
Binary files Original_4.4.4_r1/frameworks/opt/telephony/.git/index and AndroidSource/frameworks/opt/telephony/.git/index differ
diff -urN Original_4.4.4_r1/frameworks/opt/timezonepicker/assets/backward AndroidSource/frameworks/opt/timezonepicker/assets/backward
--- Original_4.4.4_r1/frameworks/opt/timezonepicker/assets/backward	2016-01-29 15:12:25.611488000 +0900
+++ AndroidSource/frameworks/opt/timezonepicker/assets/backward	1970-01-01 09:00:00.000000000 +0900
@@ -1,117 +0,0 @@
-# <pre>
-# This file is in the public domain, so clarified as of
-# 2009-05-17 by Arthur David Olson.
-
-# This file provides links between current names for time zones
-# and their old names.  Many names changed in late 1993.
-
-Link	Africa/Asmara		Africa/Asmera
-Link	Africa/Bamako		Africa/Timbuktu
-Link	America/Argentina/Catamarca	America/Argentina/ComodRivadavia
-Link	America/Adak		America/Atka
-Link	America/Argentina/Buenos_Aires	America/Buenos_Aires
-Link	America/Argentina/Catamarca	America/Catamarca
-Link	America/Atikokan	America/Coral_Harbour
-Link	America/Argentina/Cordoba	America/Cordoba
-Link	America/Tijuana		America/Ensenada
-Link	America/Indiana/Indianapolis	America/Fort_Wayne
-Link	America/Indiana/Indianapolis	America/Indianapolis
-Link	America/Argentina/Jujuy	America/Jujuy
-Link	America/Indiana/Knox	America/Knox_IN
-Link	America/Kentucky/Louisville	America/Louisville
-Link	America/Argentina/Mendoza	America/Mendoza
-Link	America/Rio_Branco	America/Porto_Acre
-Link	America/Argentina/Cordoba	America/Rosario
-Link	America/St_Thomas	America/Virgin
-Link	Asia/Ashgabat		Asia/Ashkhabad
-Link	Asia/Chongqing		Asia/Chungking
-Link	Asia/Dhaka		Asia/Dacca
-Link	Asia/Kathmandu		Asia/Katmandu
-Link	Asia/Kolkata		Asia/Calcutta
-Link	Asia/Macau		Asia/Macao
-Link	Asia/Jerusalem		Asia/Tel_Aviv
-Link	Asia/Ho_Chi_Minh	Asia/Saigon
-Link	Asia/Thimphu		Asia/Thimbu
-Link	Asia/Makassar		Asia/Ujung_Pandang
-Link	Asia/Ulaanbaatar	Asia/Ulan_Bator
-Link	Atlantic/Faroe		Atlantic/Faeroe
-Link	Europe/Oslo		Atlantic/Jan_Mayen
-Link	Australia/Sydney	Australia/ACT
-Link	Australia/Sydney	Australia/Canberra
-Link	Australia/Lord_Howe	Australia/LHI
-Link	Australia/Sydney	Australia/NSW
-Link	Australia/Darwin	Australia/North
-Link	Australia/Brisbane	Australia/Queensland
-Link	Australia/Adelaide	Australia/South
-Link	Australia/Hobart	Australia/Tasmania
-Link	Australia/Melbourne	Australia/Victoria
-Link	Australia/Perth		Australia/West
-Link	Australia/Broken_Hill	Australia/Yancowinna
-Link	America/Rio_Branco	Brazil/Acre
-Link	America/Noronha		Brazil/DeNoronha
-Link	America/Sao_Paulo	Brazil/East
-Link	America/Manaus		Brazil/West
-Link	America/Halifax		Canada/Atlantic
-Link	America/Winnipeg	Canada/Central
-Link	America/Regina		Canada/East-Saskatchewan
-Link	America/Toronto		Canada/Eastern
-Link	America/Edmonton	Canada/Mountain
-Link	America/St_Johns	Canada/Newfoundland
-Link	America/Vancouver	Canada/Pacific
-Link	America/Regina		Canada/Saskatchewan
-Link	America/Whitehorse	Canada/Yukon
-Link	America/Santiago	Chile/Continental
-Link	Pacific/Easter		Chile/EasterIsland
-Link	America/Havana		Cuba
-Link	Africa/Cairo		Egypt
-Link	Europe/Dublin		Eire
-Link	Europe/London		Europe/Belfast
-Link	Europe/Chisinau		Europe/Tiraspol
-Link	Europe/London		GB
-Link	Europe/London		GB-Eire
-Link	Etc/GMT			GMT+0
-Link	Etc/GMT			GMT-0
-Link	Etc/GMT			GMT0
-Link	Etc/GMT			Greenwich
-Link	Asia/Hong_Kong		Hongkong
-Link	Atlantic/Reykjavik	Iceland
-Link	Asia/Tehran		Iran
-Link	Asia/Jerusalem		Israel
-Link	America/Jamaica		Jamaica
-Link	Asia/Tokyo		Japan
-Link	Pacific/Kwajalein	Kwajalein
-Link	Africa/Tripoli		Libya
-Link	America/Tijuana		Mexico/BajaNorte
-Link	America/Mazatlan	Mexico/BajaSur
-Link	America/Mexico_City	Mexico/General
-Link	Pacific/Auckland	NZ
-Link	Pacific/Chatham		NZ-CHAT
-Link	America/Denver		Navajo
-Link	Asia/Shanghai		PRC
-Link	Pacific/Pago_Pago	Pacific/Samoa
-Link	Pacific/Chuuk		Pacific/Yap
-Link	Pacific/Chuuk		Pacific/Truk
-Link	Pacific/Pohnpei		Pacific/Ponape
-Link	Europe/Warsaw		Poland
-Link	Europe/Lisbon		Portugal
-Link	Asia/Taipei		ROC
-Link	Asia/Seoul		ROK
-Link	Asia/Singapore		Singapore
-Link	Europe/Istanbul		Turkey
-Link	Etc/UCT			UCT
-Link	America/Anchorage	US/Alaska
-Link	America/Adak		US/Aleutian
-Link	America/Phoenix		US/Arizona
-Link	America/Chicago		US/Central
-Link	America/Indiana/Indianapolis	US/East-Indiana
-Link	America/New_York	US/Eastern
-Link	Pacific/Honolulu	US/Hawaii
-Link	America/Indiana/Knox	US/Indiana-Starke
-Link	America/Detroit		US/Michigan
-Link	America/Denver		US/Mountain
-Link	America/Los_Angeles	US/Pacific
-Link	Pacific/Pago_Pago	US/Samoa
-Link	Etc/UTC			UTC
-Link	Etc/UTC			Universal
-Link	Europe/Moscow		W-SU
-Link	Etc/UTC			Zulu
diff -urN Original_4.4.4_r1/frameworks/opt/timezonepicker/assets/zone.tab AndroidSource/frameworks/opt/timezonepicker/assets/zone.tab
--- Original_4.4.4_r1/frameworks/opt/timezonepicker/assets/zone.tab	2016-01-29 15:12:25.611488000 +0900
+++ AndroidSource/frameworks/opt/timezonepicker/assets/zone.tab	1970-01-01 09:00:00.000000000 +0900
@@ -1,444 +0,0 @@
-# <pre>
-# This file is in the public domain, so clarified as of
-# 2009-05-17 by Arthur David Olson.
-#
-# TZ zone descriptions
-#
-# From Paul Eggert (1996-08-05):
-#
-# This file contains a table with the following columns:
-# 1.  ISO 3166 2-character country code.  See the file `iso3166.tab'.
-# 2.  Latitude and longitude of the zone's principal location
-#     in ISO 6709 sign-degrees-minutes-seconds format,
-#     either +-DDMM+-DDDMM or +-DDMMSS+-DDDMMSS,
-#     first latitude (+ is north), then longitude (+ is east).
-# 3.  Zone name used in value of TZ environment variable.
-# 4.  Comments; present if and only if the country has multiple rows.
-#
-# Columns are separated by a single tab.
-# The table is sorted first by country, then an order within the country that
-# (1) makes some geographical sense, and
-# (2) puts the most populous zones first, where that does not contradict (1).
-#
-# Lines beginning with `#' are comments.
-#
-#country-
-#code	coordinates	TZ			comments
-AD	+4230+00131	Europe/Andorra
-AE	+2518+05518	Asia/Dubai
-AF	+3431+06912	Asia/Kabul
-AG	+1703-06148	America/Antigua
-AI	+1812-06304	America/Anguilla
-AL	+4120+01950	Europe/Tirane
-AM	+4011+04430	Asia/Yerevan
-AO	-0848+01314	Africa/Luanda
-AQ	-7750+16636	Antarctica/McMurdo	McMurdo Station, Ross Island
-AQ	-9000+00000	Antarctica/South_Pole	Amundsen-Scott Station, South Pole
-AQ	-6734-06808	Antarctica/Rothera	Rothera Station, Adelaide Island
-AQ	-6448-06406	Antarctica/Palmer	Palmer Station, Anvers Island
-AQ	-6736+06253	Antarctica/Mawson	Mawson Station, Holme Bay
-AQ	-6835+07758	Antarctica/Davis	Davis Station, Vestfold Hills
-AQ	-6617+11031	Antarctica/Casey	Casey Station, Bailey Peninsula
-AQ	-7824+10654	Antarctica/Vostok	Vostok Station, Lake Vostok
-AQ	-6640+14001	Antarctica/DumontDUrville	Dumont-d'Urville Station, Terre Adelie
-AQ	-690022+0393524	Antarctica/Syowa	Syowa Station, E Ongul I
-AR	-3436-05827	America/Argentina/Buenos_Aires	Buenos Aires (BA, CF)
-AR	-3124-06411	America/Argentina/Cordoba	most locations (CB, CC, CN, ER, FM, MN, SE, SF)
-AR	-2447-06525	America/Argentina/Salta	(SA, LP, NQ, RN)
-AR	-2411-06518	America/Argentina/Jujuy	Jujuy (JY)
-AR	-2649-06513	America/Argentina/Tucuman	Tucuman (TM)
-AR	-2828-06547	America/Argentina/Catamarca	Catamarca (CT), Chubut (CH)
-AR	-2926-06651	America/Argentina/La_Rioja	La Rioja (LR)
-AR	-3132-06831	America/Argentina/San_Juan	San Juan (SJ)
-AR	-3253-06849	America/Argentina/Mendoza	Mendoza (MZ)
-AR	-3319-06621	America/Argentina/San_Luis	San Luis (SL)
-AR	-5138-06913	America/Argentina/Rio_Gallegos	Santa Cruz (SC)
-AR	-5448-06818	America/Argentina/Ushuaia	Tierra del Fuego (TF)
-AS	-1416-17042	Pacific/Pago_Pago
-AT	+4813+01620	Europe/Vienna
-AU	-3352+15113	Australia/Sydney	New South Wales - most locations
-AU	-3455+13835	Australia/Adelaide	South Australia
-AU	-3133+15905	Australia/Lord_Howe	Lord Howe Island
-AU	-5430+15857	Antarctica/Macquarie	Macquarie Island
-AU	-4253+14719	Australia/Hobart	Tasmania - most locations
-AU	-3956+14352	Australia/Currie	Tasmania - King Island
-AU	-3749+14458	Australia/Melbourne	Victoria
-AU	-3157+14127	Australia/Broken_Hill	New South Wales - Yancowinna
-AU	-2728+15302	Australia/Brisbane	Queensland - most locations
-AU	-2016+14900	Australia/Lindeman	Queensland - Holiday Islands
-AU	-1228+13050	Australia/Darwin	Northern Territory
-AU	-3157+11551	Australia/Perth	Western Australia - most locations
-AU	-3143+12852	Australia/Eucla	Western Australia - Eucla area
-AW	+1230-06958	America/Aruba
-AX	+6006+01957	Europe/Mariehamn
-AZ	+4023+04951	Asia/Baku
-BA	+4352+01825	Europe/Sarajevo
-BB	+1306-05937	America/Barbados
-BD	+2343+09025	Asia/Dhaka
-BE	+5050+00420	Europe/Brussels
-BF	+1222-00131	Africa/Ouagadougou
-BG	+4241+02319	Europe/Sofia
-BH	+2623+05035	Asia/Bahrain
-BI	-0323+02922	Africa/Bujumbura
-BJ	+0629+00237	Africa/Porto-Novo
-BL	+1753-06251	America/St_Barthelemy
-BM	+3217-06446	Atlantic/Bermuda
-BN	+0456+11455	Asia/Brunei
-BO	-1630-06809	America/La_Paz
-BQ	+120903-0681636	America/Kralendijk
-BR	-0351-03225	America/Noronha	Atlantic islands
-BR	-0127-04829	America/Belem	Amapa, E Para
-BR	-0343-03830	America/Fortaleza	NE Brazil (MA, PI, CE, RN, PB)
-BR	-0803-03454	America/Recife	Pernambuco
-BR	-0712-04812	America/Araguaina	Tocantins
-BR	-0940-03543	America/Maceio	Alagoas, Sergipe
-BR	-1259-03831	America/Bahia	Bahia
-BR	-2332-04637	America/Sao_Paulo	S & SE Brazil (GO, DF, MG, ES, RJ, SP, PR, SC, RS)
-BR	-2027-05437	America/Campo_Grande	Mato Grosso do Sul
-BR	-1535-05605	America/Cuiaba	Mato Grosso
-BR	-0226-05452	America/Santarem	W Para
-BR	-0846-06354	America/Porto_Velho	Rondonia
-BR	+0249-06040	America/Boa_Vista	Roraima
-BR	-0308-06001	America/Manaus	E Amazonas
-BR	-0640-06952	America/Eirunepe	W Amazonas
-BR	-0958-06748	America/Rio_Branco	Acre
-BS	+2505-07721	America/Nassau
-BT	+2728+08939	Asia/Thimphu
-BW	-2439+02555	Africa/Gaborone
-BY	+5354+02734	Europe/Minsk
-BZ	+1730-08812	America/Belize
-CA	+4734-05243	America/St_Johns	Newfoundland Time, including SE Labrador
-CA	+4439-06336	America/Halifax	Atlantic Time - Nova Scotia (most places), PEI
-CA	+4612-05957	America/Glace_Bay	Atlantic Time - Nova Scotia - places that did not observe DST 1966-1971
-CA	+4606-06447	America/Moncton	Atlantic Time - New Brunswick
-CA	+5320-06025	America/Goose_Bay	Atlantic Time - Labrador - most locations
-CA	+5125-05707	America/Blanc-Sablon	Atlantic Standard Time - Quebec - Lower North Shore
-CA	+4531-07334	America/Montreal	Eastern Time - Quebec - most locations
-CA	+4339-07923	America/Toronto	Eastern Time - Ontario - most locations
-CA	+4901-08816	America/Nipigon	Eastern Time - Ontario & Quebec - places that did not observe DST 1967-1973
-CA	+4823-08915	America/Thunder_Bay	Eastern Time - Thunder Bay, Ontario
-CA	+6344-06828	America/Iqaluit	Eastern Time - east Nunavut - most locations
-CA	+6608-06544	America/Pangnirtung	Eastern Time - Pangnirtung, Nunavut
-CA	+744144-0944945	America/Resolute	Central Standard Time - Resolute, Nunavut
-CA	+484531-0913718	America/Atikokan	Eastern Standard Time - Atikokan, Ontario and Southampton I, Nunavut
-CA	+624900-0920459	America/Rankin_Inlet	Central Time - central Nunavut
-CA	+4953-09709	America/Winnipeg	Central Time - Manitoba & west Ontario
-CA	+4843-09434	America/Rainy_River	Central Time - Rainy River & Fort Frances, Ontario
-CA	+5024-10439	America/Regina	Central Standard Time - Saskatchewan - most locations
-CA	+5017-10750	America/Swift_Current	Central Standard Time - Saskatchewan - midwest
-CA	+5333-11328	America/Edmonton	Mountain Time - Alberta, east British Columbia & west Saskatchewan
-CA	+690650-1050310	America/Cambridge_Bay	Mountain Time - west Nunavut
-CA	+6227-11421	America/Yellowknife	Mountain Time - central Northwest Territories
-CA	+682059-1334300	America/Inuvik	Mountain Time - west Northwest Territories
-CA	+5946-12014	America/Dawson_Creek	Mountain Standard Time - Dawson Creek & Fort Saint John, British Columbia
-CA	+4906-11631	America/Creston	Mountain Standard Time - Creston, British Columbia
-CA	+4916-12307	America/Vancouver	Pacific Time - west British Columbia
-CA	+6043-13503	America/Whitehorse	Pacific Time - south Yukon
-CA	+6404-13925	America/Dawson	Pacific Time - north Yukon
-CC	-1210+09655	Indian/Cocos
-CD	-0418+01518	Africa/Kinshasa	west Dem. Rep. of Congo
-CD	-1140+02728	Africa/Lubumbashi	east Dem. Rep. of Congo
-CF	+0422+01835	Africa/Bangui
-CG	-0416+01517	Africa/Brazzaville
-CH	+4723+00832	Europe/Zurich
-CI	+0519-00402	Africa/Abidjan
-CK	-2114-15946	Pacific/Rarotonga
-CL	-3327-07040	America/Santiago	most locations
-CL	-2709-10926	Pacific/Easter	Easter Island & Sala y Gomez
-CM	+0403+00942	Africa/Douala
-CN	+3114+12128	Asia/Shanghai	east China - Beijing, Guangdong, Shanghai, etc.
-CN	+4545+12641	Asia/Harbin	Heilongjiang (except Mohe), Jilin
-CN	+2934+10635	Asia/Chongqing	central China - Sichuan, Yunnan, Guangxi, Shaanxi, Guizhou, etc.
-CN	+4348+08735	Asia/Urumqi	most of Tibet & Xinjiang
-CN	+3929+07559	Asia/Kashgar	west Tibet & Xinjiang
-CO	+0436-07405	America/Bogota
-CR	+0956-08405	America/Costa_Rica
-CU	+2308-08222	America/Havana
-CV	+1455-02331	Atlantic/Cape_Verde
-CW	+1211-06900	America/Curacao
-CX	-1025+10543	Indian/Christmas
-CY	+3510+03322	Asia/Nicosia
-CZ	+5005+01426	Europe/Prague
-DE	+5230+01322	Europe/Berlin	most locations
-DE	+4742+00841	Europe/Busingen	Busingen
-DJ	+1136+04309	Africa/Djibouti
-DK	+5540+01235	Europe/Copenhagen
-DM	+1518-06124	America/Dominica
-DO	+1828-06954	America/Santo_Domingo
-DZ	+3647+00303	Africa/Algiers
-EC	-0210-07950	America/Guayaquil	mainland
-EC	-0054-08936	Pacific/Galapagos	Galapagos Islands
-EE	+5925+02445	Europe/Tallinn
-EG	+3003+03115	Africa/Cairo
-EH	+2709-01312	Africa/El_Aaiun
-ER	+1520+03853	Africa/Asmara
-ES	+4024-00341	Europe/Madrid	mainland
-ES	+3553-00519	Africa/Ceuta	Ceuta & Melilla
-ES	+2806-01524	Atlantic/Canary	Canary Islands
-ET	+0902+03842	Africa/Addis_Ababa
-FI	+6010+02458	Europe/Helsinki
-FJ	-1808+17825	Pacific/Fiji
-FK	-5142-05751	Atlantic/Stanley
-FM	+0725+15147	Pacific/Chuuk	Chuuk (Truk) and Yap
-FM	+0658+15813	Pacific/Pohnpei	Pohnpei (Ponape)
-FM	+0519+16259	Pacific/Kosrae	Kosrae
-FO	+6201-00646	Atlantic/Faroe
-FR	+4852+00220	Europe/Paris
-GA	+0023+00927	Africa/Libreville
-GB	+513030-0000731	Europe/London
-GD	+1203-06145	America/Grenada
-GE	+4143+04449	Asia/Tbilisi
-GF	+0456-05220	America/Cayenne
-GG	+4927-00232	Europe/Guernsey
-GH	+0533-00013	Africa/Accra
-GI	+3608-00521	Europe/Gibraltar
-GL	+6411-05144	America/Godthab	most locations
-GL	+7646-01840	America/Danmarkshavn	east coast, north of Scoresbysund
-GL	+7029-02158	America/Scoresbysund	Scoresbysund / Ittoqqortoormiit
-GL	+7634-06847	America/Thule	Thule / Pituffik
-GM	+1328-01639	Africa/Banjul
-GN	+0931-01343	Africa/Conakry
-GP	+1614-06132	America/Guadeloupe
-GQ	+0345+00847	Africa/Malabo
-GR	+3758+02343	Europe/Athens
-GS	-5416-03632	Atlantic/South_Georgia
-GT	+1438-09031	America/Guatemala
-GU	+1328+14445	Pacific/Guam
-GW	+1151-01535	Africa/Bissau
-GY	+0648-05810	America/Guyana
-HK	+2217+11409	Asia/Hong_Kong
-HN	+1406-08713	America/Tegucigalpa
-HR	+4548+01558	Europe/Zagreb
-HT	+1832-07220	America/Port-au-Prince
-HU	+4730+01905	Europe/Budapest
-ID	-0610+10648	Asia/Jakarta	Java & Sumatra
-ID	-0002+10920	Asia/Pontianak	west & central Borneo
-ID	-0507+11924	Asia/Makassar	east & south Borneo, Sulawesi (Celebes), Bali, Nusa Tengarra, west Timor
-ID	-0232+14042	Asia/Jayapura	west New Guinea (Irian Jaya) & Malukus (Moluccas)
-IE	+5320-00615	Europe/Dublin
-IL	+3146+03514	Asia/Jerusalem
-IM	+5409-00428	Europe/Isle_of_Man
-IN	+2232+08822	Asia/Kolkata
-IO	-0720+07225	Indian/Chagos
-IQ	+3321+04425	Asia/Baghdad
-IR	+3540+05126	Asia/Tehran
-IS	+6409-02151	Atlantic/Reykjavik
-IT	+4154+01229	Europe/Rome
-JE	+4912-00207	Europe/Jersey
-JM	+1800-07648	America/Jamaica
-JO	+3157+03556	Asia/Amman
-JP	+353916+1394441	Asia/Tokyo
-KE	-0117+03649	Africa/Nairobi
-KG	+4254+07436	Asia/Bishkek
-KH	+1133+10455	Asia/Phnom_Penh
-KI	+0125+17300	Pacific/Tarawa	Gilbert Islands
-KI	-0308-17105	Pacific/Enderbury	Phoenix Islands
-KI	+0152-15720	Pacific/Kiritimati	Line Islands
-KM	-1141+04316	Indian/Comoro
-KN	+1718-06243	America/St_Kitts
-KP	+3901+12545	Asia/Pyongyang
-KR	+3733+12658	Asia/Seoul
-KW	+2920+04759	Asia/Kuwait
-KY	+1918-08123	America/Cayman
-KZ	+4315+07657	Asia/Almaty	most locations
-KZ	+4448+06528	Asia/Qyzylorda	Qyzylorda (Kyzylorda, Kzyl-Orda)
-KZ	+5017+05710	Asia/Aqtobe	Aqtobe (Aktobe)
-KZ	+4431+05016	Asia/Aqtau	Atyrau (Atirau, Gur'yev), Mangghystau (Mankistau)
-KZ	+5113+05121	Asia/Oral	West Kazakhstan
-LA	+1758+10236	Asia/Vientiane
-LB	+3353+03530	Asia/Beirut
-LC	+1401-06100	America/St_Lucia
-LI	+4709+00931	Europe/Vaduz
-LK	+0656+07951	Asia/Colombo
-LR	+0618-01047	Africa/Monrovia
-LS	-2928+02730	Africa/Maseru
-LT	+5441+02519	Europe/Vilnius
-LU	+4936+00609	Europe/Luxembourg
-LV	+5657+02406	Europe/Riga
-LY	+3254+01311	Africa/Tripoli
-MA	+3339-00735	Africa/Casablanca
-MC	+4342+00723	Europe/Monaco
-MD	+4700+02850	Europe/Chisinau
-ME	+4226+01916	Europe/Podgorica
-MF	+1804-06305	America/Marigot
-MG	-1855+04731	Indian/Antananarivo
-MH	+0709+17112	Pacific/Majuro	most locations
-MH	+0905+16720	Pacific/Kwajalein	Kwajalein
-MK	+4159+02126	Europe/Skopje
-ML	+1239-00800	Africa/Bamako
-MM	+1647+09610	Asia/Rangoon
-MN	+4755+10653	Asia/Ulaanbaatar	most locations
-MN	+4801+09139	Asia/Hovd	Bayan-Olgiy, Govi-Altai, Hovd, Uvs, Zavkhan
-MN	+4804+11430	Asia/Choibalsan	Dornod, Sukhbaatar
-MO	+2214+11335	Asia/Macau
-MP	+1512+14545	Pacific/Saipan
-MQ	+1436-06105	America/Martinique
-MR	+1806-01557	Africa/Nouakchott
-MS	+1643-06213	America/Montserrat
-MT	+3554+01431	Europe/Malta
-MU	-2010+05730	Indian/Mauritius
-MV	+0410+07330	Indian/Maldives
-MW	-1547+03500	Africa/Blantyre
-MX	+1924-09909	America/Mexico_City	Central Time - most locations
-MX	+2105-08646	America/Cancun	Central Time - Quintana Roo
-MX	+2058-08937	America/Merida	Central Time - Campeche, Yucatan
-MX	+2540-10019	America/Monterrey	Mexican Central Time - Coahuila, Durango, Nuevo Leon, Tamaulipas away from US border
-MX	+2550-09730	America/Matamoros	US Central Time - Coahuila, Durango, Nuevo Leon, Tamaulipas near US border
-MX	+2313-10625	America/Mazatlan	Mountain Time - S Baja, Nayarit, Sinaloa
-MX	+2838-10605	America/Chihuahua	Mexican Mountain Time - Chihuahua away from US border
-MX	+2934-10425	America/Ojinaga	US Mountain Time - Chihuahua near US border
-MX	+2904-11058	America/Hermosillo	Mountain Standard Time - Sonora
-MX	+3232-11701	America/Tijuana	US Pacific Time - Baja California near US border
-MX	+3018-11452	America/Santa_Isabel	Mexican Pacific Time - Baja California away from US border
-MX	+2048-10515	America/Bahia_Banderas	Mexican Central Time - Bahia de Banderas
-MY	+0310+10142	Asia/Kuala_Lumpur	peninsular Malaysia
-MY	+0133+11020	Asia/Kuching	Sabah & Sarawak
-MZ	-2558+03235	Africa/Maputo
-NA	-2234+01706	Africa/Windhoek
-NC	-2216+16627	Pacific/Noumea
-NE	+1331+00207	Africa/Niamey
-NF	-2903+16758	Pacific/Norfolk
-NG	+0627+00324	Africa/Lagos
-NI	+1209-08617	America/Managua
-NL	+5222+00454	Europe/Amsterdam
-NO	+5955+01045	Europe/Oslo
-NP	+2743+08519	Asia/Kathmandu
-NR	-0031+16655	Pacific/Nauru
-NU	-1901-16955	Pacific/Niue
-NZ	-3652+17446	Pacific/Auckland	most locations
-NZ	-4357-17633	Pacific/Chatham	Chatham Islands
-OM	+2336+05835	Asia/Muscat
-PA	+0858-07932	America/Panama
-PE	-1203-07703	America/Lima
-PF	-1732-14934	Pacific/Tahiti	Society Islands
-PF	-0900-13930	Pacific/Marquesas	Marquesas Islands
-PF	-2308-13457	Pacific/Gambier	Gambier Islands
-PG	-0930+14710	Pacific/Port_Moresby
-PH	+1435+12100	Asia/Manila
-PK	+2452+06703	Asia/Karachi
-PL	+5215+02100	Europe/Warsaw
-PM	+4703-05620	America/Miquelon
-PN	-2504-13005	Pacific/Pitcairn
-PR	+182806-0660622	America/Puerto_Rico
-PS	+3130+03428	Asia/Gaza	Gaza Strip
-PS	+313200+0350542	Asia/Hebron	West Bank
-PT	+3843-00908	Europe/Lisbon	mainland
-PT	+3238-01654	Atlantic/Madeira	Madeira Islands
-PT	+3744-02540	Atlantic/Azores	Azores
-PW	+0720+13429	Pacific/Palau
-PY	-2516-05740	America/Asuncion
-QA	+2517+05132	Asia/Qatar
-RE	-2052+05528	Indian/Reunion
-RO	+4426+02606	Europe/Bucharest
-RS	+4450+02030	Europe/Belgrade
-RU	+5443+02030	Europe/Kaliningrad	Moscow-01 - Kaliningrad
-RU	+5545+03735	Europe/Moscow	Moscow+00 - west Russia
-RU	+4844+04425	Europe/Volgograd	Moscow+00 - Caspian Sea
-RU	+5312+05009	Europe/Samara	Moscow+00 - Samara, Udmurtia
-RU	+5651+06036	Asia/Yekaterinburg	Moscow+02 - Urals
-RU	+5500+07324	Asia/Omsk	Moscow+03 - west Siberia
-RU	+5502+08255	Asia/Novosibirsk	Moscow+03 - Novosibirsk
-RU	+5345+08707	Asia/Novokuznetsk	Moscow+03 - Novokuznetsk
-RU	+5601+09250	Asia/Krasnoyarsk	Moscow+04 - Yenisei River
-RU	+5216+10420	Asia/Irkutsk	Moscow+05 - Lake Baikal
-RU	+6200+12940	Asia/Yakutsk	Moscow+06 - Lena River
-RU	+623923+1353314	Asia/Khandyga	Moscow+06 - Tomponsky, Ust-Maysky
-RU	+4310+13156	Asia/Vladivostok	Moscow+07 - Amur River
-RU	+4658+14242	Asia/Sakhalin	Moscow+07 - Sakhalin Island
-RU	+643337+1431336	Asia/Ust-Nera	Moscow+07 - Oymyakonsky
-RU	+5934+15048	Asia/Magadan	Moscow+08 - Magadan
-RU	+5301+15839	Asia/Kamchatka	Moscow+08 - Kamchatka
-RU	+6445+17729	Asia/Anadyr	Moscow+08 - Bering Sea
-RW	-0157+03004	Africa/Kigali
-SA	+2438+04643	Asia/Riyadh
-SB	-0932+16012	Pacific/Guadalcanal
-SC	-0440+05528	Indian/Mahe
-SD	+1536+03232	Africa/Khartoum
-SE	+5920+01803	Europe/Stockholm
-SG	+0117+10351	Asia/Singapore
-SH	-1555-00542	Atlantic/St_Helena
-SI	+4603+01431	Europe/Ljubljana
-SJ	+7800+01600	Arctic/Longyearbyen
-SK	+4809+01707	Europe/Bratislava
-SL	+0830-01315	Africa/Freetown
-SM	+4355+01228	Europe/San_Marino
-SN	+1440-01726	Africa/Dakar
-SO	+0204+04522	Africa/Mogadishu
-SR	+0550-05510	America/Paramaribo
-SS	+0451+03136	Africa/Juba
-ST	+0020+00644	Africa/Sao_Tome
-SV	+1342-08912	America/El_Salvador
-SX	+180305-0630250	America/Lower_Princes
-SY	+3330+03618	Asia/Damascus
-SZ	-2618+03106	Africa/Mbabane
-TC	+2128-07108	America/Grand_Turk
-TD	+1207+01503	Africa/Ndjamena
-TF	-492110+0701303	Indian/Kerguelen
-TG	+0608+00113	Africa/Lome
-TH	+1345+10031	Asia/Bangkok
-TJ	+3835+06848	Asia/Dushanbe
-TK	-0922-17114	Pacific/Fakaofo
-TL	-0833+12535	Asia/Dili
-TM	+3757+05823	Asia/Ashgabat
-TN	+3648+01011	Africa/Tunis
-TO	-2110-17510	Pacific/Tongatapu
-TR	+4101+02858	Europe/Istanbul
-TT	+1039-06131	America/Port_of_Spain
-TV	-0831+17913	Pacific/Funafuti
-TW	+2503+12130	Asia/Taipei
-TZ	-0648+03917	Africa/Dar_es_Salaam
-UA	+5026+03031	Europe/Kiev	most locations
-UA	+4837+02218	Europe/Uzhgorod	Ruthenia
-UA	+4750+03510	Europe/Zaporozhye	Zaporozh'ye, E Lugansk / Zaporizhia, E Luhansk
-UA	+4457+03406	Europe/Simferopol	central Crimea
-UG	+0019+03225	Africa/Kampala
-UM	+1645-16931	Pacific/Johnston	Johnston Atoll
-UM	+2813-17722	Pacific/Midway	Midway Islands
-UM	+1917+16637	Pacific/Wake	Wake Island
-US	+404251-0740023	America/New_York	Eastern Time
-US	+421953-0830245	America/Detroit	Eastern Time - Michigan - most locations
-US	+381515-0854534	America/Kentucky/Louisville	Eastern Time - Kentucky - Louisville area
-US	+364947-0845057	America/Kentucky/Monticello	Eastern Time - Kentucky - Wayne County
-US	+394606-0860929	America/Indiana/Indianapolis	Eastern Time - Indiana - most locations
-US	+384038-0873143	America/Indiana/Vincennes	Eastern Time - Indiana - Daviess, Dubois, Knox & Martin Counties
-US	+410305-0863611	America/Indiana/Winamac	Eastern Time - Indiana - Pulaski County
-US	+382232-0862041	America/Indiana/Marengo	Eastern Time - Indiana - Crawford County
-US	+382931-0871643	America/Indiana/Petersburg	Eastern Time - Indiana - Pike County
-US	+384452-0850402	America/Indiana/Vevay	Eastern Time - Indiana - Switzerland County
-US	+415100-0873900	America/Chicago	Central Time
-US	+375711-0864541	America/Indiana/Tell_City	Central Time - Indiana - Perry County
-US	+411745-0863730	America/Indiana/Knox	Central Time - Indiana - Starke County
-US	+450628-0873651	America/Menominee	Central Time - Michigan - Dickinson, Gogebic, Iron & Menominee Counties
-US	+470659-1011757	America/North_Dakota/Center	Central Time - North Dakota - Oliver County
-US	+465042-1012439	America/North_Dakota/New_Salem	Central Time - North Dakota - Morton County (except Mandan area)
-US	+471551-1014640	America/North_Dakota/Beulah	Central Time - North Dakota - Mercer County
-US	+394421-1045903	America/Denver	Mountain Time
-US	+433649-1161209	America/Boise	Mountain Time - south Idaho & east Oregon
-US	+364708-1084111	America/Shiprock	Mountain Time - Navajo
-US	+332654-1120424	America/Phoenix	Mountain Standard Time - Arizona
-US	+340308-1181434	America/Los_Angeles	Pacific Time
-US	+611305-1495401	America/Anchorage	Alaska Time
-US	+581807-1342511	America/Juneau	Alaska Time - Alaska panhandle
-US	+571035-1351807	America/Sitka	Alaska Time - southeast Alaska panhandle
-US	+593249-1394338	America/Yakutat	Alaska Time - Alaska panhandle neck
-US	+643004-1652423	America/Nome	Alaska Time - west Alaska
-US	+515248-1763929	America/Adak	Aleutian Islands
-US	+550737-1313435	America/Metlakatla	Metlakatla Time - Annette Island
-US	+211825-1575130	Pacific/Honolulu	Hawaii
-UY	-3453-05611	America/Montevideo
-UZ	+3940+06648	Asia/Samarkand	west Uzbekistan
-UZ	+4120+06918	Asia/Tashkent	east Uzbekistan
-VA	+415408+0122711	Europe/Vatican
-VC	+1309-06114	America/St_Vincent
-VE	+1030-06656	America/Caracas
-VG	+1827-06437	America/Tortola
-VI	+1821-06456	America/St_Thomas
-VN	+1045+10640	Asia/Ho_Chi_Minh
-VU	-1740+16825	Pacific/Efate
-WF	-1318-17610	Pacific/Wallis
-WS	-1350-17144	Pacific/Apia
-YE	+1245+04512	Asia/Aden
-YT	-1247+04514	Indian/Mayotte
-ZA	-2615+02800	Africa/Johannesburg
-ZM	-1525+02817	Africa/Lusaka
-ZW	-1750+03103	Africa/Harare
diff -urN Original_4.4.4_r1/frameworks/opt/timezonepicker/.git/HEAD AndroidSource/frameworks/opt/timezonepicker/.git/HEAD
--- Original_4.4.4_r1/frameworks/opt/timezonepicker/.git/HEAD	2016-01-29 15:12:36.127488000 +0900
+++ AndroidSource/frameworks/opt/timezonepicker/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-8aedf9412532499dddcd965050bb5ac654d83834
Binary files Original_4.4.4_r1/frameworks/opt/timezonepicker/.git/index and AndroidSource/frameworks/opt/timezonepicker/.git/index differ
diff -urN Original_4.4.4_r1/frameworks/opt/vcard/.git/HEAD AndroidSource/frameworks/opt/vcard/.git/HEAD
--- Original_4.4.4_r1/frameworks/opt/vcard/.git/HEAD	2016-01-29 15:12:36.159488000 +0900
+++ AndroidSource/frameworks/opt/vcard/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-5f55ee296e26d5278fd0d91657edddc92766459e
Binary files Original_4.4.4_r1/frameworks/opt/vcard/.git/index and AndroidSource/frameworks/opt/vcard/.git/index differ
diff -urN Original_4.4.4_r1/frameworks/opt/widget/.git/HEAD AndroidSource/frameworks/opt/widget/.git/HEAD
--- Original_4.4.4_r1/frameworks/opt/widget/.git/HEAD	2016-01-29 15:12:36.187488000 +0900
+++ AndroidSource/frameworks/opt/widget/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-466e0e0307b3f6aa4f4be3d9419b5996bd389da5
Binary files Original_4.4.4_r1/frameworks/opt/widget/.git/index and AndroidSource/frameworks/opt/widget/.git/index differ
diff -urN Original_4.4.4_r1/frameworks/rs/.git/HEAD AndroidSource/frameworks/rs/.git/HEAD
--- Original_4.4.4_r1/frameworks/rs/.git/HEAD	2016-01-29 15:12:36.211488000 +0900
+++ AndroidSource/frameworks/rs/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-7d2a6e85c570e574457d1862c9e16025094d09e7
Binary files Original_4.4.4_r1/frameworks/rs/.git/index and AndroidSource/frameworks/rs/.git/index differ
diff -urN Original_4.4.4_r1/frameworks/support/.git/HEAD AndroidSource/frameworks/support/.git/HEAD
--- Original_4.4.4_r1/frameworks/support/.git/HEAD	2016-01-29 15:12:36.347488000 +0900
+++ AndroidSource/frameworks/support/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-197708fc4fc0a6a5ede2da2479613382b561f028
Binary files Original_4.4.4_r1/frameworks/support/.git/index and AndroidSource/frameworks/support/.git/index differ
diff -urN Original_4.4.4_r1/frameworks/testing/.git/HEAD AndroidSource/frameworks/testing/.git/HEAD
--- Original_4.4.4_r1/frameworks/testing/.git/HEAD	2016-01-29 15:12:36.427488000 +0900
+++ AndroidSource/frameworks/testing/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-abc9b55fa34639dd39c58a03c6c21d265ec84a23
Binary files Original_4.4.4_r1/frameworks/testing/.git/index and AndroidSource/frameworks/testing/.git/index differ
diff -urN Original_4.4.4_r1/frameworks/volley/.git/HEAD AndroidSource/frameworks/volley/.git/HEAD
--- Original_4.4.4_r1/frameworks/volley/.git/HEAD	2016-01-29 15:12:36.475488000 +0900
+++ AndroidSource/frameworks/volley/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-bd04632e0c5b4a29889c1b70089ac2322229b5e6
Binary files Original_4.4.4_r1/frameworks/volley/.git/index and AndroidSource/frameworks/volley/.git/index differ
diff -urN Original_4.4.4_r1/frameworks/webview/.git/HEAD AndroidSource/frameworks/webview/.git/HEAD
--- Original_4.4.4_r1/frameworks/webview/.git/HEAD	2016-01-29 15:12:36.519488000 +0900
+++ AndroidSource/frameworks/webview/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-7a7dce808e1545e859b80b86f0279ee68ce3f0cc
Binary files Original_4.4.4_r1/frameworks/webview/.git/index and AndroidSource/frameworks/webview/.git/index differ
diff -urN Original_4.4.4_r1/frameworks/wilhelm/.git/HEAD AndroidSource/frameworks/wilhelm/.git/HEAD
--- Original_4.4.4_r1/frameworks/wilhelm/.git/HEAD	2016-01-29 15:12:36.575488000 +0900
+++ AndroidSource/frameworks/wilhelm/.git/HEAD	1970-01-01 09:00:00.000000000 +0900
@@ -1 +0,0 @@
-f0c3b4edf597c40aae4ea311575f39c8bcf203df
Binary files Original_4.4.4_r1/frameworks/wilhelm/.git/index and AndroidSource/frameworks/wilhelm/.git/index differ
diff -urN Original_4.4.4_r1/frameworks/wilhelm/tests/sandbox/playbq.cpp AndroidSource/frameworks/wilhelm/tests/sandbox/playbq.cpp
--- Original_4.4.4_r1/frameworks/wilhelm/tests/sandbox/playbq.cpp	2016-01-29 15:12:36.639488000 +0900
+++ AndroidSource/frameworks/wilhelm/tests/sandbox/playbq.cpp	1970-01-01 09:00:00.000000000 +0900
@@ -1,548 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-// Play an audio file using buffer queue
-
-#include <assert.h>
-#include <math.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <SLES/OpenSLES.h>
-#ifdef ANDROID
-#include <audio_utils/sndfile.h>
-#else
-#include <sndfile.h>
-#endif
-
-#include <media/nbaio/MonoPipe.h>
-#include <media/nbaio/MonoPipeReader.h>
-
-#define max(a, b) ((a) > (b) ? (a) : (b))
-#define min(a, b) ((a) < (b) ? (a) : (b))
-
-unsigned numBuffers = 2;
-int framesPerBuffer = 512;
-SNDFILE *sndfile;
-SF_INFO sfinfo;
-unsigned which; // which buffer to use next
-SLboolean eof;  // whether we have hit EOF on input yet
-short *buffers;
-SLuint32 byteOrder; // desired to use for PCM buffers
-SLuint32 nativeByteOrder;   // of platform
-SLuint32 bitsPerSample = 16;
-
-// swap adjacent bytes; this would normally be in <unistd.h> but is missing here
-static void swab(const void *from, void *to, ssize_t n)
-{
-    // from and to as char pointers
-    const char *from_ch = (const char *) from;
-    char *to_ch = (char *) to;
-    // note that we don't swap the last odd byte
-    while (n >= 2) {
-        to_ch[0] = from_ch[1];
-        to_ch[1] = from_ch[0];
-        to_ch += 2;
-        from_ch += 2;
-        n -= 2;
-    }
-}
-
-// squeeze 16-bit signed PCM samples down to 8-bit unsigned PCM samples by truncation; no dithering
-static void squeeze(const short *from, unsigned char *to, ssize_t n)
-{
-    // note that we don't squeeze the last odd byte
-    while (n >= 2) {
-        *to++ = (*from++ + 32768) >> 8;
-        n -= 2;
-    }
-}
-
-static android::MonoPipeReader *pipeReader;
-static android::MonoPipe *pipeWriter;
-static unsigned underruns = 0;
-
-// This callback is called each time a buffer finishes playing
-
-static void callback(SLBufferQueueItf bufq, void *param)
-{
-    assert(NULL == param);
-    if (!eof) {
-        short *buffer = &buffers[framesPerBuffer * sfinfo.channels * which];
-        ssize_t count = pipeReader->read(buffer, framesPerBuffer, (int64_t) -1);
-        // on underrun from pipe, substitute silence
-        if (0 >= count) {
-            memset(buffer, 0, framesPerBuffer * sfinfo.channels * sizeof(short));
-            count = framesPerBuffer;
-            ++underruns;
-        }
-        if (count > 0) {
-            SLuint32 nbytes = count * sfinfo.channels * sizeof(short);
-            if (byteOrder != nativeByteOrder) {
-                swab(buffer, buffer, nbytes);
-            }
-            if (bitsPerSample == 8) {
-                squeeze(buffer, (unsigned char *) buffer, nbytes);
-                nbytes /= 2;
-            }
-            SLresult result = (*bufq)->Enqueue(bufq, buffer, nbytes);
-            assert(SL_RESULT_SUCCESS == result);
-            if (++which >= numBuffers)
-                which = 0;
-        }
-    }
-}
-
-// This thread reads from a (slow) filesystem with unpredictable latency and writes to pipe
-
-static void *file_reader_loop(void *arg)
-{
-#define READ_FRAMES 256
-    short *temp = (short *) malloc(READ_FRAMES * sfinfo.channels * sizeof(short));
-    sf_count_t total = 0;
-    for (;;) {
-        sf_count_t count = sf_readf_short(sndfile, temp, (sf_count_t) READ_FRAMES);
-        if (0 >= count) {
-            eof = SL_BOOLEAN_TRUE;
-            break;
-        }
-        const short *ptr = temp;
-        while (count > 0) {
-            ssize_t actual = pipeWriter->write(ptr, (size_t) count);
-            if (actual < 0) {
-                break;
-            }
-            if ((sf_count_t) actual < count) {
-                usleep(10000);
-            }
-            ptr += actual * sfinfo.channels;
-            count -= actual;
-            total += actual;
-        }
-        // simulate occasional filesystem latency
-        if ((total & 0xFF00) == 0xFF00) {
-            usleep(100000);
-        }
-    }
-    free(temp);
-    return NULL;
-}
-
-// Main program
-
-int main(int argc, char **argv)
-{
-    // Determine the native byte order (SL_BYTEORDER_NATIVE not available until 1.1)
-    union {
-        short s;
-        char c[2];
-    } u;
-    u.s = 0x1234;
-    if (u.c[0] == 0x34) {
-        nativeByteOrder = SL_BYTEORDER_LITTLEENDIAN;
-    } else if (u.c[0] == 0x12) {
-        nativeByteOrder = SL_BYTEORDER_BIGENDIAN;
-    } else {
-        fprintf(stderr, "Unable to determine native byte order\n");
-        return EXIT_FAILURE;
-    }
-    byteOrder = nativeByteOrder;
-
-    SLboolean enableReverb = SL_BOOLEAN_FALSE;
-    SLboolean enablePlaybackRate = SL_BOOLEAN_FALSE;
-    SLpermille initialRate = 0;
-    SLpermille finalRate = 0;
-    SLpermille deltaRate = 1;
-    SLmillisecond deltaRateMs = 0;
-
-    // process command-line options
-    int i;
-    for (i = 1; i < argc; ++i) {
-        char *arg = argv[i];
-        if (arg[0] != '-') {
-            break;
-        }
-        if (!strcmp(arg, "-b")) {
-            byteOrder = SL_BYTEORDER_BIGENDIAN;
-        } else if (!strcmp(arg, "-l")) {
-            byteOrder = SL_BYTEORDER_LITTLEENDIAN;
-        } else if (!strcmp(arg, "-8")) {
-            bitsPerSample = 8;
-        } else if (!strncmp(arg, "-f", 2)) {
-            framesPerBuffer = atoi(&arg[2]);
-        } else if (!strncmp(arg, "-n", 2)) {
-            numBuffers = atoi(&arg[2]);
-        } else if (!strncmp(arg, "-p", 2)) {
-            initialRate = atoi(&arg[2]);
-            enablePlaybackRate = SL_BOOLEAN_TRUE;
-        } else if (!strncmp(arg, "-P", 2)) {
-            finalRate = atoi(&arg[2]);
-            enablePlaybackRate = SL_BOOLEAN_TRUE;
-        } else if (!strncmp(arg, "-q", 2)) {
-            deltaRate = atoi(&arg[2]);
-            // deltaRate is a magnitude, so take absolute value
-            if (deltaRate < 0) {
-                deltaRate = -deltaRate;
-            }
-            enablePlaybackRate = SL_BOOLEAN_TRUE;
-        } else if (!strncmp(arg, "-Q", 2)) {
-            deltaRateMs = atoi(&arg[2]);
-            enablePlaybackRate = SL_BOOLEAN_TRUE;
-        } else if (!strcmp(arg, "-r")) {
-            enableReverb = SL_BOOLEAN_TRUE;
-        } else {
-            fprintf(stderr, "option %s ignored\n", arg);
-        }
-    }
-
-    if (argc - i != 1) {
-        fprintf(stderr, "usage: [-b/l] [-8] [-f#] [-n#] [-p#] [-r] %s filename\n", argv[0]);
-        fprintf(stderr, "    -b  force big-endian byte order (default is native byte order)\n");
-        fprintf(stderr, "    -l  force little-endian byte order (default is native byte order)\n");
-        fprintf(stderr, "    -8  output 8-bits per sample (default is 16-bits per sample)\n");
-        fprintf(stderr, "    -f# frames per buffer (default 512)\n");
-        fprintf(stderr, "    -n# number of buffers (default 2)\n");
-        fprintf(stderr, "    -p# initial playback rate in per mille (default 1000)\n");
-        fprintf(stderr, "    -P# final playback rate in per mille (default same as -p#)\n");
-        fprintf(stderr, "    -q# magnitude of playback rate changes in per mille (default 1)\n");
-        fprintf(stderr, "    -Q# period between playback rate changes in ms (default 50)\n");
-        fprintf(stderr, "    -r  enable reverb (default disabled)\n");
-        return EXIT_FAILURE;
-    }
-
-    const char *filename = argv[i];
-    //memset(&sfinfo, 0, sizeof(SF_INFO));
-    sfinfo.format = 0;
-    sndfile = sf_open(filename, SFM_READ, &sfinfo);
-    if (NULL == sndfile) {
-        perror(filename);
-        return EXIT_FAILURE;
-    }
-
-    // The sample rate is a lie, but it doesn't actually matter
-    const android::NBAIO_Format nbaio_format = android::Format_from_SR_C(44100, sfinfo.channels);
-
-    // verify the file format
-    switch (sfinfo.channels) {
-    case 1:
-    case 2:
-        break;
-    default:
-        fprintf(stderr, "unsupported channel count %d\n", sfinfo.channels);
-        goto close_sndfile;
-    }
-
-    switch (sfinfo.samplerate) {
-    case  8000:
-    case 11025:
-    case 12000:
-    case 16000:
-    case 22050:
-    case 24000:
-    case 32000:
-    case 44100:
-    case 48000:
-        break;
-    default:
-        fprintf(stderr, "unsupported sample rate %d\n", sfinfo.samplerate);
-        goto close_sndfile;
-    }
-
-    switch (sfinfo.format & SF_FORMAT_TYPEMASK) {
-    case SF_FORMAT_WAV:
-        break;
-    default:
-        fprintf(stderr, "unsupported format type 0x%x\n", sfinfo.format & SF_FORMAT_TYPEMASK);
-        goto close_sndfile;
-    }
-
-    switch (sfinfo.format & SF_FORMAT_SUBMASK) {
-    case SF_FORMAT_PCM_16:
-    case SF_FORMAT_PCM_U8:
-        break;
-    default:
-        fprintf(stderr, "unsupported sub-format 0x%x\n", sfinfo.format & SF_FORMAT_SUBMASK);
-        goto close_sndfile;
-    }
-
-    {
-
-    buffers = (short *) malloc(framesPerBuffer * sfinfo.channels * sizeof(short) * numBuffers);
-
-    // create engine
-    SLresult result;
-    SLObjectItf engineObject;
-    result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
-    assert(SL_RESULT_SUCCESS == result);
-    SLEngineItf engineEngine;
-    result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
-    assert(SL_RESULT_SUCCESS == result);
-    result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
-    assert(SL_RESULT_SUCCESS == result);
-
-    // create output mix
-    SLObjectItf outputMixObject;
-    SLInterfaceID ids[1] = {SL_IID_ENVIRONMENTALREVERB};
-    SLboolean req[1] = {SL_BOOLEAN_TRUE};
-    result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, enableReverb ? 1 : 0,
-            ids, req);
-    assert(SL_RESULT_SUCCESS == result);
-    result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
-    assert(SL_RESULT_SUCCESS == result);
-
-    // configure environmental reverb on output mix
-    SLEnvironmentalReverbItf mixEnvironmentalReverb = NULL;
-    if (enableReverb) {
-        result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_ENVIRONMENTALREVERB,
-                &mixEnvironmentalReverb);
-        assert(SL_RESULT_SUCCESS == result);
-        SLEnvironmentalReverbSettings settings = SL_I3DL2_ENVIRONMENT_PRESET_STONECORRIDOR;
-        result = (*mixEnvironmentalReverb)->SetEnvironmentalReverbProperties(mixEnvironmentalReverb,
-                &settings);
-        assert(SL_RESULT_SUCCESS == result);
-    }
-
-    // configure audio source
-    SLDataLocator_BufferQueue loc_bufq;
-    loc_bufq.locatorType = SL_DATALOCATOR_BUFFERQUEUE;
-    loc_bufq.numBuffers = numBuffers;
-    SLDataFormat_PCM format_pcm;
-    format_pcm.formatType = SL_DATAFORMAT_PCM;
-    format_pcm.numChannels = sfinfo.channels;
-    format_pcm.samplesPerSec = sfinfo.samplerate * 1000;
-    format_pcm.bitsPerSample = bitsPerSample;
-    format_pcm.containerSize = format_pcm.bitsPerSample;
-    format_pcm.channelMask = 1 == format_pcm.numChannels ? SL_SPEAKER_FRONT_CENTER :
-            SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
-    format_pcm.endianness = byteOrder;
-    SLDataSource audioSrc;
-    audioSrc.pLocator = &loc_bufq;
-    audioSrc.pFormat = &format_pcm;
-
-    // configure audio sink
-    SLDataLocator_OutputMix loc_outmix;
-    loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
-    loc_outmix.outputMix = outputMixObject;
-    SLDataSink audioSnk;
-    audioSnk.pLocator = &loc_outmix;
-    audioSnk.pFormat = NULL;
-
-    // create audio player
-    SLInterfaceID ids2[3] = {SL_IID_BUFFERQUEUE, SL_IID_PLAYBACKRATE, SL_IID_EFFECTSEND};
-    SLboolean req2[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
-    SLObjectItf playerObject;
-    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
-            &audioSnk, enableReverb ? 3 : (enablePlaybackRate ? 2 : 1), ids2, req2);
-    if (SL_RESULT_SUCCESS != result) {
-        fprintf(stderr, "can't create audio player\n");
-        goto no_player;
-    }
-
-    {
-
-    // realize the player
-    result = (*playerObject)->Realize(playerObject, SL_BOOLEAN_FALSE);
-    assert(SL_RESULT_SUCCESS == result);
-
-    // get the effect send interface and enable effect send reverb for this player
-    if (enableReverb) {
-        SLEffectSendItf playerEffectSend;
-        result = (*playerObject)->GetInterface(playerObject, SL_IID_EFFECTSEND, &playerEffectSend);
-        assert(SL_RESULT_SUCCESS == result);
-        result = (*playerEffectSend)->EnableEffectSend(playerEffectSend, mixEnvironmentalReverb,
-                SL_BOOLEAN_TRUE, (SLmillibel) 0);
-        assert(SL_RESULT_SUCCESS == result);
-    }
-
-    // get the playback rate interface and configure the rate
-    SLPlaybackRateItf playerPlaybackRate;
-    SLpermille currentRate = 0;
-    if (enablePlaybackRate) {
-        result = (*playerObject)->GetInterface(playerObject, SL_IID_PLAYBACKRATE,
-                &playerPlaybackRate);
-        assert(SL_RESULT_SUCCESS == result);
-        SLpermille defaultRate;
-        result = (*playerPlaybackRate)->GetRate(playerPlaybackRate, &defaultRate);
-        assert(SL_RESULT_SUCCESS == result);
-        SLuint32 defaultProperties;
-        result = (*playerPlaybackRate)->GetProperties(playerPlaybackRate, &defaultProperties);
-        assert(SL_RESULT_SUCCESS == result);
-        printf("default playback rate %d per mille, properties 0x%x\n", defaultRate,
-                defaultProperties);
-        if (initialRate <= 0) {
-            initialRate = defaultRate;
-        }
-        if (finalRate <= 0) {
-            finalRate = initialRate;
-        }
-        currentRate = defaultRate;
-        if (finalRate == initialRate) {
-            deltaRate = 0;
-        } else if (finalRate < initialRate) {
-            deltaRate = -deltaRate;
-        }
-        if (initialRate != defaultRate) {
-            result = (*playerPlaybackRate)->SetRate(playerPlaybackRate, initialRate);
-            if (SL_RESULT_FEATURE_UNSUPPORTED == result) {
-                fprintf(stderr, "initial playback rate %d is unsupported\n", initialRate);
-                deltaRate = 0;
-            } else if (SL_RESULT_PARAMETER_INVALID == result) {
-                fprintf(stderr, "initial playback rate %d is invalid\n", initialRate);
-                deltaRate = 0;
-            } else {
-                assert(SL_RESULT_SUCCESS == result);
-                currentRate = initialRate;
-            }
-        }
-    }
-
-    // get the play interface
-    SLPlayItf playerPlay;
-    result = (*playerObject)->GetInterface(playerObject, SL_IID_PLAY, &playerPlay);
-    assert(SL_RESULT_SUCCESS == result);
-
-    // get the buffer queue interface
-    SLBufferQueueItf playerBufferQueue;
-    result = (*playerObject)->GetInterface(playerObject, SL_IID_BUFFERQUEUE,
-            &playerBufferQueue);
-    assert(SL_RESULT_SUCCESS == result);
-
-    // loop until EOF or no more buffers
-    for (which = 0; which < numBuffers; ++which) {
-        short *buffer = &buffers[framesPerBuffer * sfinfo.channels * which];
-        sf_count_t frames = framesPerBuffer;
-        sf_count_t count;
-        count = sf_readf_short(sndfile, buffer, frames);
-        if (0 >= count) {
-            eof = SL_BOOLEAN_TRUE;
-            break;
-        }
-
-        // enqueue a buffer
-        SLuint32 nbytes = count * sfinfo.channels * sizeof(short);
-        if (byteOrder != nativeByteOrder) {
-            swab(buffer, buffer, nbytes);
-        }
-        if (bitsPerSample == 8) {
-            squeeze(buffer, (unsigned char *) buffer, nbytes);
-            nbytes /= 2;
-        }
-        result = (*playerBufferQueue)->Enqueue(playerBufferQueue, buffer, nbytes);
-        assert(SL_RESULT_SUCCESS == result);
-    }
-    if (which >= numBuffers) {
-        which = 0;
-    }
-
-    // register a callback on the buffer queue
-    result = (*playerBufferQueue)->RegisterCallback(playerBufferQueue, callback, NULL);
-    assert(SL_RESULT_SUCCESS == result);
-
-    pipeWriter = new android::MonoPipe(16384, nbaio_format, false /*writeCanBlock*/);
-    android::NBAIO_Format offer = nbaio_format;
-    size_t numCounterOffers = 0;
-    ssize_t neg = pipeWriter->negotiate(&offer, 1, NULL, numCounterOffers);
-    assert(0 == neg);
-    pipeReader = new android::MonoPipeReader(pipeWriter);
-    numCounterOffers = 0;
-    neg = pipeReader->negotiate(&offer, 1, NULL, numCounterOffers);
-    assert(0 == neg);
-
-    // create thread to read from file
-    pthread_t thread;
-    int ok = pthread_create(&thread, (const pthread_attr_t *) NULL, file_reader_loop, NULL);
-    assert(0 == ok);
-
-    // give thread a head start so that the pipe is initially filled
-    sleep(1);
-
-    // set the player's state to playing
-    result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING);
-    assert(SL_RESULT_SUCCESS == result);
-
-    // get the initial time
-    struct timespec prevTs;
-    clock_gettime(CLOCK_MONOTONIC, &prevTs);
-    long elapsedNs = 0;
-    long deltaRateNs = deltaRateMs * 1000000;
-
-    // wait until the buffer queue is empty
-    SLBufferQueueState bufqstate;
-    for (;;) {
-        result = (*playerBufferQueue)->GetState(playerBufferQueue, &bufqstate);
-        assert(SL_RESULT_SUCCESS == result);
-        if (0 >= bufqstate.count) {
-            break;
-        }
-        if (!enablePlaybackRate || deltaRate == 0) {
-            sleep(1);
-        } else {
-            struct timespec curTs;
-            clock_gettime(CLOCK_MONOTONIC, &curTs);
-            elapsedNs += (curTs.tv_sec - prevTs.tv_sec) * 1000000000 +
-                    // this term can be negative
-                    (curTs.tv_nsec - prevTs.tv_nsec);
-            prevTs = curTs;
-            if (elapsedNs < deltaRateNs) {
-                usleep((deltaRateNs - elapsedNs) / 1000);
-                continue;
-            }
-            elapsedNs -= deltaRateNs;
-            SLpermille nextRate = currentRate + deltaRate;
-            result = (*playerPlaybackRate)->SetRate(playerPlaybackRate, nextRate);
-            if (SL_RESULT_SUCCESS != result) {
-                fprintf(stderr, "next playback rate %d is unsupported\n", nextRate);
-            } else if (SL_RESULT_PARAMETER_INVALID == result) {
-                fprintf(stderr, "next playback rate %d is invalid\n", nextRate);
-            } else {
-                assert(SL_RESULT_SUCCESS == result);
-            }
-            currentRate = nextRate;
-            if (currentRate >= max(initialRate, finalRate)) {
-                currentRate = max(initialRate, finalRate);
-                deltaRate = -abs(deltaRate);
-            } else if (currentRate <= min(initialRate, finalRate)) {
-                currentRate = min(initialRate, finalRate);
-                deltaRate = abs(deltaRate);
-            }
-        }
-    }
-
-    // destroy audio player
-    (*playerObject)->Destroy(playerObject);
-
-    }
-
-no_player:
-
-    // destroy output mix
-    (*outputMixObject)->Destroy(outputMixObject);
-
-    // destroy engine
-    (*engineObject)->Destroy(engineObject);
-
-    }
-
-close_sndfile:
-
-    (void) sf_close(sndfile);
-
-    return EXIT_SUCCESS;
-}
diff -urN Original_4.4.4_r1/frameworks/wilhelm/tools/hashgen/interfaces.c AndroidSource/frameworks/wilhelm/tools/hashgen/interfaces.c
--- Original_4.4.4_r1/frameworks/wilhelm/tools/hashgen/interfaces.c	2016-01-29 15:12:36.631488000 +0900
+++ AndroidSource/frameworks/wilhelm/tools/hashgen/interfaces.c	1970-01-01 09:00:00.000000000 +0900
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-// Map minimal perfect hash of an interface ID to its name
-
-#include <assert.h>
-#include <string.h>
-#include "MPH.h"
-
-const char * const interface_names[MPH_MAX] = {
-
-    // OpenSL ES 1.0.1 interfaces
-    "3DCOMMIT",
-    "3DDOPPLER",
-    "3DGROUPING",
-    "3DLOCATION",
-    "3DMACROSCOPIC",
-    "3DSOURCE",
-    "AUDIODECODERCAPABILITIES",
-    "AUDIOENCODER",
-    "AUDIOENCODERCAPABILITIES",
-    "AUDIOIODEVICECAPABILITIES",
-    "BASSBOOST",
-    "BUFFERQUEUE",
-    "DEVICEVOLUME",
-    "DYNAMICINTERFACEMANAGEMENT",
-    "DYNAMICSOURCE",
-    "EFFECTSEND",
-    "ENGINE",
-    "ENGINECAPABILITIES",
-    "ENVIRONMENTALREVERB",
-    "EQUALIZER",
-    "LED",
-    "METADATAEXTRACTION",
-    "METADATATRAVERSAL",
-    "MIDIMESSAGE",
-    "MIDIMUTESOLO",
-    "MIDITEMPO",
-    "MIDITIME",
-    "MUTESOLO",
-    "NULL",
-    "OBJECT",
-    "OUTPUTMIX",
-    "PITCH",
-    "PLAY",
-    "PLAYBACKRATE",
-    "PREFETCHSTATUS",
-    "PRESETREVERB",
-    "RATEPITCH",
-    "RECORD",
-    "SEEK",
-    "THREADSYNC",
-    "VIBRA",
-    "VIRTUALIZER",
-    "VISUALIZATION",
-    "VOLUME",
-
-    // Wilhelm desktop extended interfaces
-    "OUTPUTMIXEXT",
-
-    // Android API level 9 extended interfaces
-    "ANDROIDEFFECT",
-    "ANDROIDEFFECTCAPABILITIES",
-    "ANDROIDEFFECTSEND",
-    "ANDROIDCONFIGURATION",
-    "ANDROIDSIMPLEBUFFERQUEUE",
-
-    // Android API level 12 extended interfaces
-    "ANDROIDBUFFERQUEUESOURCE",
-
-    // OpenMAX AL 1.0.1 interfaces
-    "XAAUDIODECODERCAPABILITIES",
-    "XAAUDIOENCODER",
-    "XAAUDIOENCODERCAPABILITIES",
-    "XAAUDIOIODEVICECAPABILITIES",
-    "XACAMERA",
-    "XACAMERACAPABILITIES",
-    "XACONFIGEXTENSION",
-    "XADEVICEVOLUME",
-    "XADYNAMICINTERFACEMANAGEMENT",
-    "XADYNAMICSOURCE",
-    "XAENGINE",
-    "XAEQUALIZER",
-    "XAIMAGECONTROLS",
-    "XAIMAGEDECODERCAPABILITIES",
-    "XAIMAGEEFFECTS",
-    "XAIMAGEENCODER",
-    "XAIMAGEENCODERCAPABILITIES",
-    "XALED",
-    "XAMETADATAEXTRACTION",
-    "XAMETADATAINSERTION",
-    "XAMETADATATRAVERSAL",
-    // "XANULL",
-    "XAOBJECT",
-    "XAOUTPUTMIX",
-    "XAPLAY",
-    "XAPLAYBACKRATE",
-    "XAPREFETCHSTATUS",
-    "XARADIO",
-    "XARDS",
-    "XARECORD",
-    "XASEEK",
-    "XASNAPSHOT",
-    "XASTREAMINFORMATION",
-    "XATHREADSYNC",
-    "XAVIBRA",
-    "XAVIDEODECODERCAPABILITIES",
-    "XAVIDEOENCODER",
-    "XAVIDEOENCODERCAPABILITIES",
-    "XAVIDEOPOSTPROCESSING",
-    "XAVOLUME",
-
-};
-
-
-/** Convert an MPH value to an MPH identifier */
-
-void MPH_to_MPH_string(unsigned MPH, char buffer[40])
-{
-    assert(MPH_MAX > MPH);
-    const char *infix;
-    infix = "";
-    strcpy(buffer, "MPH");
-    strcpy(&buffer[3], infix);
-    strcat(buffer, "_");
-    strcat(buffer, interface_names[MPH]);
-}
diff -urN Original_4.4.4_r1/frameworks/wilhelm/tools/hashgen/MPH.h AndroidSource/frameworks/wilhelm/tools/hashgen/MPH.h
--- Original_4.4.4_r1/frameworks/wilhelm/tools/hashgen/MPH.h	2016-01-29 15:12:36.627488000 +0900
+++ AndroidSource/frameworks/wilhelm/tools/hashgen/MPH.h	1970-01-01 09:00:00.000000000 +0900
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-#ifndef __MPH_H
-#define __MPH_H
-
-// Minimal perfect hash for each interface ID
-
-#define MPH_NONE                      (-1)
-#define MPH_MIN                         0
-
-// OpenSL ES 1.0.1 interfaces
-#define MPH_3DCOMMIT                    0
-#define MPH_3DDOPPLER                   1
-#define MPH_3DGROUPING                  2
-#define MPH_3DLOCATION                  3
-#define MPH_3DMACROSCOPIC               4
-#define MPH_3DSOURCE                    5
-#define MPH_AUDIODECODERCAPABILITIES    6
-#define MPH_AUDIOENCODER                7
-#define MPH_AUDIOENCODERCAPABILITIES    8
-#define MPH_AUDIOIODEVICECAPABILITIES   9
-#define MPH_BASSBOOST                  10
-#define MPH_BUFFERQUEUE                11
-#define MPH_DEVICEVOLUME               12
-#define MPH_DYNAMICINTERFACEMANAGEMENT 13
-#define MPH_DYNAMICSOURCE              14
-#define MPH_EFFECTSEND                 15
-#define MPH_ENGINE                     16
-#define MPH_ENGINECAPABILITIES         17
-#define MPH_ENVIRONMENTALREVERB        18
-#define MPH_EQUALIZER                  19
-#define MPH_LED                        20
-#define MPH_METADATAEXTRACTION         21
-#define MPH_METADATATRAVERSAL          22
-#define MPH_MIDIMESSAGE                23
-#define MPH_MIDIMUTESOLO               24
-#define MPH_MIDITEMPO                  25
-#define MPH_MIDITIME                   26
-#define MPH_MUTESOLO                   27
-#define MPH_NULL                       28  // shared by SL and XA
-#define MPH_OBJECT                     29
-#define MPH_OUTPUTMIX                  30
-#define MPH_PITCH                      31
-#define MPH_PLAY                       32
-#define MPH_PLAYBACKRATE               33
-#define MPH_PREFETCHSTATUS             34
-#define MPH_PRESETREVERB               35
-#define MPH_RATEPITCH                  36
-#define MPH_RECORD                     37
-#define MPH_SEEK                       38
-#define MPH_THREADSYNC                 39
-#define MPH_VIBRA                      40
-#define MPH_VIRTUALIZER                41
-#define MPH_VISUALIZATION              42
-#define MPH_VOLUME                     43
-
-// Wilhelm desktop extended interfaces
-#define MPH_OUTPUTMIXEXT               44
-
-// Android API level 9 extended interfaces
-// GUID and MPH are shared by SL and XA, but currently documented for SL only
-#define MPH_ANDROIDEFFECT              45
-#define MPH_ANDROIDEFFECTCAPABILITIES  46
-#define MPH_ANDROIDEFFECTSEND          47
-#define MPH_ANDROIDCONFIGURATION       48
-#define MPH_ANDROIDSIMPLEBUFFERQUEUE   49
-
-// Android API level 12 extended interfaces
-// GUID and MPH are shared by SL and XA, but currently documented for XA only
-#define MPH_ANDROIDBUFFERQUEUESOURCE   50
-
-// OpenMAX AL 1.0.1 interfaces
-#define MPH_XAAUDIODECODERCAPABILITIES   51
-#define MPH_XAAUDIOENCODER               52
-#define MPH_XAAUDIOENCODERCAPABILITIES   53
-#define MPH_XAAUDIOIODEVICECAPABILITIES  54
-#define MPH_XACAMERA                     55
-#define MPH_XACAMERACAPABILITIES         56
-#define MPH_XACONFIGEXTENSION            57
-#define MPH_XADEVICEVOLUME               58
-#define MPH_XADYNAMICINTERFACEMANAGEMENT 59
-#define MPH_XADYNAMICSOURCE              60
-#define MPH_XAENGINE                     61
-#define MPH_XAEQUALIZER                  62
-#define MPH_XAIMAGECONTROLS              63
-#define MPH_XAIMAGEDECODERCAPABILITIES   64
-#define MPH_XAIMAGEEFFECTS               65
-#define MPH_XAIMAGEENCODER               66
-#define MPH_XAIMAGEENCODERCAPABILITIES   67
-#define MPH_XALED                        68
-#define MPH_XAMETADATAEXTRACTION         69
-#define MPH_XAMETADATAINSERTION          70
-#define MPH_XAMETADATATRAVERSAL          71
-#define MPH_XANULL                 MPH_NULL
-#define MPH_XAOBJECT                     72
-#define MPH_XAOUTPUTMIX                  73
-#define MPH_XAPLAY                       74
-#define MPH_XAPLAYBACKRATE               75
-#define MPH_XAPREFETCHSTATUS             76
-#define MPH_XARADIO                      77
-#define MPH_XARDS                        78
-#define MPH_XARECORD                     79
-#define MPH_XASEEK                       80
-#define MPH_XASNAPSHOT                   81
-#define MPH_XASTREAMINFORMATION          82
-#define MPH_XATHREADSYNC                 83
-#define MPH_XAVIBRA                      84
-#define MPH_XAVIDEODECODERCAPABILITIES   85
-#define MPH_XAVIDEOENCODER               86
-#define MPH_XAVIDEOENCODERCAPABILITIES   87
-#define MPH_XAVIDEOPOSTPROCESSING        88
-#define MPH_XAVOLUME                     89
-
-// total number of interface IDs
-#define MPH_MAX                          90
-
-#endif // !defined(__MPH_H)
diff -urN Original_4.4.4_r1/frameworks/wilhelm/tools/hashgen/OpenSLES_IID.c AndroidSource/frameworks/wilhelm/tools/hashgen/OpenSLES_IID.c
--- Original_4.4.4_r1/frameworks/wilhelm/tools/hashgen/OpenSLES_IID.c	2016-01-29 15:12:36.627488000 +0900
+++ AndroidSource/frameworks/wilhelm/tools/hashgen/OpenSLES_IID.c	1970-01-01 09:00:00.000000000 +0900
@@ -1,253 +0,0 @@
-/*
- * Copyright (c) 2007-2009 The Khronos Group Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and /or associated documentation files (the "Materials "), to
- * deal in the Materials without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Materials, and to permit persons to whom the Materials are
- * furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Materials.
- *
- * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS IN THE
- * MATERIALS.
- *
- * OpenSLES_IID.c - OpenSL ES version 1.0
- *
- */
-
-/****************************************************************************/
-/* NOTE: This file is a standard OpenSL ES file and should not be           */
-/* modified in any way.                                                     */
-/****************************************************************************/
-
-
-#include <SLES/OpenSLES.h>         /* SL Header */
-#include <OMXAL/OpenMAXAL.h>
-#ifdef ANDROID
-#include <SLES/OpenSLES_Android.h>  /* Android-specific SL Header */
-#include <OMXAL/OpenMAXAL_Android.h>/* Android-specific MAX AL Header */
-#endif
-#include "MPH.h"
-
-#ifdef __cplusplus
-LI_API extern const struct SLInterfaceID_ SL_IID_array[MPH_MAX];
-#endif
-
-/*****************************************************************************/
-/* Interface IDs                                                             */
-/*****************************************************************************/
-
-// Note that the lack of an ifdef on each section is intentional. The entries in this table map
-// to an interface GUID from an MPH (a short-hand representation of the full interface GUID).
-// The presence of an entry does not represent a commitment to support that particular interface.
-
-const struct SLInterfaceID_ SL_IID_array[MPH_MAX] = {
-
-// OpenSL ES 1.0.1 interfaces
-
-    // SL_IID_3DCOMMIT
-    { 0x3564ad80, 0xdd0f, 0x11db, 0x9e19, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_3DDOPPLER
-    { 0xb45c9a80, 0xddd2, 0x11db, 0xb028, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_3DGROUPING
-    { 0xebe844e0, 0xddd2, 0x11db, 0xb510, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_3DLOCATION
-    { 0x2b878020, 0xddd3, 0x11db, 0x8a01, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_3DMACROSCOPIC
-    { 0x5089aec0, 0xddd3, 0x11db, 0x9ad3, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_3DSOURCE
-    { 0x70bc7b00, 0xddd3, 0x11db, 0xa873, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_AUDIODECODERCAPABILITIES
-    { 0x3fe5a3a0, 0xfcc6, 0x11db, 0x94ac, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_AUDIOENCODER
-    { 0xd7d5af7a, 0x351c, 0x41a6, 0x94ec, { 0x1a, 0xc9, 0x5c, 0x71, 0x82, 0x2c } },
-    // SL_IID_AUDIOENCODERCAPABILITIES
-    { 0x0f52a340, 0xfcd1, 0x11db, 0xa993, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_AUDIOIODEVICECAPABILITIES
-    { 0xb2564dc0, 0xddd3, 0x11db, 0xbd62, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_BASSBOOST
-    { 0x0634f220, 0xddd4, 0x11db, 0xa0fc, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_BUFFERQUEUE
-    { 0x2bc99cc0, 0xddd4, 0x11db, 0x8d99, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_DEVICEVOLUME
-    { 0xe1634760, 0xf3e2, 0x11db, 0x9ca9, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_DYNAMICINTERFACEMANAGEMENT
-    { 0x63936540, 0xf775, 0x11db, 0x9cc4, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_DYNAMICSOURCE
-    { 0xc55cc100, 0x038b, 0x11dc, 0xbb45, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_EFFECTSEND
-    { 0x56e7d200, 0xddd4, 0x11db, 0xaefb, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_ENGINE
-    { 0x8d97c260, 0xddd4, 0x11db, 0x958f, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_ENGINECAPABILITIES
-    { 0x8320d0a0, 0xddd5, 0x11db, 0xa1b1, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_ENVIRONMENTALREVERB
-    { 0xc2e5d5f0, 0x94bd, 0x4763, 0x9cac, { 0x4e, 0x23, 0x4d, 0x6, 0x83, 0x9e } },
-    // SL_IID_EQUALIZER
-    { 0x0bed4300, 0xddd6, 0x11db, 0x8f34, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_LED
-    { 0x2cc1cd80, 0xddd6, 0x11db, 0x807e, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_METADATAEXTRACTION
-    { 0xaa5b1f80, 0xddd6, 0x11db, 0xac8e, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_METADATATRAVERSAL
-    { 0xc43662c0, 0xddd6, 0x11db, 0xa7ab, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_MIDIMESSAGE
-    { 0xddf4a820, 0xddd6, 0x11db, 0xb174, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_MIDIMUTESOLO
-    { 0x039eaf80, 0xddd7, 0x11db, 0x9a02, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_MIDITEMPO
-    { 0x1f347400, 0xddd7, 0x11db, 0xa7ce, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_MIDITIME
-    { 0x3da51de0, 0xddd7, 0x11db, 0xaf70, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_MUTESOLO
-    { 0x5a28ebe0, 0xddd7, 0x11db, 0x8220, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_NULL
-    { 0xec7178ec, 0xe5e1, 0x4432, 0xa3f4, { 0x46, 0x57, 0xe6, 0x79, 0x52, 0x10 } },
-    // SL_IID_OBJECT
-    { 0x79216360, 0xddd7, 0x11db, 0xac16, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_OUTPUTMIX
-    { 0x97750f60, 0xddd7, 0x11db, 0x92b1, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_PITCH
-    { 0xc7e8ee00, 0xddd7, 0x11db, 0xa42c, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_PLAY
-    { 0xef0bd9c0, 0xddd7, 0x11db, 0xbf49, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_PLAYBACKRATE
-    { 0x2e3b2a40, 0xddda, 0x11db, 0xa349, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_PREFETCHSTATUS
-    { 0x2a41ee80, 0xddd8, 0x11db, 0xa41f, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_PRESETREVERB
-    { 0x47382d60, 0xddd8, 0x11db, 0xbf3a, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_RATEPITCH
-    { 0x61b62e60, 0xddda, 0x11db, 0x9eb8, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_RECORD
-    { 0xc5657aa0, 0xdddb, 0x11db, 0x82f7, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_SEEK
-    { 0xd43135a0, 0xdddc, 0x11db, 0xb458, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_THREADSYNC
-    { 0xf6ac6b40, 0xdddc, 0x11db, 0xa62e, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_VIBRA
-    { 0x169a8d60, 0xdddd, 0x11db, 0x923d, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_VIRTUALIZER
-    { 0x37cc2c00, 0xdddd, 0x11db, 0x8577, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_VISUALIZATION
-    { 0xe46b26a0, 0xdddd, 0x11db, 0x8afd, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_VOLUME
-    { 0x09e8ede0, 0xddde, 0x11db, 0xb4f6, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-
-// Wilhelm desktop extended interfaces
-
-    // SL_IID_OUTPUTMIXEXT
-    { 0xfe5cce00, 0x57bb, 0x11df, 0x951c, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-
-// Android API level 9 extended interfaces
-// GUID and MPH shared by SL and XA, but currently documented for SL only
-
-    // SL_IID_ANDROIDEFFECT
-    { 0xae12da60, 0x99ac, 0x11df, 0xb456, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_ANDROIDEFFECTCAPABILITIES
-    { 0x6a4f6d60, 0xb5e6, 0x11df, 0xbb3b, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_ANDROIDEFFECTSEND
-    { 0x7be462c0, 0xbc43, 0x11df, 0x8670, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_ANDROIDCONFIGURATION
-    { 0x89f6a7e0, 0xbeac, 0x11df, 0x8b5c, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_ANDROIDSIMPLEBUFERQUEUE
-    { 0x198e4940, 0xc5d7, 0x11df, 0xa2a6, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-
-// Android API level 12 extended interfaces
-// GUID and MPH shared by SL and XA, but currently documented for XA only
-
-    // SL_IID_ANDROIDBUFFERQUEUESOURCE
-    { 0x7fc1a460, 0xeec1, 0x11df, 0xa306, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-
-// OpenMAX AL 1.0.1 interfaces
-
-    // XA_IID_AUDIODECODERCAPABILITIES
-    { 0xdeac0cc0, 0x3995, 0x11dc, 0x8872, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_AUDIOENCODER
-    { 0xebbab900, 0x3997, 0x11dc, 0x891f, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_AUDIOENCODERCAPABILITIES
-    { 0x83fbc600, 0x3998, 0x11dc, 0x8f6d, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_AUDIOIODEVICECAPABILITIES
-    { 0x2b276d00, 0xf775, 0x11db, 0xa963, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_CAMERA
-    { 0xc7b84d20, 0xdf00, 0x11db, 0xba87, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_CAMERACAPABILITIES
-    { 0x01cab1c0, 0xe86a, 0x11db, 0xa5b9, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_CONFIGEXTENSION
-    { 0x6dc22ea0, 0xdf03, 0x11db, 0xbed7, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_DEVICEVOLUME
-    { 0x4bb44020, 0xf775, 0x11db, 0xad03, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_DYNAMICINTERFACEMANAGEMENT
-    { 0x6e2340c0, 0xf775, 0x11db, 0x85da, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_DYNAMICSOURCE
-    { 0xc88d5480, 0x3a12, 0x11dc, 0x80a2, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_ENGINE
-    { 0x45c58f40, 0xdf04, 0x11db, 0x9e76, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_EQUALIZER
-    { 0x7ad86d40, 0xf775, 0x11db, 0xbc77, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_IMAGECONTROLS
-    { 0xf46de3e0, 0xdf03, 0x11db, 0x92f1, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_IMAGEDECODERCAPABILITIES
-    { 0xc333e7a0, 0xe616, 0x11dc, 0xa93e, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_IMAGEEFFECTS
-    { 0xb865bca0, 0xdf04, 0x11db, 0xbab9, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_IMAGEENCODER
-    { 0xcd49f140, 0xdf04, 0x11db, 0x8888, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_IMAGEENCODERCAPABILITIES
-    { 0xc19f0640, 0xe86f, 0x11db, 0xb2d2, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_LED
-    { 0xa534d920, 0xf775, 0x11db, 0x8b70, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_METADATAEXTRACTION
-    { 0x5df4fda0, 0xf776, 0x11db, 0xabc5, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_METADATAINSERTION
-    { 0x49a14d60, 0xdf05, 0x11db, 0x9191, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_METADATATRAVERSAL
-    { 0x73ffb0e0, 0xf776, 0x11db, 0xa00e, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_OBJECT
-    { 0x82f5a5a0, 0xf776, 0x11db, 0x9700, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_OUTPUTMIX
-    { 0xb25b6fa0, 0xf776, 0x11db, 0xb86b, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_NULL
-    // shared with OpenSL ES
-    // XA_IID_PLAY
-    { 0xb9c293e0, 0xf776, 0x11db, 0x80df, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_PLAYBACKRATE
-    { 0xc36f1440, 0xf776, 0x11db, 0xac48, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_PREFETCHSTATUS
-    { 0xcceac0a0, 0xf776, 0x11db, 0xbb9c, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_RADIO
-    { 0xb316ad80, 0xdf05, 0x11db, 0xb5b6, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_RDS
-    { 0xb80f42c0, 0xdf05, 0x11db, 0x92a5, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_RECORD
-    { 0xd7948cc0, 0xf776, 0x11db, 0x8a3b, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_SEEK
-    { 0xee6a3120, 0xf776, 0x11db, 0xb518, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_SNAPSHOT
-    { 0xdb1b6dc0, 0xdf05, 0x11db, 0x8c01, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_STREAMINFORMATION
-    { 0x3a628fe0, 0x1238, 0x11de, 0xad9f, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_THREADSYNC
-    { 0xf3599ea0, 0xf776, 0x11db, 0xb3ea, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_VIBRA
-    { 0xfe374c00, 0xf776, 0x11db, 0xa8f0, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_VIDEODECODERCAPABILITIES
-    { 0xd18cb200, 0xe616, 0x11dc, 0xab01, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_VIDEOENCODER
-    { 0x9444db60, 0xdf06, 0x11db, 0xb311, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_VIDEOENCODERCAPABILITIES
-    { 0x5aef2760, 0xe872, 0x11db, 0x849f, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_VIDEOPOSTPROCESSING
-    { 0x898b6820, 0x7e6e, 0x11dd, 0x8caf, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // XA_IID_VOLUME
-    { 0x088ba520, 0xf777, 0x11db, 0xa5e3, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-};
diff -urN Original_4.4.4_r1/frameworks/wilhelm/tools/mphtogen/MPH.h AndroidSource/frameworks/wilhelm/tools/mphtogen/MPH.h
--- Original_4.4.4_r1/frameworks/wilhelm/tools/mphtogen/MPH.h	2016-01-29 15:12:36.627488000 +0900
+++ AndroidSource/frameworks/wilhelm/tools/mphtogen/MPH.h	1970-01-01 09:00:00.000000000 +0900
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-#ifndef __MPH_H
-#define __MPH_H
-
-// Minimal perfect hash for each interface ID
-
-#define MPH_NONE                      (-1)
-#define MPH_MIN                         0
-
-// OpenSL ES 1.0.1 interfaces
-#define MPH_3DCOMMIT                    0
-#define MPH_3DDOPPLER                   1
-#define MPH_3DGROUPING                  2
-#define MPH_3DLOCATION                  3
-#define MPH_3DMACROSCOPIC               4
-#define MPH_3DSOURCE                    5
-#define MPH_AUDIODECODERCAPABILITIES    6
-#define MPH_AUDIOENCODER                7
-#define MPH_AUDIOENCODERCAPABILITIES    8
-#define MPH_AUDIOIODEVICECAPABILITIES   9
-#define MPH_BASSBOOST                  10
-#define MPH_BUFFERQUEUE                11
-#define MPH_DEVICEVOLUME               12
-#define MPH_DYNAMICINTERFACEMANAGEMENT 13
-#define MPH_DYNAMICSOURCE              14
-#define MPH_EFFECTSEND                 15
-#define MPH_ENGINE                     16
-#define MPH_ENGINECAPABILITIES         17
-#define MPH_ENVIRONMENTALREVERB        18
-#define MPH_EQUALIZER                  19
-#define MPH_LED                        20
-#define MPH_METADATAEXTRACTION         21
-#define MPH_METADATATRAVERSAL          22
-#define MPH_MIDIMESSAGE                23
-#define MPH_MIDIMUTESOLO               24
-#define MPH_MIDITEMPO                  25
-#define MPH_MIDITIME                   26
-#define MPH_MUTESOLO                   27
-#define MPH_NULL                       28  // shared by SL and XA
-#define MPH_OBJECT                     29
-#define MPH_OUTPUTMIX                  30
-#define MPH_PITCH                      31
-#define MPH_PLAY                       32
-#define MPH_PLAYBACKRATE               33
-#define MPH_PREFETCHSTATUS             34
-#define MPH_PRESETREVERB               35
-#define MPH_RATEPITCH                  36
-#define MPH_RECORD                     37
-#define MPH_SEEK                       38
-#define MPH_THREADSYNC                 39
-#define MPH_VIBRA                      40
-#define MPH_VIRTUALIZER                41
-#define MPH_VISUALIZATION              42
-#define MPH_VOLUME                     43
-
-// Wilhelm desktop extended interfaces
-#define MPH_OUTPUTMIXEXT               44
-
-// Android API level 9 extended interfaces
-// GUID and MPH are shared by SL and XA, but currently documented for SL only
-#define MPH_ANDROIDEFFECT              45
-#define MPH_ANDROIDEFFECTCAPABILITIES  46
-#define MPH_ANDROIDEFFECTSEND          47
-#define MPH_ANDROIDCONFIGURATION       48
-#define MPH_ANDROIDSIMPLEBUFFERQUEUE   49
-
-// Android API level 12 extended interfaces
-// GUID and MPH are shared by SL and XA, but currently documented for XA only
-#define MPH_ANDROIDBUFFERQUEUESOURCE   50
-
-// OpenMAX AL 1.0.1 interfaces
-#define MPH_XAAUDIODECODERCAPABILITIES   51
-#define MPH_XAAUDIOENCODER               52
-#define MPH_XAAUDIOENCODERCAPABILITIES   53
-#define MPH_XAAUDIOIODEVICECAPABILITIES  54
-#define MPH_XACAMERA                     55
-#define MPH_XACAMERACAPABILITIES         56
-#define MPH_XACONFIGEXTENSION            57
-#define MPH_XADEVICEVOLUME               58
-#define MPH_XADYNAMICINTERFACEMANAGEMENT 59
-#define MPH_XADYNAMICSOURCE              60
-#define MPH_XAENGINE                     61
-#define MPH_XAEQUALIZER                  62
-#define MPH_XAIMAGECONTROLS              63
-#define MPH_XAIMAGEDECODERCAPABILITIES   64
-#define MPH_XAIMAGEEFFECTS               65
-#define MPH_XAIMAGEENCODER               66
-#define MPH_XAIMAGEENCODERCAPABILITIES   67
-#define MPH_XALED                        68
-#define MPH_XAMETADATAEXTRACTION         69
-#define MPH_XAMETADATAINSERTION          70
-#define MPH_XAMETADATATRAVERSAL          71
-#define MPH_XANULL                 MPH_NULL
-#define MPH_XAOBJECT                     72
-#define MPH_XAOUTPUTMIX                  73
-#define MPH_XAPLAY                       74
-#define MPH_XAPLAYBACKRATE               75
-#define MPH_XAPREFETCHSTATUS             76
-#define MPH_XARADIO                      77
-#define MPH_XARDS                        78
-#define MPH_XARECORD                     79
-#define MPH_XASEEK                       80
-#define MPH_XASNAPSHOT                   81
-#define MPH_XASTREAMINFORMATION          82
-#define MPH_XATHREADSYNC                 83
-#define MPH_XAVIBRA                      84
-#define MPH_XAVIDEODECODERCAPABILITIES   85
-#define MPH_XAVIDEOENCODER               86
-#define MPH_XAVIDEOENCODERCAPABILITIES   87
-#define MPH_XAVIDEOPOSTPROCESSING        88
-#define MPH_XAVOLUME                     89
-
-// total number of interface IDs
-#define MPH_MAX                          90
-
-#endif // !defined(__MPH_H)
diff -urN Original_4.4.4_r1/frameworks/wilhelm/tools/mphtogen/MPH_to.c AndroidSource/frameworks/wilhelm/tools/mphtogen/MPH_to.c
--- Original_4.4.4_r1/frameworks/wilhelm/tools/mphtogen/MPH_to.c	2016-01-29 15:12:36.627488000 +0900
+++ AndroidSource/frameworks/wilhelm/tools/mphtogen/MPH_to.c	1970-01-01 09:00:00.000000000 +0900
@@ -1,263 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-// Map minimal perfect hash of an interface ID to its class index.
-
-#include "MPH.h"
-
-// If defined, then compile with C99 such as GNU C, not GNU C++ or non-GNU C.
-//#define USE_DESIGNATED_INITIALIZERS
-
-// It is critical that all entries are populated with either a specific index
-// or -1. Do not let the compiler use a default initializer of zero, because
-// that actually maps to the IObject index. For non-USE_DESIGNATED_INITIALIZERS
-// builds, we use the automagically-generated MPH_to_*.h files for this reason.
-
-// A good test is to use the GNU C compiler with -S option (for assembler output),
-// and compile both with and without USE_DESIGNATED_INITIALIZERS.  The resulting .s
-// files should be identical for both compilations.
-
-// Important note: if you add any interfaces here, be sure to also
-// update the #define for the corresponding INTERFACES_<Class>.
-
-// IObject is the first interface in a class, so the index for MPH_OBJECT must be zero.
-// Don't cross streams, otherwise bad things happen.
-
-
-const signed char MPH_to_3DGroup[MPH_MAX] = {
-#ifdef USE_DESIGNATED_INITIALIZERS
-    [0 ... MPH_MAX-1] = -1,
-    [MPH_OBJECT] = 0,
-    [MPH_DYNAMICINTERFACEMANAGEMENT] = 1,
-    [MPH_3DLOCATION] = 2,
-    [MPH_3DDOPPLER] = 3,
-    [MPH_3DSOURCE] = 4,
-    [MPH_3DMACROSCOPIC] = 5
-#else
-#include "MPH_to_3DGroup.h"
-#endif
-};
-
-const signed char MPH_to_AudioPlayer[MPH_MAX] = {
-#ifdef USE_DESIGNATED_INITIALIZERS
-    [0 ... MPH_MAX-1] = -1,
-    [MPH_OBJECT] = 0,
-    [MPH_DYNAMICINTERFACEMANAGEMENT] = 1,
-    [MPH_PLAY] = 2,
-    [MPH_3DDOPPLER] = 3,
-    [MPH_3DGROUPING] = 4,
-    [MPH_3DLOCATION] = 5,
-    [MPH_3DSOURCE] = 6,
-    [MPH_BUFFERQUEUE] = 7,
-    [MPH_EFFECTSEND] = 8,
-    [MPH_MUTESOLO] = 9,
-    [MPH_METADATAEXTRACTION] = 10,
-    [MPH_METADATATRAVERSAL] = 11,
-    [MPH_PREFETCHSTATUS] = 12,
-    [MPH_RATEPITCH] = 13,
-    [MPH_SEEK] = 14,
-    [MPH_VOLUME] = 15,
-    [MPH_3DMACROSCOPIC] = 16,
-    [MPH_BASSBOOST] = 17,
-    [MPH_DYNAMICSOURCE] = 18,
-    [MPH_ENVIRONMENTALREVERB] = 19,
-    [MPH_EQUALIZER] = 20,
-    [MPH_PITCH] = 21,
-    [MPH_PRESETREVERB] = 22,
-    [MPH_PLAYBACKRATE] = 23,
-    [MPH_VIRTUALIZER] = 24,
-    [MPH_VISUALIZATION] = 25,
-#ifdef ANDROID
-    [MPH_ANDROIDEFFECT] = 26,
-    [MPH_ANDROIDEFFECTSEND] = 27,
-    [MPH_ANDROIDCONFIGURATION] = 28,
-    [MPH_ANDROIDSIMPLEBUFFERQUEUE] = 7,  // alias for [MPH_BUFFERQUEUE]
-    [MPH_ANDROIDBUFFERQUEUESOURCE] = 29
-#endif
-#else
-#include "MPH_to_AudioPlayer.h"
-#endif
-};
-
-const signed char MPH_to_AudioRecorder[MPH_MAX] = {
-#ifdef USE_DESIGNATED_INITIALIZERS
-    [0 ... MPH_MAX-1] = -1,
-    [MPH_OBJECT] = 0,
-    [MPH_DYNAMICINTERFACEMANAGEMENT] = 1,
-    [MPH_RECORD] = 2,
-    [MPH_AUDIOENCODER] = 3,
-    [MPH_BASSBOOST] = 4,
-    [MPH_DYNAMICSOURCE] = 5,
-    [MPH_EQUALIZER] = 6,
-    [MPH_VISUALIZATION] = 7,
-    [MPH_VOLUME] = 8,
-#ifdef ANDROID
-    [MPH_ANDROIDSIMPLEBUFFERQUEUE] = 9, // this is not an alias
-    [MPH_ANDROIDCONFIGURATION] = 10
-#endif
-#else
-#include "MPH_to_AudioRecorder.h"
-#endif
-};
-
-const signed char MPH_to_Engine[MPH_MAX] = {
-#ifdef USE_DESIGNATED_INITIALIZERS
-    [0 ... MPH_MAX-1] = -1,
-    [MPH_OBJECT] = 0,
-    [MPH_DYNAMICINTERFACEMANAGEMENT] = 1,
-    [MPH_ENGINE] = 2,
-    [MPH_ENGINECAPABILITIES] = 3,
-    [MPH_THREADSYNC] = 4,
-    [MPH_AUDIOIODEVICECAPABILITIES] = 5,
-    [MPH_AUDIODECODERCAPABILITIES] = 6,
-    [MPH_AUDIOENCODERCAPABILITIES] = 7,
-    [MPH_3DCOMMIT] = 8,
-    [MPH_DEVICEVOLUME] = 9,
-    [MPH_XAENGINE] = 10,
-#ifdef ANDROID
-    [MPH_ANDROIDEFFECTCAPABILITIES] = 11,
-#endif
-    [MPH_XAVIDEODECODERCAPABILITIES] = 12
-#else
-#include "MPH_to_Engine.h"
-#endif
-};
-
-const signed char MPH_to_LEDDevice[MPH_MAX] = {
-#ifdef USE_DESIGNATED_INITIALIZERS
-    [0 ... MPH_MAX-1] = -1,
-    [MPH_OBJECT] = 0,
-    [MPH_DYNAMICINTERFACEMANAGEMENT] = 1,
-    [MPH_LED] = 2
-#else
-#include "MPH_to_LEDDevice.h"
-#endif
-};
-
-const signed char MPH_to_Listener[MPH_MAX] = {
-#ifdef USE_DESIGNATED_INITIALIZERS
-    [0 ... MPH_MAX-1] = -1,
-    [MPH_OBJECT] = 0,
-    [MPH_DYNAMICINTERFACEMANAGEMENT] = 1,
-    [MPH_3DDOPPLER] = 2,
-    [MPH_3DLOCATION] = 3
-#else
-#include "MPH_to_Listener.h"
-#endif
-};
-
-const signed char MPH_to_MetadataExtractor[MPH_MAX] = {
-#ifdef USE_DESIGNATED_INITIALIZERS
-    [0 ... MPH_MAX-1] = -1,
-    [MPH_OBJECT] = 0,
-    [MPH_DYNAMICINTERFACEMANAGEMENT] = 1,
-    [MPH_DYNAMICSOURCE] = 2,
-    [MPH_METADATAEXTRACTION] = 3,
-    [MPH_METADATATRAVERSAL] = 4
-#else
-#include "MPH_to_MetadataExtractor.h"
-#endif
-};
-
-const signed char MPH_to_MidiPlayer[MPH_MAX] = {
-#ifdef USE_DESIGNATED_INITIALIZERS
-    [0 ... MPH_MAX-1] = -1,
-    [MPH_OBJECT] = 0,
-    [MPH_DYNAMICINTERFACEMANAGEMENT] = 1,
-    [MPH_PLAY] = 2,
-    [MPH_3DDOPPLER] = 3,
-    [MPH_3DGROUPING] = 4,
-    [MPH_3DLOCATION] = 5,
-    [MPH_3DSOURCE] = 6,
-    [MPH_BUFFERQUEUE] = 7,
-    [MPH_EFFECTSEND] = 8,
-    [MPH_MUTESOLO] = 9,
-    [MPH_METADATAEXTRACTION] = 10,
-    [MPH_METADATATRAVERSAL] = 11,
-    [MPH_MIDIMESSAGE] = 12,
-    [MPH_MIDITIME] = 13,
-    [MPH_MIDITEMPO] = 14,
-    [MPH_MIDIMUTESOLO] = 15,
-    [MPH_PREFETCHSTATUS] = 16,
-    [MPH_SEEK] = 17,
-    [MPH_VOLUME] = 18,
-    [MPH_3DMACROSCOPIC] = 19,
-    [MPH_BASSBOOST] = 20,
-    [MPH_DYNAMICSOURCE] = 21,
-    [MPH_ENVIRONMENTALREVERB] = 22,
-    [MPH_EQUALIZER] = 23,
-    [MPH_PITCH] = 24,
-    [MPH_PRESETREVERB] = 25,
-    [MPH_PLAYBACKRATE] = 26,
-    [MPH_VIRTUALIZER] = 27,
-    [MPH_VISUALIZATION] = 28,
-#else
-#include "MPH_to_MidiPlayer.h"
-#endif
-};
-
-const signed char MPH_to_OutputMix[MPH_MAX] = {
-#ifdef USE_DESIGNATED_INITIALIZERS
-    [0 ... MPH_MAX-1] = -1,
-    [MPH_OBJECT] = 0,
-    [MPH_DYNAMICINTERFACEMANAGEMENT] = 1,
-    [MPH_OUTPUTMIX] = 2,
-#ifdef USE_OUTPUTMIXEXT
-    [MPH_OUTPUTMIXEXT] = 3,
-#endif
-    [MPH_ENVIRONMENTALREVERB] = 4,
-    [MPH_EQUALIZER] = 5,
-    [MPH_PRESETREVERB] = 6,
-    [MPH_VIRTUALIZER] = 7,
-    [MPH_VOLUME] = 8,
-    [MPH_BASSBOOST] = 9,
-    [MPH_VISUALIZATION] = 10,
-#ifdef ANDROID
-    [MPH_ANDROIDEFFECT] = 11
-#endif
-#else
-#include "MPH_to_OutputMix.h"
-#endif
-};
-
-const signed char MPH_to_Vibra[MPH_MAX] = {
-#ifdef USE_DESIGNATED_INITIALIZERS
-    [0 ... MPH_MAX-1] = -1,
-    [MPH_OBJECT] = 0,
-    [MPH_DYNAMICINTERFACEMANAGEMENT] = 1,
-    [MPH_VIBRA] = 2
-#else
-#include "MPH_to_Vibra.h"
-#endif
-};
-
-const signed char MPH_to_MediaPlayer[MPH_MAX] = {
-#ifdef USE_DESIGNATED_INITIALIZERS
-    [0 ... MPH_MAX-1] = -1,
-    [MPH_XAOBJECT] = 0,
-    [MPH_XADYNAMICINTERFACEMANAGEMENT] = 1,
-    [MPH_XAPLAY] = 2,
-    [MPH_XASTREAMINFORMATION] = 3,
-    [MPH_XAVOLUME] = 4,
-    [MPH_XASEEK] = 5,
-    [MPH_XAPREFETCHSTATUS] = 6,
-#ifdef ANDROID
-    [MPH_ANDROIDBUFFERQUEUESOURCE] = 7,
-#endif
-#else
-#include "MPH_to_MediaPlayer.h"
-#endif
-};
diff -urN Original_4.4.4_r1/frameworks/wilhelm/tools/mphtogen/MPH_to.h AndroidSource/frameworks/wilhelm/tools/mphtogen/MPH_to.h
--- Original_4.4.4_r1/frameworks/wilhelm/tools/mphtogen/MPH_to.h	2016-01-29 15:12:36.627488000 +0900
+++ AndroidSource/frameworks/wilhelm/tools/mphtogen/MPH_to.h	1970-01-01 09:00:00.000000000 +0900
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-#ifndef __MPH_to_H
-#define __MPH_to_H
-
-/** \brief Map minimal perfect hash of an interface ID to its class index. */
-
-extern const signed char
-    MPH_to_3DGroup[MPH_MAX],
-    MPH_to_AudioPlayer[MPH_MAX],
-    MPH_to_AudioRecorder[MPH_MAX],
-    MPH_to_Engine[MPH_MAX],
-    MPH_to_LEDDevice[MPH_MAX],
-    MPH_to_Listener[MPH_MAX],
-    MPH_to_MetadataExtractor[MPH_MAX],
-    MPH_to_MidiPlayer[MPH_MAX],
-    MPH_to_OutputMix[MPH_MAX],
-    MPH_to_Vibra[MPH_MAX],
-    MPH_to_MediaPlayer[MPH_MAX];
-
-/** \brief Maximum number of interfaces on a single object. */
-#define MAX_INDEX 32
-
-#endif // !defined(__MPH_to_H)
