Merge "powerHAL: Add interface for GPU and DDR performance boosting"
diff --git a/audio/audio_hw.c b/audio/audio_hw.c
index 87fc4c6..a62c344 100644
--- a/audio/audio_hw.c
+++ b/audio/audio_hw.c
@@ -132,7 +132,6 @@
 static size_t out_get_buffer_size(const struct audio_stream *stream)
 {
     ALOGV("out_get_buffer_size: %d", 4096);
-    struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
 
     /* return the closest majoring multiple of 16 frames, as
      * audioflinger expects audio buffers to be a multiple of 16 frames */
@@ -200,7 +199,6 @@
     struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
     struct alsa_audio_device *adev = out->dev;
     struct str_parms *parms;
-    char *str;
     char value[32];
     int ret, val = 0;
 
@@ -251,7 +249,6 @@
     struct alsa_audio_device *adev = out->dev;
     size_t frame_size = audio_stream_out_frame_size(stream);
     size_t out_frames = bytes / frame_size;
-    int kernel_frames;
     struct misc_io_pcm_buf_param pcmbuf;
 
     /* acquiring hw device mutex systematically is useful if a low priority thread is waiting
@@ -589,7 +586,7 @@
     return 320;
 }
 
-static int adev_open_input_stream(struct audio_hw_device *dev,
+static int adev_open_input_stream(struct audio_hw_device __unused *dev,
         audio_io_handle_t handle,
         audio_devices_t devices,
         struct audio_config *config,
@@ -598,11 +595,9 @@
         const char *address __unused,
         audio_source_t source __unused)
 {
-    ALOGV("adev_open_input_stream...");
-
-    struct stub_audio_device *ladev = (struct stub_audio_device *)dev;
     struct stub_stream_in *in;
-    int ret;
+
+    ALOGV("adev_open_input_stream...");
 
     in = (struct stub_stream_in *)calloc(1, sizeof(struct stub_stream_in));
     if (!in)
@@ -655,10 +650,9 @@
 static int adev_open(const hw_module_t* module, const char* name,
         hw_device_t** device)
 {
-    ALOGV("adev_open: %s", name);
-
     struct alsa_audio_device *adev;
-    int ret;
+
+    ALOGV("adev_open: %s", name);
 
     if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
         return -EINVAL;
diff --git a/device-common.mk b/device-common.mk
index 3443b05..18b6282 100644
--- a/device-common.mk
+++ b/device-common.mk
@@ -151,6 +151,7 @@
         frameworks/native/data/etc/android.software.cts.xml:system/etc/permissions/android.software.cts.xml \
         frameworks/native/data/etc/android.software.app_widgets.xml:system/etc/permissions/android.software.app_widgets.xml \
         frameworks/native/data/etc/android.software.backup.xml:system/etc/permissions/android.software.backup.xml \
+        frameworks/native/data/etc/android.software.voice_recognizers.xml:system/etc/permissions/android.software.voice_recognizers.xml \
         frameworks/native/data/etc/android.hardware.ethernet.xml:system/etc/permissions/android.hardware.ethernet.xml \
         frameworks/native/data/etc/android.hardware.usb.accessory.xml:system/etc/permissions/android.hardware.usb.accessory.xml \
         frameworks/native/data/etc/android.hardware.usb.host.xml:system/etc/permissions/android.hardware.usb.host.xml \
diff --git a/gralloc/alloc_device.cpp b/gralloc/alloc_device.cpp
index d1377ff..488e47c 100644
--- a/gralloc/alloc_device.cpp
+++ b/gralloc/alloc_device.cpp
@@ -446,13 +446,26 @@
 				bpp = 2;
 				break;
 
+			case HAL_PIXEL_FORMAT_BLOB:
+				if (h != 1) {
+					AERR("Height for HAL_PIXEL_FORMAT_BLOB must be 1. h=%d", h);
+					return -EINVAL;
+				}
+				break;
+
 			default:
+				AERR("The format is not supported yet: format=%d\n",  format);
 				return -EINVAL;
 		}
 
-		size_t bpr = GRALLOC_ALIGN(w * bpp, 64);
-		size = bpr * h;
-		stride = bpr / bpp;
+		if (format == HAL_PIXEL_FORMAT_BLOB) {
+			stride = 0; /* No 'rows', it's effectively a long one dimensional array */
+			size = w;
+		}else{
+			size_t bpr = GRALLOC_ALIGN(w * bpp, 64);
+			size = bpr * h;
+			stride = bpr / bpp;
+		}
 	}
 
 	int err;
