Merge "Extract crop hint rect from source wallpaper image"
diff --git a/Android.mk b/Android.mk
index 5983b30..ad164e20 100644
--- a/Android.mk
+++ b/Android.mk
@@ -187,6 +187,8 @@
 	core/java/android/hardware/location/IGeofenceHardware.aidl \
 	core/java/android/hardware/location/IGeofenceHardwareCallback.aidl \
 	core/java/android/hardware/location/IGeofenceHardwareMonitorCallback.aidl \
+	core/java/android/hardware/location/IContextHubCallback.aidl \
+	core/java/android/hardware/location/IContextHubService.aidl \
 	core/java/android/hardware/soundtrigger/IRecognitionStatusCallback.aidl \
 	core/java/android/hardware/usb/IUsbManager.aidl \
 	core/java/android/net/ICaptivePortal.aidl \
@@ -417,6 +419,7 @@
 	telephony/java/com/android/internal/telephony/ISub.aidl \
 	telephony/java/com/android/internal/telephony/ITelephony.aidl \
 	telephony/java/com/android/internal/telephony/ITelephonyDebug.aidl \
+	telephony/java/com/android/internal/telephony/ITelephonyDebugSubscriber.aidl \
 	telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl \
 	telephony/java/com/android/internal/telephony/IWapPushManager.aidl \
 	wifi/java/android/net/wifi/IWifiManager.aidl \