@@ -561,8 +574,6 @@
 	else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
 	{
 #if GRALLOC_ARM_DMA_BUF_MODULE
-		private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
-
 		/* Buffer might be unregistered so we need to check for invalid ump handle*/
 		if (0 != hnd->base)
 		{
diff --git a/gralloc/gralloc_module.cpp b/gralloc/gralloc_module.cpp
index 70d2c69..d0cb080 100644
--- a/gralloc/gralloc_module.cpp
+++ b/gralloc/gralloc_module.cpp
@@ -135,7 +135,6 @@
 	else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
 	{
 #if GRALLOC_ARM_DMA_BUF_MODULE
-		int ret;
 		unsigned char *mappedAddress;
 		size_t size = hnd->size;
 		hw_module_t *pmodule = NULL;
@@ -326,9 +325,6 @@
 	}
 
 	private_handle_t *hnd = (private_handle_t *)handle;
-	int32_t current_value;
-	int32_t new_value;
-	int retry;
 
 	if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP && hnd->writeOwner)
 	{
@@ -342,18 +338,11 @@
 	{
 #if GRALLOC_ARM_DMA_BUF_MODULE
 		hw_module_t *pmodule = NULL;
-		private_module_t *m = NULL;
 
-		if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&pmodule) == 0)
-		{
-			m = reinterpret_cast<private_module_t *>(pmodule);
-			//ion_sync_fd(m->ion_client, hnd->share_fd);
-		}
-		else
+		if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&pmodule) != 0)
 		{
 			AERR("Couldnot get gralloc module for handle 0x%p\n", handle);
 		}
-
 #endif
 	}
 
diff --git a/gralloc960/alloc_ion.cpp b/gralloc960/alloc_ion.cpp
index 2af9d94..0a84aaa 100644
--- a/gralloc960/alloc_ion.cpp
+++ b/gralloc960/alloc_ion.cpp
@@ -16,6 +16,7 @@
  * limitations under the License.
  */
 
+#include <cstdlib>
 #include <string.h>
 #include <errno.h>
 #include <inttypes.h>
@@ -32,6 +33,7 @@
 #include "gralloc_priv.h"
 #include "gralloc_helper.h"
 #include "framebuffer_device.h"
+#include "ion_4.12.h"
 
 #include "mali_gralloc_formats.h"
 
@@ -148,6 +150,51 @@
 	return ion_hnd;
 }
 