diff --git a/api/system-current.txt b/api/system-current.txt
index 2fc93fa..0d33503 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -15124,6 +15124,66 @@
 
 package android.hardware.location {
 
+  public class ContextHubInfo {
+    ctor public ContextHubInfo();
+    method public int describeContents();
+    method public int getId();
+    method public android.hardware.location.MemoryRegion[] getMemoryRegions();
+    method public java.lang.String getName();
+    method public float getPeakMips();
+    method public float getPeakPowerDrawMw();
+    method public int getPlatformVersion();
+    method public float getSleepPowerDrawMw();
+    method public int getStaticSwVersion();
+    method public float getStoppedPowerDrawMw();
+    method public int[] getSupportedSensors();
+    method public java.lang.String getToolchain();
+    method public int getToolchainVersion();
+    method public java.lang.String getVendor();
+    method public void setId(int);
+    method public void setMemoryRegions(android.hardware.location.MemoryRegion[]);
+    method public void setName(java.lang.String);
+    method public void setPeakMips(float);
+    method public void setPeakPowerDrawMw(float);
+    method public void setPlatformVersion(int);
+    method public void setSleepPowerDrawMw(float);
+    method public void setStaticSwVersion(int);
+    method public void setStoppedPowerDrawMw(float);
+    method public void setSupportedSensors(int[]);
+    method public void setToolchain(java.lang.String);
+    method public void setToolchainVersion(int);
+    method public void setVendor(java.lang.String);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.hardware.location.ContextHubInfo> CREATOR;
+  }
+
+  public final class ContextHubManager {
+    method public java.lang.Integer[] findNanoAppOnHub(int, android.hardware.location.NanoAppFilter);
+    method public int[] getContexthubHandles();
+    method public android.hardware.location.ContextHubInfo getContexthubInfo(int);
+    method public android.hardware.location.NanoAppInstanceInfo getNanoAppInstanceInfo(int);
+    method public int loadNanoApp(int, android.hardware.location.NanoApp);
+    method public int sendMessage(int, int, android.hardware.location.ContextHubMessage);
+    method public int unloadNanoApp(int);
+    field public static final int ANY_HUB = -1; // 0xffffffff
+    field public static final int MSG_DATA_SEND = 3; // 0x3
+    field public static final int MSG_LOAD_NANO_APP = 1; // 0x1
+    field public static final int MSG_UNLOAD_NANO_APP = 2; // 0x2
+  }
+
+  public class ContextHubMessage {
+    ctor public ContextHubMessage(int, int, byte[]);
+    method public int describeContents();
+    method public byte[] getData();
+    method public int getMsgType();
+    method public int getVersion();
+    method public void setMsgData(byte[]);
+    method public void setMsgType(int);
+    method public void setVersion(int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.hardware.location.ContextHubMessage> CREATOR;
+  }
+
   public final class GeofenceHardware {
     ctor public GeofenceHardware(android.hardware.location.IGeofenceHardware);
     method public boolean addGeofence(int, int, android.hardware.location.GeofenceHardwareRequest, android.hardware.location.GeofenceHardwareCallback);
@@ -15240,6 +15300,89 @@
     method public abstract void onMonitoringSystemChange(android.hardware.location.GeofenceHardwareMonitorEvent) throws android.os.RemoteException;
   }
 
+  public class MemoryRegion implements android.os.Parcelable {
+    ctor public MemoryRegion(android.os.Parcel);
+    method public int describeContents();
+    method public int getCapacityBytes();
+    method public int getFreeCapacityBytes();
+    method public boolean isExecutable();
+    method public boolean isReadable();
+    method public boolean isWritable();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.hardware.location.MemoryRegion> CREATOR;
+  }
+
+  public class NanoApp {
+    ctor public NanoApp();
+    method public int describeContents();
+    method public byte[] getAppBinary();
+    method public int getAppId();
+    method public int getAppVersion();
+    method public java.lang.String getName();
+    method public int getNeededExecMemBytes();
+    method public int getNeededReadMemBytes();
+    method public int[] getNeededSensors();
+    method public int getNeededWriteMemBytes();
+    method public int[] getOutputEvents();
+    method public java.lang.String getPublisher();
+    method public void setAppBinary(byte[]);
+    method public void setAppId(int);
+    method public void setAppVersion(int);
+    method public void setName(java.lang.String);
+    method public void setNeededExecMemBytes(int);
+    method public void setNeededReadMemBytes(int);
+    method public void setNeededSensors(int[]);
+    method public void setNeededWriteMemBytes(int);
+    method public void setOutputEvents(int[]);
+    method public void setPublisher(java.lang.String);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.hardware.location.NanoApp> CREATOR;
+  }
+
+  public class NanoAppFilter {
+    ctor public NanoAppFilter(long, int, int, long);
+    method public int describeContents();
+    method public boolean testMatch(android.hardware.location.NanoAppInstanceInfo);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int APP_ANY = -1; // 0xffffffff
+    field public static final android.os.Parcelable.Creator<android.hardware.location.NanoAppFilter> CREATOR;
+    field public static final int FLAGS_VERSION_ANY = -1; // 0xffffffff
+    field public static final int FLAGS_VERSION_GREAT_THAN = 2; // 0x2
+    field public static final int FLAGS_VERSION_LESS_THAN = 4; // 0x4
+    field public static final int FLAGS_VERSION_STRICTLY_EQUAL = 8; // 0x8
+    field public static final int HUB_ANY = -1; // 0xffffffff
+    field public static final int VENDOR_ANY = -1; // 0xffffffff
+  }
+
+  public class NanoAppInstanceInfo {
+    ctor public NanoAppInstanceInfo();
+    method public int describeContents();
+    method public int getAppId();
+    method public int getAppVersion();
+    method public int getContexthubId();
+    method public int getHandle();
+    method public java.lang.String getName();
+    method public int getNeededExecMemBytes();
+    method public int getNeededReadMemBytes();
+    method public int[] getNeededSensors();
+    method public int getNeededWriteMemBytes();
+    method public int[] getOutputEvents();
+    method public java.lang.String getPublisher();
+    method public void setAppId(int);
+    method public void setAppVersion(int);
+    method public void setContexthubId(int);
+    method public void setHandle(int);
+    method public void setName(java.lang.String);
+    method public void setNeededExecMemBytes(int);
+    method public void setNeededReadMemBytes(int);
+    method public void setNeededSensors(int[]);
+    method public void setNeededWriteMemBytes(int);
+    method public void setOutputEvents(int[]);
+    method public void setPublisher(java.lang.String);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.hardware.location.NanoAppInstanceInfo> CREATOR;
+  }
+
 }
 
 package android.hardware.radio {
diff --git a/core/java/android/hardware/location/ContextHubInfo.aidl b/core/java/android/hardware/location/ContextHubInfo.aidl
new file mode 100644
index 0000000..1a9221a
--- /dev/null
+++ b/core/java/android/hardware/location/ContextHubInfo.aidl
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.location;
+/*
+@hide
+*/
+parcelable ContextHubInfo;
diff --git a/core/java/android/hardware/location/ContextHubInfo.java b/core/java/android/hardware/location/ContextHubInfo.java
new file mode 100644
index 0000000..e47c541
--- /dev/null
+++ b/core/java/android/hardware/location/ContextHubInfo.java
@@ -0,0 +1,351 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.location;
+
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Arrays;
+
+/**
+ * @hide
+  */
+@SystemApi
+public class ContextHubInfo {
+    private int mId;
+    private String mName;
+    private String mVendor;
+    private String mToolchain;
+    private int mPlatformVersion;
+    private int mStaticSwVersion;
+    private int mToolchainVersion;
+    private float mPeakMips;
+    private float mStoppedPowerDrawMw;
+    private float mSleepPowerDrawMw;
+    private float mPeakPowerDrawMw;
+
+    private int[] mSupportedSensors;
+
+    private MemoryRegion[] mMemoryRegions;
+
+    public ContextHubInfo() {
+    }
+
+    /**
+     * get the context hub unique identifer
+     *
+     * @return int - unique system wide identifier
+     */
+    public int getId() {
+        return mId;
+    }
+
+    /**
+     * set the context hub unique identifer
+     *
+     * @param id - unique system wide identifier for the hub
+     */
+    public void setId(int id) {
+        mId = id;
+    }
+
+    /**
+     * get a string as a hub name
+     *
+     * @return String - a name for the hub
+     */
+    public String getName() {
+        return mName;
+    }
+
+    /**
+     * set a string as the hub name
+     *
+     * @param String - the name for the hub
+     */
+    public void setName(String name) {
+        mName = name;
+    }
+
+    /**
+     * get a string as the vendor name
+     *
+     * @return String - a name for the vendor
+     */
+    public String getVendor() {
+        return mVendor;
+    }
+
+    /**
+     * set a string as the vendor name
+     *
+     * @param String - a name for the vendor
+     */
+    public void setVendor(String vendor) {
+        mVendor = vendor;
+    }
+
+    /**
+     * get tool chain string
+     *
+     * @return String - description of the tool chain
+     */
+    public String getToolchain() {
+        return mToolchain;
+    }
+
+    /**
+     * set tool chain string
+     *
+     * @param String - description of the tool chain
+     */
+    public void setToolchain(String toolchain) {
+        mToolchain = toolchain;
+    }
+
+    /**
+     * get platform version
+     *
+     * @return int - platform version number
+     */
+    public int getPlatformVersion() {
+        return mPlatformVersion;
+    }
+
+    /**
+     * set platform version
+     *
+     * @param platformVersion - platform version number
+     */
+    public void setPlatformVersion(int platformVersion) {
+        mPlatformVersion = platformVersion;
+    }
+
+    /**
+     * get static platform version number
+     *
+     * @return int - platform version number
+     */
+    public int getStaticSwVersion() {
+        return mStaticSwVersion;
+    }
+
+    /**
+     * set platform software version
+     *
+     * @param staticSwVersion - platform static s/w version number
+     */
+    public void setStaticSwVersion(int staticSwVersion) {
+        mStaticSwVersion = staticSwVersion;
+    }
+
+    /**
+     * get the tool chain version
+     *
+     * @return int - the tool chain version
+     */
+    public int getToolchainVersion() {
+        return mToolchainVersion;
+    }
+
+    /**
+     * set the tool chain version number
+     *
+     * @param toolchainVersion - tool chain version number
+     */
+    public void setToolchainVersion(int toolchainVersion) {
+        mToolchainVersion = toolchainVersion;
+    }
+
+    /**
+     * get the peak processing mips the hub can support
+     *
+     * @return float - peak MIPS that this hub can deliver
+     */
+    public float getPeakMips() {
+        return mPeakMips;
+    }
+
+    /**
+     * set the peak mips that this hub can support
+     *
+     * @param peakMips - peak mips this hub can deliver
+     */
+    public void setPeakMips(float peakMips) {
+        mPeakMips = peakMips;
+    }
+
+    /**
+     * get the stopped power draw in milliwatts
+     * This assumes that the hub enter a stopped state - which is
+     * different from the sleep state. Latencies on exiting the
+     * sleep state are typically higher and expect to be in multiple
+     * milliseconds.
+     *
+     * @return float - power draw by the hub in stopped state
+     */
+    public float getStoppedPowerDrawMw() {
+        return mStoppedPowerDrawMw;
+    }
+
+    /**
+     * Set the power consumed by the hub in stopped state
+     *
+     * @param stoppedPowerDrawMw - stopped power in milli watts
+     */
+    public void setStoppedPowerDrawMw(float stoppedPowerDrawMw) {
+        mStoppedPowerDrawMw = stoppedPowerDrawMw;
+    }
+
+    /**
+     * get the power draw of the hub in sleep mode. This assumes
+     * that the hub supports a sleep mode in which the power draw is
+     * lower than the power consumed when the hub is actively
+     * processing. As a guideline, assume that the hub should be
+     * able to enter sleep mode if it knows reliably on completion
+     * of some task that the next interrupt/scheduled work item is
+     * at least 250 milliseconds later.
+     *
+     * @return float - sleep power draw in milli watts
+     */
+    public float getSleepPowerDrawMw() {
+        return mSleepPowerDrawMw;
+    }
+
+    /**
+     * Set the sleep power draw in milliwatts
+     *
+     * @param sleepPowerDrawMw - sleep power draw in milliwatts.
+     */
+    public void setSleepPowerDrawMw(float sleepPowerDrawMw) {
+        mSleepPowerDrawMw = sleepPowerDrawMw;
+    }
+
+    /**
+     * get the peak powe draw of the hub. This is the power consumed
+     * by the hub at maximum load.
+     *
+     * @return float - peak power draw
+     */
+    public float getPeakPowerDrawMw() {
+        return mPeakPowerDrawMw;
+    }
+
+    /**
+     * set the peak power draw of the hub
+     *
+     * @param peakPowerDrawMw - peak power draw of the hub in
+     *                        milliwatts.
+     */
+    public void setPeakPowerDrawMw(float peakPowerDrawMw) {
+        mPeakPowerDrawMw = peakPowerDrawMw;
+    }
+
+    /**
+     * get the sensors supported by this hub
+     *
+     * @return int[] - all the supported sensors on this hub
+     *
+     * @see ContextHubManager
+     */
+    public int[] getSupportedSensors() {
+        return Arrays.copyOf(mSupportedSensors, mSupportedSensors.length);
+    }
+
+    /**
+     * get the various memory regions on this hub
+     *
+     * @return MemoryRegion[] - all the memory regions on this hub
+     *
+     * @see MemoryRegion
+     */
+    public MemoryRegion[] getMemoryRegions() {
+        return Arrays.copyOf(mMemoryRegions, mMemoryRegions.length);
+    }
+
+    /**
+     * set the supported sensors on this hub
+     *
+     * @param supportedSensors - supported sensors on this hub
+     */
+    public void setSupportedSensors(int[] supportedSensors) {
+        mSupportedSensors = Arrays.copyOf(supportedSensors, supportedSensors.length);
+    }
+
+    /**
+     * set memory regions for this hub
+     *
+     * @param memoryRegions - memory regions information
+     *
+     * @see MemoryRegion
+     */
+    public void setMemoryRegions(MemoryRegion[] memoryRegions) {
+        mMemoryRegions = Arrays.copyOf(memoryRegions, memoryRegions.length);
+    }
+
+    private ContextHubInfo(Parcel in) {
+        mId = in.readInt();
+        mName = in.readString();
+        mVendor = in.readString();
+        mToolchain = in.readString();
+        mPlatformVersion = in.readInt();
+        mToolchainVersion = in.readInt();
+        mStaticSwVersion = in.readInt();
+        mPeakMips = in.readFloat();
+        mStoppedPowerDrawMw = in.readFloat();
+        mSleepPowerDrawMw = in.readFloat();
+        mPeakPowerDrawMw = in.readFloat();
+
+        int numSupportedSensors = in.readInt();
+        mSupportedSensors = new int[numSupportedSensors];
+        in.readIntArray(mSupportedSensors);
+        mMemoryRegions = in.createTypedArray(MemoryRegion.CREATOR);
+    }
+
+    public int describeContents() {
+        return 0;
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(mId);
+        out.writeString(mName);
+        out.writeString(mVendor);
+        out.writeString(mToolchain);
+        out.writeInt(mPlatformVersion);
+        out.writeInt(mToolchainVersion);
+        out.writeInt(mStaticSwVersion);
+        out.writeFloat(mPeakMips);
+        out.writeFloat(mStoppedPowerDrawMw);
+        out.writeFloat(mSleepPowerDrawMw);
+        out.writeFloat(mPeakPowerDrawMw);
+
+        out.writeInt(mSupportedSensors.length);
+        out.writeIntArray(mSupportedSensors);
+        out.writeTypedArray(mMemoryRegions, flags);
+    }
+
+    public static final Parcelable.Creator<ContextHubInfo> CREATOR
+            = new Parcelable.Creator<ContextHubInfo>() {
+        public ContextHubInfo createFromParcel(Parcel in) {
+            return new ContextHubInfo(in);
+        }
+
+        public ContextHubInfo[] newArray(int size) {
+            return new ContextHubInfo[size];
+        }
+    };
+}
diff --git a/core/java/android/hardware/location/ContextHubManager.java b/core/java/android/hardware/location/ContextHubManager.java
new file mode 100644
index 0000000..301b2e4
--- /dev/null
+++ b/core/java/android/hardware/location/ContextHubManager.java
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.location;
+
+import android.annotation.SystemApi;
+import android.hardware.location.NanoAppInstanceInfo;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.ServiceConnection;
+import android.Manifest;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * A class that exposes the Context hubs on a device to
+ * applicaions.
+ *
+ * Please not that this class is not expected to be used by
+ * unbundled applications. Also, calling applications are
+ * expected to have LOCTION_HARDWARE premissions to use this
+ * class.
+ *
+ * @hide
+ */
+@SystemApi
+public final class ContextHubManager {
+
+    private static final String TAG = "ContextHubManager";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    private static final String HARDWARE_PERMISSION = Manifest.permission.LOCATION_HARDWARE;
+    private static final String ENFORCE_HW_PERMISSION_MESSAGE = "Permission '"
+            + HARDWARE_PERMISSION + "' not granted to access ContextHub Hardware";
+
+    private Context mContext;
+    private IContextHubService mContextHubService;
+    private boolean mContextHubConnected;
+
+    /**
+     * A special context hub identifer meaning any possible hub on
+     * the system.
+     */
+    public static final int ANY_HUB       = -1;
+    /**
+     * A constant denoting a message to load a a Nano App
+     */
+    public static final int MSG_LOAD_NANO_APP   = 1;
+    /**
+     * A constant denoting a message to unload a a Nano App
+     */
+    public static final int MSG_UNLOAD_NANO_APP = 2;
+    /**
+     * A constant denoting a message to send a message
+     */
+    public static final int MSG_DATA_SEND       = 3;
+
+
+    /**
+     * Get a handle to all the context hubs in the system
+     * @return array of context hub handles
+     */
+    public int[] getContexthubHandles() {
+        int[] retVal = null;
+        if(mContextHubConnected) {
+            try {
+                retVal = mContextHubService.getContextHubHandles();
+            }catch (RemoteException e) {
+                Log.e (TAG, "Could not fetch context hub handles :" + e.toString());
+            }
+        }
+        return retVal;
+    }
+
+    /**
+     * Get more information about a specific hub.
+     *
+     * @param contexthubHandle Handle of context hub
+     *
+     * @return ContextHubInfo  returned information about the hub
+     *
+     * @see ContextHubInfo
+     */
+    public ContextHubInfo getContexthubInfo(int contexthubHandle) {
+        ContextHubInfo retVal = null;
+        if(mContextHubConnected) {
+            try {
+                retVal = mContextHubService.getContextHubInfo(contexthubHandle);
+            }catch (RemoteException e) {
+                Log.e (TAG, "Could not fetch context hub info :" + e.toString());
+            }
+        }
+
+        return(retVal);
+    }
+
+    /**
+     * Load a nanoapp on a specified context hub
+     *
+     * @param hubHandle handle of context hub to load the app on.
+     * @param app the nanoApp to load on the hub
+     *
+     * @return int nanoAppInstance of the loaded nanoApp on success,
+     *         -1 otherwise
+     *
+     * @see NanoApp
+     */
+    public int loadNanoApp(int hubHandle, NanoApp app) {
+        int retVal = -1;
+
+        if(mContextHubConnected) {
+            try {
+                retVal = mContextHubService.loadNanoApp(hubHandle, app);
+            }catch (RemoteException e) {
+                Log.e (TAG, "Could not fetch load nanoApp :" + e.toString());
+            }
+        }
+
+        return retVal;
+    }
+
+    /**
+     * Unload a specified nanoApp
+     *
+     * @param nanoAppInstanceHandle handle of the nanoApp to load
+     *
+     * @return int  0 on success, -1 otherewise
+     */
+    public int unloadNanoApp(int nanoAppInstanceHandle) {
+        int retVal = -1;
+
+        if(mContextHubConnected) {
+            try {
+                retVal = mContextHubService.unloadNanoApp(nanoAppInstanceHandle);
+            }catch (RemoteException e) {
+                Log.e (TAG, "Could not fetch unload nanoApp :" + e.toString());
+            }
+        }
+
+        return retVal;
+    }
+
+    /**
+     * get information about the nano app instance
+     *
+     * @param nanoAppInstanceHandle handle of the nanoAppInstance
+     *
+     * @return NanoAppInstanceInfo Inforamtion about the nano app
+     *         instance.
+     *
+     * @see NanoAppInstanceInfo
+     */
+    public NanoAppInstanceInfo getNanoAppInstanceInfo(int nanoAppInstanceHandle) {
+        NanoAppInstanceInfo retVal = null;
+
+        if(mContextHubConnected) {
+            try {
+                retVal = mContextHubService.getNanoAppInstanceInfo(nanoAppInstanceHandle);
+            }catch (RemoteException e) {
+                Log.e (TAG, "Could not fetch nanoApp info :" + e.toString());
+            }
+        }
+
+        return retVal;
+    }
+
+    /**
+     * Find a specified nano app on the system
+     *
+     * @param hubHandle handle of hub to search for nano app
+     * @param filter filter specifying the search criteria for app
+     *
+     * @see NanoAppFilter
+     *
+     * @return Integer[] Array of handles to any found nano apps
+     */
+    public Integer[] findNanoAppOnHub(int hubHandle, NanoAppFilter filter) {
+        int[] temp;
+        Integer[] retVal = null;
+
+        if(mContextHubConnected) {
+            try {
+                temp = mContextHubService.findNanoAppOnHub(hubHandle, filter);
+                retVal = new Integer[temp.length];
+                for (int i = 0; i < temp.length; i++) {
+                    retVal[i] = temp[i];
+                }
+            }catch (RemoteException e) {
+                Log.e (TAG, "Could not query nanoApp instance :" + e.toString());
+            }
+        }
+
+        return retVal;
+    }
+
+    /**
+     * Send a message to a spcific nano app instance on a context
+     * hub
+     *
+     *
+     * @param hubHandle handle of the hub to send the message to
+     * @param nanoAppHandle  handle of the nano app to send to
+     * @param msg Message to be sent
+     *
+     * @see ContextHubMessage
+     *
+     * @return int 0 on success, -1 otherwise
+     */
+    public int sendMessage(int hubHandle, int nanoAppHandle, ContextHubMessage msg) {
+        int retVal = -1;
+
+        if(mContextHubConnected) {
+            try {
+                retVal = mContextHubService.sendMessage(hubHandle, nanoAppHandle, msg);
+            }catch (RemoteException e) {
+                Log.e (TAG, "Could not fetch send message :" + e.toString());
+            }
+        }
+
+        return retVal;
+    }
+
+    private void checkPermissions() {
+        mContext.enforceCallingPermission(HARDWARE_PERMISSION, ENFORCE_HW_PERMISSION_MESSAGE);
+    }
+
+    private IContextHubCallback.Stub mClientCallback = new IContextHubCallback.Stub() {
+        @Override
+        public void onMessageReceipt(int hubId, int nanoAppId, ContextHubMessage msg) throws RemoteException {
+
+        }
+    };
+
+    private ContextHubManager(Context context) {
+        checkPermissions();
+        mContext = context;
+        mContextHubConnected = false;
+    }
+
+    private ServiceConnection mServiceConnection = new ServiceConnection() {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            mContextHubService = IContextHubService.Stub.asInterface(service);
+            mContextHubConnected = true;
+
+            // Register our Callback
+            try {
+                mContextHubService.registerCallBack(mClientCallback);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Could not register callback with context hub service :" + e.toString());
+            }
+            Log.d(TAG, "contexthub manager connected to " + name.toString());
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            mContextHubService = null;
+            mContextHubConnected = false;
+            Log.d(TAG, "contexthub manager disconnected from " + name.toString());
+        }
+    };
+
+}
diff --git a/core/java/android/hardware/location/ContextHubMessage.aidl b/core/java/android/hardware/location/ContextHubMessage.aidl
new file mode 100644
index 0000000..915f1ec
--- /dev/null
+++ b/core/java/android/hardware/location/ContextHubMessage.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.location;
+/*
+@hide
+*/
+parcelable ContextHubMessage;
+
diff --git a/core/java/android/hardware/location/ContextHubMessage.java b/core/java/android/hardware/location/ContextHubMessage.java
new file mode 100644
index 0000000..954e97d
--- /dev/null
+++ b/core/java/android/hardware/location/ContextHubMessage.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.location;
+
+
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Arrays;
+
+/**
+ * @hide
+ */
+@SystemApi
+public class ContextHubMessage {
+    private int mType;
+    private int mVersion;
+    private byte[]mData;
+
+    /**
+     * Get the message type
+     *
+     * @return int - message type
+     */
+    public int getMsgType() {
+        return mType;
+    }
+
+    /**
+     * get message version
+     *
+     * @return int - message version
+     */
+    public int getVersion() {
+        return mVersion;
+    }
+
+    /**
+     * get message data
+     *
+     * @return byte[] - message data buffer
+     */
+    public byte[] getData() {
+        return Arrays.copyOf(mData, mData.length);
+    }
+
+    /**
+     * set message type
+     *
+     * @param msgType - message type
+     */
+    public void setMsgType(int msgType) {
+        mType = msgType;
+    }
+
+    /**
+     * Set message version
+     *
+     * @param version - message version
+     */
+    public void setVersion(int version) {
+        mVersion = version;
+    }
+
+    /**
+     * set message data
+     *
+     * @param data - message buffer
+     */
+    public void setMsgData(byte[] data) {
+        mData = Arrays.copyOf(data, data.length);
+    }
+
+    /**
+     * Constructor for a context hub message
+     *
+     * @param msgType - message type
+     * @param version - version
+     * @param data    - message buffer
+     */
+    public ContextHubMessage(int msgType, int version, byte[] data) {
+        mType = msgType;
+        mVersion = version;
+        mData = Arrays.copyOf(data, data.length);
+    }
+
+    public int describeContents() {
+        return 0;
+    }
+
+    private ContextHubMessage(Parcel in) {
+        mType = in.readInt();
+        mVersion = in.readInt();
+        byte[] byteBuffer = new byte[in.readInt()];
+        in.readByteArray(byteBuffer);
+    }
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(mType);
+        out.writeInt(mVersion);
+        out.writeInt(mData.length);
+        out.writeByteArray(mData);
+    }
+
+    public static final Parcelable.Creator<ContextHubMessage> CREATOR
+            = new Parcelable.Creator<ContextHubMessage>() {
+        public ContextHubMessage createFromParcel(Parcel in) {
+            return new ContextHubMessage(in);
+        }
+
+        public ContextHubMessage[] newArray(int size) {
+            return new ContextHubMessage[size];
+        }
+    };
+}
diff --git a/core/java/android/hardware/location/ContextHubService.java b/core/java/android/hardware/location/ContextHubService.java
new file mode 100644
index 0000000..a2a13c6
--- /dev/null
+++ b/core/java/android/hardware/location/ContextHubService.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.location;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * @hide
+ */
+public class ContextHubService extends Service {
+
+    private static final String TAG = "ContextHubService";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private static ContextHubService sSingletonInstance;
+    private static final Object sSingletonInstanceLock = new Object();
+
+    private HashMap<Integer, ContextHubInfo> mHubHash;
+    private HashMap<Integer, NanoAppInstanceInfo> mNanoAppHash;
+    private ContextHubInfo[] mContexthubInfo;
+
+
+    private native int nativeSendMessage(int[] header, byte[] data);
+    private native ContextHubInfo[] nativeInitialize();
+
+    private int onMessageReceipt(int[] header, byte[] data) {
+        return 0;
+    }
+    private void initialize() {
+        mContexthubInfo = nativeInitialize();
+
+        mHubHash = new HashMap<Integer, ContextHubInfo>();
+
+        for (int i = 0; i < mContexthubInfo.length; i++) {
+            mHubHash.put(i + 1, mContexthubInfo[i]); // Avoiding zero
+        }
+    }
+
+    private ContextHubService(Context context) {
+        initialize();
+        Log.d(TAG, "Created from " + context.toString());
+    }
+
+    public static ContextHubService getInstance(Context context) {
+        synchronized (sSingletonInstanceLock) {
+            if (sSingletonInstance == null) {
+                sSingletonInstance = new ContextHubService(context);
+            }
+            return sSingletonInstance;
+        }
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;
+    }
+
+    private final IContextHubService.Stub mBinder = new IContextHubService.Stub() {
+
+        private  IContextHubCallback callback;
+
+        @Override
+        public int registerCallBack(IContextHubCallback callback) throws RemoteException{
+            this.callback = callback;
+            return 0;
+        }
+
+        @Override
+        public int[] getContextHubHandles() throws RemoteException {
+            int [] returnArray = new int[mHubHash.size()];
+            int i = 0;
+            for (int key : mHubHash.keySet()) {
+                // Add any filtering here
+                returnArray[i] = key;
+                i++;
+            }
+            return returnArray;
+        }
+
+        @Override
+        public ContextHubInfo getContextHubInfo(int contexthubHandle) throws RemoteException {
+            return mHubHash.get(contexthubHandle);
+        }
+
+        @Override
+        public int loadNanoApp(int hubHandle, NanoApp app) throws RemoteException {
+            if (!mHubHash.containsKey(hubHandle)) {
+                return -1;
+            } else {
+                // Call Native interface here
+                int[] msgHeader = new int[8];
+                msgHeader[0] = ContextHubManager.MSG_LOAD_NANO_APP;
+                msgHeader[1] = app.getAppId();
+                msgHeader[2] = app.getAppVersion();
+                msgHeader[3] = 0; // LOADING_HINTS
+                msgHeader[4] = hubHandle;
+
+                int handle = nativeSendMessage(msgHeader, app.getAppBinary());
+
+                // if successful, add an entry to mNanoAppHash
+
+                if(handle > 0) {
+                    return 0;
+                } else {
+
+                    return -1;
+                }
+            }
+        }
+
+        @Override
+        public int unloadNanoApp(int nanoAppInstanceHandle) throws RemoteException {
+            if(!mNanoAppHash.containsKey(nanoAppInstanceHandle)) {
+                return -1;
+            } else {
+                NanoAppInstanceInfo info = mNanoAppHash.get(nanoAppInstanceHandle);
+                // Call Native interface here
+                int[] msgHeader = new int[8];
+                msgHeader[0] = ContextHubManager.MSG_UNLOAD_NANO_APP;
+                msgHeader[1] = info.getContexthubId();
+                msgHeader[2] = info.getHandle();
+
+                int result = nativeSendMessage(msgHeader, null);
+                // if successful, remove the entry in mNanoAppHash
+                if(result == 0) {
+                    mNanoAppHash.remove(nanoAppInstanceHandle);
+                }
+                return(result);
+            }
+        }
+
+        @Override
+        public NanoAppInstanceInfo getNanoAppInstanceInfo(int nanoAppInstanceHandle) throws RemoteException {
+            // This assumes that all the nanoAppInfo is current. This is reasonable
+            // for the use cases for tightly controlled nanoApps.
+            //
+            if(!mNanoAppHash.containsKey(nanoAppInstanceHandle)) {
+                return(mNanoAppHash.get(nanoAppInstanceHandle));
+            } else {
+                return null;
+            }
+        }
+
+        @Override
+        public int[] findNanoAppOnHub(int hubHandle, NanoAppFilter filter) throws RemoteException {
+            ArrayList<Integer> foundInstances = new ArrayList<Integer>();
+
+            for(Integer nanoAppInstance : mNanoAppHash.keySet()) {
+                NanoAppInstanceInfo info = mNanoAppHash.get(nanoAppInstance);
+
+                if(filter.testMatch(info)){
+                    foundInstances.add(nanoAppInstance);
+                }
+            }
+
+            int[] retArray = new int[foundInstances.size()];
+            for (int i = 0; i < foundInstances.size(); i++) {
+                retArray[i] = foundInstances.get(i).intValue();
+            }
+
+            return retArray;
+        }
+
+        @Override
+        public int sendMessage(int hubHandle, int nanoAppHandle, ContextHubMessage msg) throws RemoteException {
+            int[] msgHeader = new int[8];
+            msgHeader[0] = ContextHubManager.MSG_DATA_SEND;
+            msgHeader[1] = hubHandle;
+            msgHeader[2] = nanoAppHandle;
+            msgHeader[3] = msg.getMsgType();
+            msgHeader[4] = msg.getVersion();
+
+            return (nativeSendMessage(msgHeader, msg.getData()));
+        }
+    };
+}
diff --git a/core/java/android/hardware/location/IContextHubCallback.aidl b/core/java/android/hardware/location/IContextHubCallback.aidl
new file mode 100644
index 0000000..45b1ef4
--- /dev/null
+++ b/core/java/android/hardware/location/IContextHubCallback.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.location;
+
+import android.hardware.location.ContextHubMessage;
+
+/** @hide */
+oneway interface IContextHubCallback {
+    void onMessageReceipt(int hubId, int nanoAppId, in ContextHubMessage msg);
+}
diff --git a/core/java/android/hardware/location/IContextHubService.aidl b/core/java/android/hardware/location/IContextHubService.aidl
new file mode 100644
index 0000000..b2db0b2
--- /dev/null
+++ b/core/java/android/hardware/location/IContextHubService.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.location;
+
+// Declare any non-default types here with import statements
+import android.hardware.location.ContextHubMessage;
+import android.hardware.location.ContextHubInfo;
+import android.hardware.location.NanoApp;
+import android.hardware.location.NanoAppInstanceInfo;
+import android.hardware.location.NanoAppFilter;
+import android.hardware.location.IContextHubCallback;
+
+/** @hide */
+interface IContextHubService {
+
+    // register a callback to receive messages
+    int registerCallBack(in IContextHubCallback callback);
+
+    // Gets a list of available context hub handles
+    int[] getContextHubHandles();
+
+    // Get the properties of a hub
+    ContextHubInfo getContextHubInfo(int contextHubHandle);
+
+    // Load a nanoapp on a specified context hub
+    int loadNanoApp(int hubHandle, in NanoApp app);
+
+    // Unload a nanoapp instance
+    int unloadNanoApp(int nanoAppInstanceHandle);
+
+    // get information about a nanoAppInstance
+    NanoAppInstanceInfo getNanoAppInstanceInfo(int nanoAppInstanceHandle);
+
+    // find all nanoApp instances matching some filter
+    int[] findNanoAppOnHub(int hubHandle, in NanoAppFilter filter);
+
+    // send a message to a nanoApp
+    int sendMessage(int hubHandle, int nanoAppHandle, in ContextHubMessage msg);
+}
diff --git a/core/java/android/hardware/location/MemoryRegion.java b/core/java/android/hardware/location/MemoryRegion.java
new file mode 100644
index 0000000..e8c7615
--- /dev/null
+++ b/core/java/android/hardware/location/MemoryRegion.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.location;
+
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * @hide
+ */
+
+@SystemApi
+public class MemoryRegion implements Parcelable{
+
+    private int mSizeBytes;
+    private int mSizeBytesFree;
+    private boolean mIsReadable;
+    private boolean mIsWritable;
+    private boolean mIsExecutable;
+
+    /**
+     * get the capacity of the memory region in bytes
+     *
+     * @return int - the memory capacity in bytes
+     */
+    public int getCapacityBytes() {
+        return mSizeBytes;
+    }
+
+    /**
+     * get the free capacity of the memory region in bytes
+     *
+     * @return int - free bytes
+     */
+    public int getFreeCapacityBytes() {
+        return mSizeBytesFree;
+    }
+
+    /**
+     * Is the memory readable
+     *
+     * @return boolean - true if memory is readable, false otherwise
+     */
+    public boolean isReadable() {
+        return mIsReadable;
+    }
+
+    /**
+     * Is the memory writable
+     *
+     * @return boolean - true if memory is writable, false otherwise
+     */
+    public boolean isWritable() {
+        return mIsWritable;
+    }
+
+    /**
+     * Is the memory executable
+     *
+     * @return boolean - true if memory is executable, false
+     *         otherwise
+     */
+    public boolean isExecutable() {
+        return mIsExecutable;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mSizeBytes);
+        dest.writeInt(mSizeBytesFree);
+        dest.writeInt(mIsReadable ? 1 : 0);
+        dest.writeInt(mIsWritable ? 1 : 0);
+        dest.writeInt(mIsExecutable ? 1 : 0);
+    }
+
+    public MemoryRegion(Parcel source) {
+        mSizeBytes = source.readInt();
+        mSizeBytesFree = source.readInt();
+        mIsReadable = source.readInt() != 0;
+        mIsWritable = source.readInt() != 0;
+        mIsExecutable = source.readInt() != 0;
+    }
+
+    public static final Parcelable.Creator<MemoryRegion> CREATOR
+            = new Parcelable.Creator<MemoryRegion>() {
+        public MemoryRegion createFromParcel(Parcel in) {
+            return new MemoryRegion(in);
+        }
+
+        public MemoryRegion[] newArray(int size) {
+            return new MemoryRegion[size];
+        }
+    };
+
+}
diff --git a/core/java/android/hardware/location/NanoApp.aidl b/core/java/android/hardware/location/NanoApp.aidl
new file mode 100644
index 0000000..d32c44a
--- /dev/null
+++ b/core/java/android/hardware/location/NanoApp.aidl
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.location;
+/*
+@hide
+*/
+parcelable NanoApp;
diff --git a/core/java/android/hardware/location/NanoApp.java b/core/java/android/hardware/location/NanoApp.java
new file mode 100644
index 0000000..36d181f
--- /dev/null
+++ b/core/java/android/hardware/location/NanoApp.java
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.location;
+
+
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A class describing nano apps.
+ * A nano app is a piece of executable code that can be
+ * downloaded onto a specific architecture. These are targtted
+ * for low power compute domains on a device.
+ *
+ * Nano apps are expected to be used only by bundled apps only
+ * at this time.
+ *
+ * @hide
+ */
+@SystemApi
+public class NanoApp {
+    private String mPublisher;
+    private String mName;
+
+    private int mAppId;
+    private int mAppVersion;
+
+    private int mNeededReadMemBytes;
+    private int mNeededWriteMemBytes;
+    private int mNeededExecMemBytes;
+
+    private int[] mNeededSensors;
+    private int[] mOutputEvents;
+    private byte[] mAppBinary;
+
+    public NanoApp() {
+    }
+
+    /**
+     * Set the publisher name
+     *
+     * @param publisher name of the publisher of this nano app
+     */
+    public void setPublisher(String publisher) {
+        mPublisher = publisher;
+    }
+
+    /**
+     * set the name of the app
+     *
+     * @param name   name of the app
+     */
+    public void setName(String name) {
+        mName = name;
+    }
+
+    /**
+     * set the app identifier
+     *
+     * @param appId  add identifier
+     */
+    public void setAppId(int appId) {
+        mAppId = appId;
+    }
+
+    /**
+     * Set the app version
+     *
+     * @param appVersion app version
+     */
+    public void setAppVersion(int appVersion) {
+        mAppVersion = appVersion;
+    }
+
+    /**
+     * set memory needed as read only
+     *
+     * @param neededReadMemBytes
+     *               read only memory needed in bytes
+     */
+    public void setNeededReadMemBytes(int neededReadMemBytes) {
+        mNeededReadMemBytes = neededReadMemBytes;
+    }
+
+    /**
+     * set writable memory needed in bytes
+     *
+     * @param neededWriteMemBytes
+     *               writable memory needed in bytes
+     */
+    public void setNeededWriteMemBytes(int neededWriteMemBytes) {
+        mNeededWriteMemBytes = neededWriteMemBytes;
+    }
+
+    /**
+     * set executable memory needed
+     *
+     * @param neededExecMemBytes
+     *               executable memory needed in bytes
+     */
+    public void setNeededExecMemBytes(int neededExecMemBytes) {
+        mNeededExecMemBytes = neededExecMemBytes;
+    }
+
+    /**
+     * set the sensors needed for this app
+     *
+     * @param neededSensors
+     *               needed Sensors
+     */
+    public void setNeededSensors(int[] neededSensors) {
+        mNeededSensors = neededSensors;
+    }
+
+    public void setOutputEvents(int[] outputEvents) {
+        mOutputEvents = outputEvents;
+    }
+
+    /**
+     * set output events returned by the nano app
+     *
+     * @param appBinary generated events
+     */
+    public void setAppBinary(byte[] appBinary) {
+        mAppBinary = appBinary;
+    }
+
+
+    /**
+     * get the publisher name
+     *
+     * @return publisher name
+     */
+    public String getPublisher() {
+      return mPublisher;
+    }
+
+    /**
+     * get the name of the app
+     *
+     * @return app name
+     */
+    public String getName() {
+    return mName;
+    }
+
+    /**
+     * get the identifier of the app
+     *
+     * @return identifier for this app
+     */
+    public int getAppId() {
+      return mAppId;
+    }
+
+    /**
+     * get the app version
+     *
+     * @return app version
+     */
+    public int getAppVersion() {
+      return mAppVersion;
+    }
+
+    /**
+     * get the ammount of readable memory needed by this app
+     *
+     * @return readable memory needed in bytes
+     */
+    public int getNeededReadMemBytes() {
+      return mNeededReadMemBytes;
+    }
+
+    /**
+     * get the ammount og writable memory needed in bytes
+     *
+     * @return writable memory needed in bytes
+     */
+    public int getNeededWriteMemBytes() {
+      return mNeededWriteMemBytes;
+    }
+
+    /**
+     * executable memory needed in bytes
+     *
+     * @return executable memory needed in bytes
+     */
+    public int getNeededExecMemBytes() {
+      return mNeededExecMemBytes;
+    }
+
+    /**
+     * get the sensors needed by this app
+     *
+     * @return sensors needed
+     */
+    public int[] getNeededSensors() {
+      return mNeededSensors;
+    }
+
+    /**
+     * get the events generated by this app
+     *
+     * @return generated events
+     */
+    public int[] getOutputEvents() {
+      return mOutputEvents;
+    }
+
+    /**
+     * get the binary for this app
+     *
+     * @return app binary
+     */
+    public byte[] getAppBinary() {
+      return mAppBinary;
+    }
+
+    private NanoApp(Parcel in) {
+        mPublisher = in.readString();
+        mName = in.readString();
+
+        mAppId = in.readInt();
+        mAppVersion = in.readInt();
+        mNeededReadMemBytes = in.readInt();
+        mNeededWriteMemBytes = in.readInt();
+        mNeededExecMemBytes = in.readInt();
+
+        int mNeededSensorsLength = in.readInt();
+        mNeededSensors = new int[mNeededSensorsLength];
+        in.readIntArray(mNeededSensors);
+
+        int mOutputEventsLength = in.readInt();
+        mOutputEvents = new int[mOutputEventsLength];
+        in.readIntArray(mOutputEvents);
+
+        int binaryLength = in.readInt();
+        mAppBinary = new byte[binaryLength];
+        in.readByteArray(mAppBinary);
+    }
+
+    public int describeContents() {
+        return 0;
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(mPublisher);
+        out.writeString(mName);
+        out.writeInt(mAppId);
+        out.writeInt(mAppVersion);
+        out.writeInt(mNeededReadMemBytes);
+        out.writeInt(mNeededWriteMemBytes);
+        out.writeInt(mNeededExecMemBytes);
+
+        out.writeInt(mNeededSensors.length);
+        out.writeIntArray(mNeededSensors);
+
+        out.writeInt(mOutputEvents.length);
+        out.writeIntArray(mOutputEvents);
+
+        out.writeInt(mAppBinary.length);
+        out.writeByteArray(mAppBinary);
+    }
+
+    public static final Parcelable.Creator<NanoApp> CREATOR
+            = new Parcelable.Creator<NanoApp>() {
+        public NanoApp createFromParcel(Parcel in) {
+            return new NanoApp(in);
+        }
+
+        public NanoApp[] newArray(int size) {
+            return new NanoApp[size];
+        }
+    };
+}
diff --git a/core/java/android/hardware/location/NanoAppFilter.aidl b/core/java/android/hardware/location/NanoAppFilter.aidl
new file mode 100644
index 0000000..cc6d475
--- /dev/null
+++ b/core/java/android/hardware/location/NanoAppFilter.aidl
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.location;
+/*
+@hide
+*/
+parcelable NanoAppFilter;
diff --git a/core/java/android/hardware/location/NanoAppFilter.java b/core/java/android/hardware/location/NanoAppFilter.java
new file mode 100644
index 0000000..ac341e4
--- /dev/null
+++ b/core/java/android/hardware/location/NanoAppFilter.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.location;
+
+
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * @hide
+ */
+@SystemApi
+public class NanoAppFilter {
+
+    // The appId, can be set to APP_ID_ANY
+    private long mAppId;
+
+    // Version to filter apps
+    private int mAppVersion;
+
+    // filtering spec for version
+    private int mVersionRestrictionMask;
+
+    // If APP_ID is any, then a match is performef with the vendor mask
+    private long mAppIdVendorMask;
+
+    // Id of the context hub this instance is expected on
+    private int mContextHubId;
+
+    /**
+     * Flag indicating any version. With this flag set, all versions shall match provided version.
+     */
+    public static final int FLAGS_VERSION_ANY = -1;
+    /**
+     * If this flag is set, only versions strictly greater than the version specified shall match.
+     */
+    public static final int FLAGS_VERSION_GREAT_THAN  = 2;
+    /**
+     * If this flag is set, only versions strictly less than the version specified shall match.
+     */
+    public static final int FLAGS_VERSION_LESS_THAN   = 4;
+    public static final int FLAGS_VERSION_STRICTLY_EQUAL = 8;
+
+    /**
+     * If this flag is set, only versions strictly equal to the version specified shall match.
+     */
+    public static final int APP_ANY = -1;
+
+    /**
+     * If this flag is set, all vendors shall match.
+     */
+    public static final int VENDOR_ANY = -1;
+
+    /**
+     * If this flag is set, any hub shall match.
+     */
+    public static final int HUB_ANY = -1;
+
+    private NanoAppFilter(Parcel in) {
+        mAppId = in.readLong();
+        mAppVersion = in.readInt();
+        mVersionRestrictionMask = in.readInt();
+        mAppIdVendorMask = in.readInt();
+    }
+
+    public int describeContents() {
+        return 0;
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+
+        out.writeLong(mAppId);
+        out.writeInt(mAppVersion);
+        out.writeInt(mVersionRestrictionMask);
+        out.writeLong(mAppIdVendorMask);
+    }
+
+    /**
+     * Create a filter
+     *
+     * @param appId       application id
+     * @param appVersion  application version
+     * @param versionMask version
+     * @param vendorMask  vendor
+     */
+    public NanoAppFilter(long appId, int appVersion, int versionMask, long vendorMask) {
+        mAppId = appId;
+        mAppVersion = appVersion;
+        mVersionRestrictionMask = versionMask;
+        mAppIdVendorMask = vendorMask;
+    }
+
+    private boolean versionsMatch(int versionRestrictionMask, int expected, int actual){
+        // some refactoring of version restriction mask is needed, until then, return all
+        return true;
+    }
+    /**
+     *
+     * @param nano app instance info
+     *
+     * @return true if this is a match, false otherwise
+     */
+    public boolean testMatch(NanoAppInstanceInfo info) {
+        if ((mContextHubId == HUB_ANY || info.getContexthubId() == mContextHubId) &&
+                (mAppId == APP_ANY || info.getAppId() == mAppId) &&
+               // (mAppIdVendorMask == VENDOR_ANY) TODO : Expose Vendor mask cleanly
+                (versionsMatch(mVersionRestrictionMask, mAppVersion, info.getAppVersion()))) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    public static final Parcelable.Creator<NanoAppFilter> CREATOR
+            = new Parcelable.Creator<NanoAppFilter>() {
+        public NanoAppFilter createFromParcel(Parcel in) {
+            return new NanoAppFilter(in);
+        }
+
+        public NanoAppFilter[] newArray(int size) {
+            return new NanoAppFilter[size];
+        }
+    };
+}
diff --git a/core/java/android/hardware/location/NanoAppInstanceInfo.aidl b/core/java/android/hardware/location/NanoAppInstanceInfo.aidl
new file mode 100644
index 0000000..c8c40d7
--- /dev/null
+++ b/core/java/android/hardware/location/NanoAppInstanceInfo.aidl
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.location;
+/*
+@hide
+*/
+parcelable NanoAppInstanceInfo;
\ No newline at end of file
diff --git a/core/java/android/hardware/location/NanoAppInstanceInfo.java b/core/java/android/hardware/location/NanoAppInstanceInfo.java
new file mode 100644
index 0000000..ac62919
--- /dev/null
+++ b/core/java/android/hardware/location/NanoAppInstanceInfo.java
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.location;
+
+
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * @hide
+ */
+@SystemApi
+public class NanoAppInstanceInfo {
+    private String mPublisher;
+    private String mName;
+
+    private int mAppId;
+    private int mAppVersion;
+
+    private int mNeededReadMemBytes;
+    private int mNeededWriteMemBytes;
+    private int mNeededExecMemBytes;
+
+    private int[] mNeededSensors;
+    private int[] mOutputEvents;
+
+    private int mContexthubId;
+    private int mHandle;
+
+    public NanoAppInstanceInfo() {
+    }
+
+    /**
+     * get the publisher of this app
+     *
+     * @return String - name of the publisher
+     */
+    public String getPublisher() {
+        return mPublisher;
+    }
+
+
+    /**
+     * set the publisher name for the app
+     *
+     * @param publisher - name of the publisher
+     */
+    public void setPublisher(String publisher) {
+        mPublisher = publisher;
+    }
+
+    /**
+     * get the name of the app
+     *
+     * @return String - name of the app
+     */
+    public String getName() {
+        return mName;
+    }
+
+    /**
+     * set the name of the app
+     *
+     * @param name - name of the app
+     */
+    public void setName(String name) {
+        mName = name;
+    }
+
+    /**
+     * Get the application identifier
+     *
+     * @return int - application identifier
+     */
+    public int getAppId() {
+        return mAppId;
+    }
+
+    /**
+     * Set the application identifier
+     *
+     * @param appId - application identifier
+     */
+    public void setAppId(int appId) {
+        mAppId = appId;
+    }
+
+    /**
+     * Set the application version
+     *
+     * @return int - version of the app
+     */
+    public int getAppVersion() {
+        return mAppVersion;
+    }
+
+    /**
+     * Set the application version
+     *
+     * @param appVersion - version of the app
+     */
+    public void setAppVersion(int appVersion) {
+        mAppVersion = appVersion;
+    }
+
+    /**
+     * Get the read memory needed by the app
+     *
+     * @return int - readable memory needed in bytes
+     */
+    public int getNeededReadMemBytes() {
+        return mNeededReadMemBytes;
+    }
+
+    /**
+     * Set the read memory needed by the app
+     *
+     * @param neededReadMemBytes - readable Memory needed in bytes
+     */
+    public void setNeededReadMemBytes(int neededReadMemBytes) {
+        mNeededReadMemBytes = neededReadMemBytes;
+    }
+
+    /**
+     *  get writable memory needed by the app
+     *
+     * @return int - writable memory needed by the app
+     */
+    public int getNeededWriteMemBytes() {
+        return mNeededWriteMemBytes;
+    }
+
+    /**
+     * set writable memory needed by the app
+     *
+     * @param neededWriteMemBytes - writable memory needed by the
+     *                            app
+     */
+    public void setNeededWriteMemBytes(int neededWriteMemBytes) {
+        mNeededWriteMemBytes = neededWriteMemBytes;
+    }
+
+    /**
+     * get executable memory needed by the app
+     *
+     * @return int - executable memory needed by the app
+     */
+    public int getNeededExecMemBytes() {
+        return mNeededExecMemBytes;
+    }
+
+    /**
+     * set executable memory needed by the app
+     *
+     * @param neededExecMemBytes - executable memory needed by the
+     *                           app
+     */
+    public void setNeededExecMemBytes(int neededExecMemBytes) {
+        mNeededExecMemBytes = neededExecMemBytes;
+    }
+
+    /**
+     * Get the sensors needed by this app
+     *
+     * @return int[] all the required sensors needed by this app
+     */
+    public int[] getNeededSensors() {
+        return mNeededSensors;
+    }
+
+    /**
+     * set the sensors needed by this app
+     *
+     * @param neededSensors - all the sensors needed by this app
+     */
+    public void setNeededSensors(int[] neededSensors) {
+        mNeededSensors = neededSensors;
+    }
+
+    /**
+     * get the events generated by this app
+     *
+     * @return all the events that can be generated by this app
+     */
+    public int[] getOutputEvents() {
+        return mOutputEvents;
+    }
+
+    /**
+     * set the output events that can be generated by this app
+     *
+     * @param outputEvents - the events that may be generated by
+     *                     this app
+     */
+    public void setOutputEvents(int[] outputEvents) {
+        mOutputEvents = outputEvents;
+    }
+
+    /**
+     * get the context hub identifier
+     *
+     * @return int - system unique hub identifier
+     */
+    public int getContexthubId() {
+        return mContexthubId;
+    }
+
+    /**
+     * set the context hub identifier
+     *
+     * @param contexthubId - system wide unique identifier
+     */
+    public void setContexthubId(int contexthubId) {
+        mContexthubId = contexthubId;
+    }
+
+    /**
+     * get a handle to the nano app instance
+     *
+     * @return int - handle to this instance
+     */
+    public int getHandle() {
+        return mHandle;
+    }
+
+    /**
+     * set the handle for an app instance
+     *
+     * @param handle - handle to this instance
+     */
+    public void setHandle(int handle) {
+        mHandle = handle;
+    }
+
+
+    private NanoAppInstanceInfo(Parcel in) {
+        mPublisher = in.readString();
+        mName = in.readString();
+
+        mAppId = in.readInt();
+        mAppVersion = in.readInt();
+        mNeededReadMemBytes = in.readInt();
+        mNeededWriteMemBytes = in.readInt();
+        mNeededExecMemBytes = in.readInt();
+
+        int mNeededSensorsLength = in.readInt();
+        mNeededSensors = new int[mNeededSensorsLength];
+        in.readIntArray(mNeededSensors);
+
+        int mOutputEventsLength = in.readInt();
+        mOutputEvents = new int[mOutputEventsLength];
+        in.readIntArray(mOutputEvents);
+    }
+
+    public int describeContents() {
+        return 0;
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(mPublisher);
+        out.writeString(mName);
+        out.writeInt(mAppId);
+        out.writeInt(mAppVersion);
+        out.writeInt(mContexthubId);
+        out.writeInt(mNeededReadMemBytes);
+        out.writeInt(mNeededWriteMemBytes);
+        out.writeInt(mNeededExecMemBytes);
+
+        out.writeInt(mNeededSensors.length);
+        out.writeIntArray(mNeededSensors);
+
+        out.writeInt(mOutputEvents.length);
+        out.writeIntArray(mOutputEvents);
+
+    }
+
+    public static final Parcelable.Creator<NanoAppInstanceInfo> CREATOR
+            = new Parcelable.Creator<NanoAppInstanceInfo>() {
+        public NanoAppInstanceInfo createFromParcel(Parcel in) {
+            return new NanoAppInstanceInfo(in);
+        }
+
+        public NanoAppInstanceInfo[] newArray(int size) {
+            return new NanoAppInstanceInfo[size];
+        }
+    };
+}
diff --git a/packages/DocumentsUI/AndroidManifest.xml b/packages/DocumentsUI/AndroidManifest.xml
index c3452d5..fa9ff01 100644
--- a/packages/DocumentsUI/AndroidManifest.xml
+++ b/packages/DocumentsUI/AndroidManifest.xml
@@ -54,8 +54,7 @@
             android:name=".LauncherActivity"
             android:theme="@android:style/Theme.NoDisplay"
             android:icon="@drawable/ic_files_app"
-            android:label="@string/files_label"
-            android:enabled="@bool/productivity_device">
+            android:label="@string/files_label">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
diff --git a/packages/DocumentsUI/res/values/config.xml b/packages/DocumentsUI/res/values/config.xml
index ff28e15..e8d8c8e 100644
--- a/packages/DocumentsUI/res/values/config.xml
+++ b/packages/DocumentsUI/res/values/config.xml
@@ -18,7 +18,6 @@
     <!-- Allow Advanced Devices default value to be customised -->
     <bool name="config_defaultAdvancedDevices">false</bool>
 
-    <bool name="productivity_device">true</bool>
     <!-- Intentionally unset. Vendors should set this in an overlay. -->
     <string name="trusted_quick_viewer_package"></string>
 </resources>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
index 5ffc435..9309693 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
@@ -104,7 +104,6 @@
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
 
-        mProductivityDevice = getResources().getBoolean(R.bool.productivity_device);
         mState = (icicle != null)
                 ? icicle.<State>getParcelable(EXTRA_STATE)
                         : buildState();
diff --git a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
index 393fdcd..f51f689 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
@@ -16,12 +16,11 @@
 
 package com.android.documentsui;
 
+import static com.android.documentsui.OperationDialogFragment.DIALOG_TYPE_UNKNOWN;
 import static com.android.documentsui.Shared.DEBUG;
 import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_NONE;
 import static com.android.internal.util.Preconditions.checkArgument;
 import static com.android.internal.util.Preconditions.checkState;
-import static com.android.documentsui.OperationDialogFragment.DialogType;
-import static com.android.documentsui.OperationDialogFragment.DIALOG_TYPE_UNKNOWN;
 
 import android.app.Activity;
 import android.app.FragmentManager;
@@ -45,6 +44,7 @@
 import android.widget.Spinner;
 import android.widget.Toolbar;
 
+import com.android.documentsui.OperationDialogFragment.DialogType;
 import com.android.documentsui.RecentsProvider.ResumeColumns;
 import com.android.documentsui.dirlist.DirectoryFragment;
 import com.android.documentsui.model.DocumentInfo;
@@ -256,9 +256,6 @@
 
         pasteFromCb.setEnabled(mClipper.hasItemsToPaste());
 
-        newWindow.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
-        newWindow.setVisible(mProductivityDevice);
-
         Menus.disableHiddenItems(menu, pasteFromCb);
         return true;
     }