+static int find_system_heap_id(int ion_client)
+{
+	int i, ret, cnt, system_heap_id = -1;
+	struct ion_heap_data *data;
+
+	ret = ion_query_heap_cnt(ion_client, &cnt);
+
+	if (ret)
+	{
+		AERR("ion count query failed with %s", strerror(errno));
+		return -1;
+	}
+
+	data = (struct ion_heap_data *)malloc(cnt * sizeof(*data));
+	if (!data)
+	{
+		AERR("Error allocating data %s\n", strerror(errno));
+		return -1;
+	}
+
+	ret = ion_query_get_heaps(ion_client, cnt, data);
+	if (ret)
+	{
+		AERR("Error querying heaps from ion %s", strerror(errno));
+	}
+	else
+	{
+		for (i = 0; i < cnt; i++) {
+			if (strcmp(data[i].name, "ion_system_heap") == 0) {
+				system_heap_id = data[i].heap_id;
+				break;
+			}
+		}
+
+		if (i == cnt)
+		{
+			AERR("No System Heap Found amongst %d heaps\n", cnt);
+			system_heap_id = -1;
+		}
+	}
+
+	free(data);
+	return system_heap_id;
+}
+
 unsigned int pick_ion_heap(int usage)
 {
 	unsigned int heap_mask;
@@ -215,7 +262,6 @@
 int alloc_backend_alloc(alloc_device_t* dev, size_t size, int usage, buffer_handle_t* pHandle, uint64_t fmt, int w, int h)
 {
 	private_module_t* m = reinterpret_cast<private_module_t*>(dev->common.module);
-	ion_user_handle_t ion_hnd;
 	unsigned char *cpu_ptr = NULL;
 	int shared_fd;
 	int ret;
@@ -225,36 +271,52 @@
 	int lock_state = 0;
 	int min_pgsz = 0;
 
-	heap_mask = pick_ion_heap(usage);
-	if(heap_mask == 0)
+	if (m->gralloc_legacy_ion)
 	{
-		AERR("Failed to find an appropriate ion heap");
-		return -1;
-	}
-	set_ion_flags(heap_mask, usage, &priv_heap_flag, &ion_flags);
+		ion_user_handle_t ion_hnd;
 
-	ion_hnd = alloc_from_ion_heap(m->ion_client, size, heap_mask, ion_flags, &min_pgsz);
-	if (ion_hnd < 0)
+		heap_mask = pick_ion_heap(usage);
+		if(heap_mask == 0)
+		{
+			AERR("Failed to find an appropriate ion heap");
+			return -1;
+		}
+		set_ion_flags(heap_mask, usage, &priv_heap_flag, &ion_flags);
+
+		ion_hnd = alloc_from_ion_heap(m->ion_client, size, heap_mask, ion_flags, &min_pgsz);
+		if (ion_hnd < 0)
+		{
+			AERR("Failed to ion_alloc from ion_client:%d", m->ion_client);
+			return -1;
+		}
+
+		ret = ion_share( m->ion_client, ion_hnd, &shared_fd );
+		if ( ret != 0 )
+		{
+			AERR( "ion_share( %d ) failed", m->ion_client );
+			if ( 0 != ion_free( m->ion_client, ion_hnd ) ) AERR( "ion_free( %d ) failed", m->ion_client );
+			return -1;
+		}
+
+		// we do not need ion_hnd once we have shared_fd
+		if (0 != ion_free(m->ion_client, ion_hnd))
+		{
+		    AWAR("ion_free( %d ) failed", m->ion_client);
+		}
+		ion_hnd = -1;
+	}
+	else
 	{
-		AERR("Failed to ion_alloc from ion_client:%d", m->ion_client);
-		return -1;
+		/* Support only System heap to begin with */
+		ret = ion_alloc_fd(m->ion_client, size, 0, 1 << m->system_heap_id, 0, &(shared_fd));
+		if (ret != 0)
+		{
+			AERR("Failed to ion_alloc_fd from ion_client:%d", m->ion_client);
+			return -1;
+		}
+		min_pgsz = SZ_4K;
 	}
 
-	ret = ion_share( m->ion_client, ion_hnd, &shared_fd );
-	if ( ret != 0 )
-	{
-		AERR( "ion_share( %d ) failed", m->ion_client );
-		if ( 0 != ion_free( m->ion_client, ion_hnd ) ) AERR( "ion_free( %d ) failed", m->ion_client );		
-		return -1;
-	}
-
-        // we do not need ion_hnd once we have shared_fd
-        if (0 != ion_free(m->ion_client, ion_hnd))
-        {
-            AWAR("ion_free( %d ) failed", m->ion_client);
-        }
-        ion_hnd = -1;
-
 	if (!(usage & GRALLOC_USAGE_PROTECTED))
 	{
 		cpu_ptr = (unsigned char*)mmap( NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shared_fd, 0 );
@@ -352,6 +414,20 @@
 		return -1;
 	}
 
+	m->gralloc_legacy_ion = ion_is_legacy(m->ion_client);
+
+	if (!m->gralloc_legacy_ion)
+	{
+		m->system_heap_id = find_system_heap_id(m->ion_client);
+		if (m->system_heap_id < 0)
+		{
+			ion_close(m->ion_client);
+			m->ion_client = -1;
+			AERR( "ion_open failed: no system heap found" );
+			return -1;
+		}
+	}
+
 	return 0;
 }
 
diff --git a/gralloc960/gralloc_module_ion.cpp b/gralloc960/gralloc_module_ion.cpp
index d91902c..9d3c4c8 100644
--- a/gralloc960/gralloc_module_ion.cpp
+++ b/gralloc960/gralloc_module_ion.cpp
@@ -27,6 +27,7 @@
 #include "gralloc_priv.h"
 #include "alloc_device.h"
 #include "framebuffer_device.h"
+#include "ion_4.12.h"
 
 #include <linux/ion.h>
 #include <ion/ion.h>
@@ -110,13 +111,15 @@
 	{
 	case private_handle_t::PRIV_FLAGS_USES_ION:
 		hw_module_t * pmodule = NULL;
-		private_module_t *m=NULL;
 		if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&pmodule) == 0)
 		{
-			if(!(hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION_DMA_HEAP))
+			private_module_t *m = reinterpret_cast<private_module_t *>(pmodule);
+			if (m->gralloc_legacy_ion)
 			{
-				m = reinterpret_cast<private_module_t *>(pmodule);
-				ion_sync_fd(m->ion_client, hnd->share_fd);
+				if(!(hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION_DMA_HEAP))
+				{
+					ion_sync_fd(m->ion_client, hnd->share_fd);
+				}
 			}
 		}
 		else
diff --git a/gralloc960/gralloc_priv.h b/gralloc960/gralloc_priv.h
index 55feb67..606b365 100644
--- a/gralloc960/gralloc_priv.h
+++ b/gralloc960/gralloc_priv.h
@@ -94,6 +94,8 @@
 	pthread_mutex_t lock;
 	buffer_handle_t currentBuffer;
 	int ion_client;
+	int system_heap_id;
+	bool gralloc_legacy_ion;
 	mali_dpy_type dpy_type;
 
 	struct fb_var_screeninfo info;
diff --git a/gralloc960/ion_4.12.h b/gralloc960/ion_4.12.h
new file mode 100644
index 0000000..6ae79d4
--- /dev/null
+++ b/gralloc960/ion_4.12.h
@@ -0,0 +1,125 @@
+/*
+ * Adapted from drivers/staging/android/uapi/ion.h
+ *
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _UAPI_LINUX_ION_NEW_H
+#define _UAPI_LINUX_ION_NEW_H
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+#define ION_NUM_HEAP_IDS (sizeof(unsigned int) * 8)
+
+/**
+ * DOC: Ion Userspace API
+ *
+ * create a client by opening /dev/ion
+ * most operations handled via following ioctls
+ *
+ */
+
+/**
+ * struct ion_new_allocation_data - metadata passed from userspace for allocations
+ * @len:		size of the allocation
+ * @heap_id_mask:	mask of heap ids to allocate from
+ * @flags:		flags passed to heap
+ * @handle:		pointer that will be populated with a cookie to use to
+ *			refer to this allocation
+ *
+ * Provided by userspace as an argument to the ioctl - added _new to denote
+ * this belongs to the new ION interface.
+ */
+struct ion_new_allocation_data {
+    __u64 len;
+    __u32 heap_id_mask;
+    __u32 flags;
+    __u32 fd;
+    __u32 unused;
+};
+
+#define MAX_HEAP_NAME 32
+
+/**
+ * struct ion_heap_data - data about a heap
+ * @name - first 32 characters of the heap name
+ * @type - heap type
+ * @heap_id - heap id for the heap
+ */
+struct ion_heap_data {
+    char name[MAX_HEAP_NAME];
+    __u32 type;
+    __u32 heap_id;
+    __u32 reserved0;
+    __u32 reserved1;
+    __u32 reserved2;
+};
+
+/**
+ * struct ion_heap_query - collection of data about all heaps
+ * @cnt - total number of heaps to be copied
+ * @heaps - buffer to copy heap data
+ */
+struct ion_heap_query {
+    __u32 cnt;       /* Total number of heaps to be copied */
+    __u32 reserved0; /* align to 64bits */
+    __u64 heaps;     /* buffer to be populated */
+    __u32 reserved1;
+    __u32 reserved2;
+};
+
+#define ION_IOC_MAGIC 'I'
+
+/**
+ * DOC: ION_IOC_NEW_ALLOC - allocate memory
+ *
+ * Takes an ion_allocation_data struct and returns it with the handle field
+ * populated with the opaque handle for the allocation.
+ * TODO: This IOCTL will clash by design; however, only one of
+ *  ION_IOC_ALLOC or ION_IOC_NEW_ALLOC paths will be exercised,
+ *  so this should not conflict.
+ */
+#define ION_IOC_NEW_ALLOC _IOWR(ION_IOC_MAGIC, 0, struct ion_new_allocation_data)
+
+/**
+ * DOC: ION_IOC_FREE - free memory
+ *
+ * Takes an ion_handle_data struct and frees the handle.
+ *
+ * #define ION_IOC_FREE		_IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data)
+ * This will come from the older kernels, so don't redefine here
+ */
+
+/**
+ * DOC: ION_IOC_SHARE - creates a file descriptor to use to share an allocation
+ *
+ * Takes an ion_fd_data struct with the handle field populated with a valid
+ * opaque handle.  Returns the struct with the fd field set to a file
+ * descriptor open in the current address space.  This file descriptor
+ * can then be passed to another process.  The corresponding opaque handle can
+ * be retrieved via ION_IOC_IMPORT.
+ *
+ * #define ION_IOC_SHARE		_IOWR(ION_IOC_MAGIC, 4, struct ion_fd_data)
+ * This will come from the older kernels, so don't redefine here
+ */
+
+/**
+ * DOC: ION_IOC_HEAP_QUERY - information about available heaps
+ *
+ * Takes an ion_heap_query structure and populates information about
+ * available Ion heaps.
+ */
+#define ION_IOC_HEAP_QUERY _IOWR(ION_IOC_MAGIC, 8, struct ion_heap_query)
+
+#endif /* _UAPI_LINUX_ION_NEW_H */
diff --git a/init.common.rc b/init.common.rc
index 0481b64..9feaacc 100644
--- a/init.common.rc
+++ b/init.common.rc
@@ -93,7 +93,7 @@
 
 service wpa_supplicant /system/vendor/bin/hw/wpa_supplicant \
      -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \
-     -e/data/misc/wifi/entropy.bin  -g@android:wpa_wlan0
+     -g@android:wpa_wlan0
      socket wpa_wlan0 dgram 660 wifi wifi
      class main
      disabled
diff --git a/installer/hikey/fip.bin b/installer/hikey/fip.bin
index 41e6ffd..80fb102 100644
--- a/installer/hikey/fip.bin
+++ b/installer/hikey/fip.bin
Binary files differ
diff --git a/installer/hikey/l-loader.bin b/installer/hikey/l-loader.bin
index 0f9d11d..ac42148 100644
--- a/installer/hikey/l-loader.bin
+++ b/installer/hikey/l-loader.bin
Binary files differ
diff --git a/overlay/frameworks/base/core/res/res/values/config.xml b/overlay/frameworks/base/core/res/res/values/config.xml
index 8fc81a3..f241581 100644
--- a/overlay/frameworks/base/core/res/res/values/config.xml
+++ b/overlay/frameworks/base/core/res/res/values/config.xml
@@ -42,7 +42,6 @@
     <!-- the 6th element indicates boot-time dependency-met value. -->
     <string-array translatable="false" name="networkAttributes">
         <item>"wifi,1,1,1,-1,true"</item>
-        <item>"wifi_p2p,13,1,0,-1,true"</item>
         <item>"ethernet,9,9,2,-1,true"</item>
     </string-array>
 
diff --git a/sepolicy/hal_wifi_supplicant_default.te b/sepolicy/hal_wifi_supplicant_default.te
new file mode 100644
index 0000000..3646bac
--- /dev/null
+++ b/sepolicy/hal_wifi_supplicant_default.te
@@ -0,0 +1,10 @@
+# TODO(b/36657258): Remove data_between_core_and_vendor_violators once
+# hal_wifi_supplicant no longer directly accesses wifi_data_file.
+typeattribute hal_wifi_supplicant_default data_between_core_and_vendor_violators;
+
+allow hal_wifi_supplicant_default wifi_data_file:dir create_dir_perms;
+allow hal_wifi_supplicant_default wifi_data_file:file create_file_perms;
+
+# Create a socket for receiving info from wpa
+allow hal_wifi_supplicant_default wpa_socket:dir create_dir_perms;
+allow hal_wifi_supplicant_default wpa_socket:sock_file create_file_perms;
diff --git a/sepolicy/hostapd.te b/sepolicy/hostapd.te
new file mode 100644
index 0000000..86b985a
--- /dev/null
+++ b/sepolicy/hostapd.te
@@ -0,0 +1,11 @@
+# TODO(b/36657258): Remove data_between_core_and_vendor_violators once
+# hostapd no longer directly accesses /data outside /data/vendor.
+typeattribute hostapd data_between_core_and_vendor_violators;
+# hostapd can read and write WiFi related data and configuration.
+allow hostapd wifi_data_file:file rw_file_perms;
+r_dir_file(hostapd, wifi_data_file)
+
+# hostapd wants to create the directory holding its control socket.
+allow hostapd hostapd_socket:dir create_dir_perms;
+# hostapd needs to create, bind to, read, and write its control socket.
+allow hostapd hostapd_socket:sock_file create_file_perms;