@@ -287,6 +284,14 @@
         Metrics.logMultiWindow(this);
         Intent intent = LauncherActivity.createLaunchIntent(this);
         intent.putExtra(Shared.EXTRA_STACK, (Parcelable) mState.stack);
+
+        // With new multi-window mode we have to pick how we are launched.
+        // By default we'd be launched in-place above the existing app.
+        // By setting launch-to-side ActivityManager will open us to side.
+        if (inMultiWindowMode()) {
+            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_TO_SIDE);
+        }
+
         startActivity(intent);
     }
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/LauncherActivity.java b/packages/DocumentsUI/src/com/android/documentsui/LauncherActivity.java
index b3d0cf3..7930c28 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/LauncherActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/LauncherActivity.java
@@ -74,6 +74,9 @@
 
     private void startTask() {
         Intent intent = createLaunchIntent(this);
+
+        // Forward any flags from the original intent.
+        intent.setFlags(getIntent().getFlags());
         if (DEBUG) Log.d(TAG, "Starting new task > " + intent.getData());
         startActivity(intent);
     }
@@ -84,7 +87,7 @@
         startActivity(intent);
     }
 
-    static Intent createLaunchIntent(Context context) {
+    static final Intent createLaunchIntent(Context context) {
         Intent intent = new Intent(context, FilesActivity.class);
         intent.setData(buildLaunchUri());
         return intent;
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/HumanInteractionClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/HumanInteractionClassifier.java
index 27d4c0e..c7e5ea4 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/HumanInteractionClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/HumanInteractionClassifier.java
@@ -35,6 +35,10 @@
 public class HumanInteractionClassifier extends Classifier {
     private static final String HIC_ENABLE = "HIC_enable";
     private static final float FINGER_DISTANCE = 0.1f;
+
+    /** Default value for the HIC_ENABLE setting: 1 - enabled, 0 - disabled */
+    private static final int HIC_ENABLE_DEFAULT = 1;
+
     private static HumanInteractionClassifier sInstance = null;
 
     private final Handler mHandler = new Handler();
@@ -101,9 +105,9 @@
     }
 
     private void updateConfiguration() {
-        mEnableClassifier = Build.IS_DEBUGGABLE && 0 != Settings.Global.getInt(
+        mEnableClassifier = 0 != Settings.Global.getInt(
                 mContext.getContentResolver(),
-                HIC_ENABLE, 0);
+                HIC_ENABLE, HIC_ENABLE_DEFAULT);
     }
 
     public void setType(int type) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 76fbebf..b5982c3 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -12970,6 +12970,9 @@
 
         final StringBuilder sb = new StringBuilder(1024);
         appendDropBoxProcessHeaders(process, processName, sb);
+        sb.append("Foreground: ")
+                .append(process.isInterestingToUserLocked() ? "Yes" : "No")
+                .append("\n");
         if (activity != null) {
             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
         }
diff --git a/telephony/java/android/telephony/ModemActivityInfo.java b/telephony/java/android/telephony/ModemActivityInfo.java
index c65e8ba..84883d8 100644
--- a/telephony/java/android/telephony/ModemActivityInfo.java
+++ b/telephony/java/android/telephony/ModemActivityInfo.java
@@ -48,7 +48,9 @@
         mTimestamp = timestamp;
         mSleepTimeMs = sleepTimeMs;
         mIdleTimeMs = idleTimeMs;
-        System.arraycopy(txTimeMs, 0, mTxTimeMs, 0, Math.min(txTimeMs.length, TX_POWER_LEVELS));
+        if (txTimeMs != null) {
+            System.arraycopy(txTimeMs, 0, mTxTimeMs, 0, Math.min(txTimeMs.length, TX_POWER_LEVELS));
+        }
         mRxTimeMs = rxTimeMs;
         mEnergyUsed = energyUsed;
     }
diff --git a/telephony/java/com/android/internal/telephony/ITelephonyDebug.aidl b/telephony/java/com/android/internal/telephony/ITelephonyDebug.aidl
index 5dffa28..069fcbf 100644
--- a/telephony/java/com/android/internal/telephony/ITelephonyDebug.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephonyDebug.aidl
@@ -16,8 +16,9 @@
 
 package com.android.internal.telephony;
 
-import android.os.Bundle;
+import com.android.internal.telephony.ITelephonyDebugSubscriber;
 
+import android.os.Bundle;
 
 /**
  * Interface used to interact with the Telephony debug service.
@@ -36,4 +37,7 @@
      * @param data optional
      */
     void writeEvent(long timestamp, int phoneId, int tag, int param1, int param2, in Bundle data);
+
+    void subscribe(in ITelephonyDebugSubscriber subscriber);
+    void unsubscribe(in ITelephonyDebugSubscriber subscriber);
 }
diff --git a/telephony/java/com/android/internal/telephony/ITelephonyDebugSubscriber.aidl b/telephony/java/com/android/internal/telephony/ITelephonyDebugSubscriber.aidl
new file mode 100644
index 0000000..64eb0f1
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/ITelephonyDebugSubscriber.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import com.android.internal.telephony.TelephonyEvent;
+
+import android.os.Bundle;
+
+/**
+ * Interface used to subscribe for events from Telephony debug service.
+ *
+ * {@hide}
+ */
+oneway interface ITelephonyDebugSubscriber {
+
+    /**
+     * Called when Telephony debug service has events.
+     */
+    void onEvents(in TelephonyEvent[] events);
+}
diff --git a/telephony/java/com/android/internal/telephony/TelephonyEvent.aidl b/telephony/java/com/android/internal/telephony/TelephonyEvent.aidl
new file mode 100644
index 0000000..1e74b31
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/TelephonyEvent.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+parcelable TelephonyEvent;
diff --git a/telephony/java/com/android/internal/telephony/TelephonyEvent.java b/telephony/java/com/android/internal/telephony/TelephonyEvent.java
new file mode 100644
index 0000000..26d466d
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/TelephonyEvent.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ *  A parcelable used in ITelephonyDebugSubscriber.aidl
+ */
+public class TelephonyEvent implements Parcelable {
+
+    final public long timestamp;
+    final public int phoneId;
+    final public int tag;
+    final public int param1;
+    final public int param2;
+    final public Bundle data;
+
+    public TelephonyEvent(long timestamp, int phoneId, int tag,
+            int param1, int param2, Bundle data) {
+        this.timestamp = timestamp;
+        this.phoneId = phoneId;
+        this.tag = tag;
+        this.param1 = param1;
+        this.param2 = param2;
+        this.data = data;
+    }
+
+    /** Implement the Parcelable interface */
+    public static final Parcelable.Creator<TelephonyEvent> CREATOR
+            = new Parcelable.Creator<TelephonyEvent> (){
+        public TelephonyEvent createFromParcel(Parcel source) {
+            final long timestamp = source.readLong();
+            final int phoneId = source.readInt();
+            final int tag = source.readInt();
+            final int param1 = source.readInt();
+            final int param2 = source.readInt();
+            final Bundle data = source.readBundle();
+            return new TelephonyEvent(timestamp, phoneId, tag, param1, param2, data);
+        }
+
+        public TelephonyEvent[] newArray(int size) {
+            return new TelephonyEvent[size];
+        }
+    };
+
+    /** Implement the Parcelable interface */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /** Implement the Parcelable interface */
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeLong(timestamp);
+        dest.writeInt(phoneId);
+        dest.writeInt(tag);
+        dest.writeInt(param1);
+        dest.writeInt(param2);
+        dest.writeBundle(data);
+    }
+
+    public String toString() {
+        return String.format("%d,%d,%d,%d,%d,%s",
+                timestamp, phoneId, tag, param1, param2, data);
+    }
+}
diff --git a/tests/VectorDrawableTest/res/color/vector_icon_fill_state_list_simple.xml b/tests/VectorDrawableTest/res/color/vector_icon_fill_state_list_simple.xml
new file mode 100644
index 0000000..0e2467f
--- /dev/null
+++ b/tests/VectorDrawableTest/res/color/vector_icon_fill_state_list_simple.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 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.
+ */
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:color="#f00" android:state_pressed="true" />
+    <item android:color="#00f" />
+</selector>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/color/vector_icon_stroke_state_list_simple.xml b/tests/VectorDrawableTest/res/color/vector_icon_stroke_state_list_simple.xml
new file mode 100644
index 0000000..7e6c8ce
--- /dev/null
+++ b/tests/VectorDrawableTest/res/color/vector_icon_stroke_state_list_simple.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 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.
+ */
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:color="#00f" android:state_pressed="true" />
+    <item android:color="#f00" />
+</selector>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/drawable/vector_icon_state_list_simple.xml b/tests/VectorDrawableTest/res/drawable/vector_icon_state_list_simple.xml
new file mode 100644
index 0000000..9f08fe8
--- /dev/null
+++ b/tests/VectorDrawableTest/res/drawable/vector_icon_state_list_simple.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 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.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:height="64dp"
+        android:width="64dp"
+        android:viewportHeight="24"
+        android:viewportWidth="24" >
+
+    <path
+        android:fillColor="@color/vector_icon_fill_state_list_simple"
+        android:strokeColor="@color/vector_icon_stroke_state_list_simple"
+        android:strokeWidth="3"
+        android:pathData="M16.0,5.0c-1.955.0 -3.83,1.268 -4.5,3.0c-0.67-1.732 -2.547-3.0 -4.5-3.0C4.4570007,5.0 2.5,6.931999 2.5,9.5c0.0,3.529 3.793,6.258 9.0,11.5c5.207-5.242 9.0-7.971 9.0-11.5C20.5,6.931999 18.543,5.0 16.0,5.0z"/>
+
+</vector>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/drawable/vector_icon_state_list.xml b/tests/VectorDrawableTest/res/drawable/vector_icon_state_list_theme.xml
similarity index 100%
rename from tests/VectorDrawableTest/res/drawable/vector_icon_state_list.xml
rename to tests/VectorDrawableTest/res/drawable/vector_icon_state_list_theme.xml
diff --git a/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java b/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java
index a7da286..7172147 100644
--- a/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java
+++ b/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java
@@ -38,7 +38,8 @@
             R.drawable.vector_icon_gradient_1,
             R.drawable.vector_icon_gradient_2,
             R.drawable.vector_icon_gradient_3,
-            R.drawable.vector_icon_state_list,
+            R.drawable.vector_icon_state_list_simple,
+            R.drawable.vector_icon_state_list_theme,
             R.drawable.vector_drawable01,
             R.drawable.vector_drawable02,
             R.drawable.vector_drawable03,