diff options
-rw-r--r-- | fastboot/fastboot.cpp | 45 | ||||
-rw-r--r-- | fs_mgr/fs_mgr_fstab.c | 6 | ||||
-rw-r--r-- | fs_mgr/fs_mgr_priv.h | 1 | ||||
-rw-r--r-- | fs_mgr/include/fs_mgr.h | 1 | ||||
-rw-r--r-- | healthd/healthd.cpp | 1 | ||||
-rw-r--r-- | healthd/healthd.h | 1 | ||||
-rw-r--r-- | healthd/healthd_mode_charger.cpp | 23 | ||||
-rw-r--r-- | include/netutils/dhcp.h | 32 | ||||
-rw-r--r-- | include/system/audio.h | 6 | ||||
-rw-r--r-- | include/system/camera.h | 7 | ||||
-rw-r--r-- | include/system/graphics.h | 209 | ||||
-rw-r--r-- | include/system/radio.h | 247 | ||||
-rw-r--r-- | include/system/window.h | 28 | ||||
-rw-r--r-- | include/sysutils/NetlinkEvent.h | 21 | ||||
-rw-r--r-- | include/utils/Looper.h | 23 | ||||
-rw-r--r-- | init/init.cpp | 72 | ||||
-rw-r--r-- | init/ueventd.cpp | 26 | ||||
-rw-r--r-- | init/util.cpp | 33 | ||||
-rw-r--r-- | init/util.h | 1 | ||||
-rw-r--r-- | libion/ion.c | 14 | ||||
-rw-r--r-- | libnetutils/dhcp_utils.c | 112 | ||||
-rw-r--r-- | libsysutils/src/NetlinkEvent.cpp | 49 | ||||
-rw-r--r-- | libutils/Looper.cpp | 189 | ||||
-rw-r--r-- | logwrapper/logwrap.c | 2 | ||||
-rw-r--r-- | rootdir/init.rc | 4 |
25 files changed, 846 insertions, 307 deletions
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp index 058d62a..a1847f6 100644 --- a/fastboot/fastboot.cpp +++ b/fastboot/fastboot.cpp @@ -285,9 +285,8 @@ void usage(void) " Can override the fs type and/or\n" " size the bootloader reports.\n" " getvar <variable> display a bootloader variable\n" - " boot <kernel> [ <ramdisk> [ <second> ] ] download and boot kernel\n" - " flash:raw boot <kernel> [ <ramdisk> [ <second> ] ] create bootimage and \n" - " flash it\n" + " boot <kernel> [ <ramdisk> ] download and boot kernel\n" + " flash:raw boot <kernel> [ <ramdisk> ] create bootimage and flash it\n" " devices list all connected devices\n" " continue continue with autoboot\n" " reboot [bootloader] reboot device, optionally into bootloader\n" @@ -315,11 +314,10 @@ void usage(void) } void *load_bootable_image(const char *kernel, const char *ramdisk, - const char *secondstage, unsigned *sz, - const char *cmdline) + unsigned *sz, const char *cmdline) { - void *kdata = 0, *rdata = 0, *sdata = 0; - unsigned ksize = 0, rsize = 0, ssize = 0; + void *kdata = 0, *rdata = 0; + unsigned ksize = 0, rsize = 0; void *bdata; unsigned bsize; @@ -355,18 +353,10 @@ void *load_bootable_image(const char *kernel, const char *ramdisk, } } - if (secondstage) { - sdata = load_file(secondstage, &ssize); - if(sdata == 0) { - fprintf(stderr,"cannot load '%s': %s\n", secondstage, strerror(errno)); - return 0; - } - } - fprintf(stderr,"creating boot image...\n"); bdata = mkbootimg(kdata, ksize, kernel_offset, rdata, rsize, ramdisk_offset, - sdata, ssize, second_offset, + 0, 0, second_offset, page_size, base_addr, tags_offset, &bsize); if(bdata == 0) { fprintf(stderr,"failed to create boot.img\n"); @@ -1128,7 +1118,6 @@ int main(int argc, char **argv) } else if(!strcmp(*argv, "boot")) { char *kname = 0; char *rname = 0; - char *sname = 0; skip(1); if (argc > 0) { kname = argv[0]; @@ -1138,11 +1127,7 @@ int main(int argc, char **argv) rname = argv[0]; skip(1); } - if (argc > 0) { - sname = argv[0]; - skip(1); - } - data = load_bootable_image(kname, rname, sname, &sz, cmdline); + data = load_bootable_image(kname, rname, &sz, cmdline); if (data == 0) return 1; fb_queue_download("boot.img", data, sz); fb_queue_command("boot", "booting"); @@ -1166,18 +1151,14 @@ int main(int argc, char **argv) char *pname = argv[1]; char *kname = argv[2]; char *rname = 0; - char *sname = 0; require(3); - skip(3); - if (argc > 0) { - rname = argv[0]; - skip(1); - } - if (argc > 0) { - sname = argv[0]; - skip(1); + if(argc > 3) { + rname = argv[3]; + skip(4); + } else { + skip(3); } - data = load_bootable_image(kname, rname, sname, &sz, cmdline); + data = load_bootable_image(kname, rname, &sz, cmdline); if (data == 0) die("cannot load bootable image"); fb_queue_flash(pname, data, sz); } else if(!strcmp(*argv, "flashall")) { diff --git a/fs_mgr/fs_mgr_fstab.c b/fs_mgr/fs_mgr_fstab.c index ab8f128..64f7edc 100644 --- a/fs_mgr/fs_mgr_fstab.c +++ b/fs_mgr/fs_mgr_fstab.c @@ -68,6 +68,7 @@ static struct flag_list fs_mgr_flags[] = { { "zramsize=", MF_ZRAMSIZE }, { "verify", MF_VERIFY }, { "noemulatedsd", MF_NOEMULATEDSD }, + { "notrim", MF_NOTRIM }, { "defaults", 0 }, { 0, 0 }, }; @@ -432,3 +433,8 @@ int fs_mgr_is_noemulatedsd(struct fstab_rec *fstab) { return fstab->fs_mgr_flags & MF_NOEMULATEDSD; } + +int fs_mgr_is_notrim(struct fstab_rec *fstab) +{ + return fstab->fs_mgr_flags & MF_NOTRIM; +} diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h index 88a1040..efc7ca5 100644 --- a/fs_mgr/fs_mgr_priv.h +++ b/fs_mgr/fs_mgr_priv.h @@ -76,6 +76,7 @@ #define MF_FORCECRYPT 0x400 #define MF_NOEMULATEDSD 0x800 /* no emulated sdcard daemon, sd card is the only external storage */ +#define MF_NOTRIM 0x1000 #define DM_BUF_SIZE 4096 diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h index 0437d45..a7a0bdb 100644 --- a/fs_mgr/include/fs_mgr.h +++ b/fs_mgr/include/fs_mgr.h @@ -94,6 +94,7 @@ int fs_mgr_is_nonremovable(struct fstab_rec *fstab); int fs_mgr_is_verified(struct fstab_rec *fstab); int fs_mgr_is_encryptable(struct fstab_rec *fstab); int fs_mgr_is_noemulatedsd(struct fstab_rec *fstab); +int fs_mgr_is_notrim(struct fstab_rec *fstab); int fs_mgr_swapon_all(struct fstab *fstab); #ifdef __cplusplus } diff --git a/healthd/healthd.cpp b/healthd/healthd.cpp index 1fee855..b0002cc 100644 --- a/healthd/healthd.cpp +++ b/healthd/healthd.cpp @@ -53,6 +53,7 @@ static struct healthd_config healthd_config = { .batteryCurrentAvgPath = String8(String8::kEmptyString), .batteryChargeCounterPath = String8(String8::kEmptyString), .energyCounter = NULL, + .boot_min_cap = 0, .screen_on = NULL, }; diff --git a/healthd/healthd.h b/healthd/healthd.h index 4704f0b..84b6d76 100644 --- a/healthd/healthd.h +++ b/healthd/healthd.h @@ -67,6 +67,7 @@ struct healthd_config { android::String8 batteryChargeCounterPath; int (*energyCounter)(int64_t *); + int boot_min_cap; bool (*screen_on)(android::BatteryProperties *props); }; diff --git a/healthd/healthd_mode_charger.cpp b/healthd/healthd_mode_charger.cpp index 9ed5944..352510b 100644 --- a/healthd/healthd_mode_charger.cpp +++ b/healthd/healthd_mode_charger.cpp @@ -116,6 +116,7 @@ struct charger { struct animation *batt_anim; gr_surface surf_unknown; + int boot_min_cap; }; static struct frame batt_anim_frames[] = { @@ -520,19 +521,29 @@ static void process_key(struct charger *charger, int code, int64_t now) LOGW("[%" PRId64 "] booting from charger mode\n", now); property_set("sys.boot_from_charger_mode", "1"); } else { - LOGW("[%" PRId64 "] rebooting\n", now); - android_reboot(ANDROID_RB_RESTART, 0, 0); + if (charger->batt_anim->capacity >= charger->boot_min_cap) { + LOGW("[%" PRId64 "] rebooting\n", now); + android_reboot(ANDROID_RB_RESTART, 0, 0); + } else { + LOGV("[%" PRId64 "] ignore power-button press, battery level " + "less than minimum\n", now); + } } } else { /* if the key is pressed but timeout hasn't expired, * make sure we wake up at the right-ish time to check */ set_next_key_check(charger, key, POWER_ON_KEY_TIME); + + /* Turn on the display and kick animation on power-key press + * rather than on key release + */ + kick_animation(charger->batt_anim); + request_suspend(false); } } else { /* if the power key got released, force screen state cycle */ if (key->pending) { - request_suspend(false); kick_animation(charger->batt_anim); } } @@ -555,6 +566,11 @@ static void handle_power_supply_state(struct charger *charger, int64_t now) return; if (!charger->charger_connected) { + + /* Last cycle would have stopped at the extreme top of battery-icon + * Need to show the correct level corresponding to capacity. + */ + kick_animation(charger->batt_anim); request_suspend(false); if (charger->next_pwr_check == -1) { charger->next_pwr_check = now + UNPLUGGED_SHUTDOWN_TIME; @@ -705,4 +721,5 @@ void healthd_mode_charger_init(struct healthd_config* config) charger->next_key_check = -1; charger->next_pwr_check = -1; healthd_config = config; + charger->boot_min_cap = config->boot_min_cap; } diff --git a/include/netutils/dhcp.h b/include/netutils/dhcp.h index de6bc82..008dbd8 100644 --- a/include/netutils/dhcp.h +++ b/include/netutils/dhcp.h @@ -23,26 +23,18 @@ __BEGIN_DECLS extern int do_dhcp(char *iname); -extern int dhcp_do_request(const char *ifname, - char *ipaddr, - char *gateway, - uint32_t *prefixLength, - char *dns[], - char *server, - uint32_t *lease, - char *vendorInfo, - char *domain, - char *mtu); -extern int dhcp_do_request_renew(const char *ifname, - char *ipaddr, - char *gateway, - uint32_t *prefixLength, - char *dns[], - char *server, - uint32_t *lease, - char *vendorInfo, - char *domain, - char *mtu); +extern int dhcp_start(const char *ifname); +extern int dhcp_start_renew(const char *ifname); +extern int dhcp_get_results(const char *ifname, + char *ipaddr, + char *gateway, + uint32_t *prefixLength, + char *dns[], + char *server, + uint32_t *lease, + char *vendorInfo, + char *domain, + char *mtu); extern int dhcp_stop(const char *ifname); extern int dhcp_release_lease(const char *ifname); extern char *dhcp_get_errmsg(); diff --git a/include/system/audio.h b/include/system/audio.h index 181a171..17bf260 100644 --- a/include/system/audio.h +++ b/include/system/audio.h @@ -194,7 +194,7 @@ typedef enum { AUDIO_FORMAT_PCM_SUB_16_BIT = 0x1, /* DO NOT CHANGE - PCM signed 16 bits */ AUDIO_FORMAT_PCM_SUB_8_BIT = 0x2, /* DO NOT CHANGE - PCM unsigned 8 bits */ AUDIO_FORMAT_PCM_SUB_32_BIT = 0x3, /* PCM signed .31 fixed point */ - AUDIO_FORMAT_PCM_SUB_8_24_BIT = 0x4, /* PCM signed 7.24 fixed point */ + AUDIO_FORMAT_PCM_SUB_8_24_BIT = 0x4, /* PCM signed 8.23 fixed point */ AUDIO_FORMAT_PCM_SUB_FLOAT = 0x5, /* PCM single-precision floating point */ AUDIO_FORMAT_PCM_SUB_24_BIT_PACKED = 0x6, /* PCM signed .23 fixed point packed in 3 bytes */ } audio_format_pcm_sub_fmt_t; @@ -872,6 +872,8 @@ typedef enum { typedef int audio_port_handle_t; #define AUDIO_PORT_HANDLE_NONE 0 +/* the maximum length for the human-readable device name. i.e. "Alesis iO4"*/ +#define AUDIO_PORT_MAX_NAME_LEN 128 /* maximum audio device address length */ #define AUDIO_DEVICE_MAX_ADDRESS_LEN 32 @@ -966,11 +968,11 @@ struct audio_port_session_ext { audio_session_t session; /* audio session */ }; - struct audio_port { audio_port_handle_t id; /* port unique ID */ audio_port_role_t role; /* sink or source */ audio_port_type_t type; /* device, mix ... */ + char name[AUDIO_PORT_MAX_NAME_LEN]; unsigned int num_sample_rates; /* number of sampling rates in following array */ unsigned int sample_rates[AUDIO_PORT_MAX_SAMPLING_RATES]; unsigned int num_channel_masks; /* number of channel masks in following array */ diff --git a/include/system/camera.h b/include/system/camera.h index 7a4dd53..09c915d 100644 --- a/include/system/camera.h +++ b/include/system/camera.h @@ -194,7 +194,12 @@ enum { /** The facing of the camera is opposite to that of the screen. */ CAMERA_FACING_BACK = 0, /** The facing of the camera is the same as that of the screen. */ - CAMERA_FACING_FRONT = 1 + CAMERA_FACING_FRONT = 1, + /** + * The facing of the camera is not fixed relative to the screen. + * The cameras with this facing are external cameras, e.g. USB cameras. + */ + CAMERA_FACING_EXTERNAL = 2 }; enum { diff --git a/include/system/graphics.h b/include/system/graphics.h index c3fca97..c9f5950 100644 --- a/include/system/graphics.h +++ b/include/system/graphics.h @@ -45,9 +45,12 @@ enum { /* * "linear" color pixel formats: * - * The pixel formats below contain sRGB data but are otherwise treated - * as linear formats, i.e.: no special operation is performed when - * reading or writing into a buffer in one of these formats + * When used with ANativeWindow, the dataSpace field describes the color + * space of the buffer. + * + * The color space determines, for example, if the formats are linear or + * gamma-corrected; or whether any special operations are performed when + * reading or writing into a buffer in one of these formats. */ HAL_PIXEL_FORMAT_RGBA_8888 = 1, HAL_PIXEL_FORMAT_RGBX_8888 = 2, @@ -56,28 +59,6 @@ enum { HAL_PIXEL_FORMAT_BGRA_8888 = 5, /* - * sRGB color pixel formats: - * - * The red, green and blue components are stored in sRGB space, and converted - * to linear space when read, using the standard sRGB to linear equation: - * - * Clinear = Csrgb / 12.92 for Csrgb <= 0.04045 - * = (Csrgb + 0.055 / 1.055)^2.4 for Csrgb > 0.04045 - * - * When written the inverse transformation is performed: - * - * Csrgb = 12.92 * Clinear for Clinear <= 0.0031308 - * = 1.055 * Clinear^(1/2.4) - 0.055 for Clinear > 0.0031308 - * - * - * The alpha component, if present, is always stored in linear space and - * is left unmodified when read or written. - * - */ - HAL_PIXEL_FORMAT_sRGB_A_8888 = 0xC, - HAL_PIXEL_FORMAT_sRGB_X_8888 = 0xD, - - /* * 0x100 - 0x1FF * * This range is reserved for pixel formats that are specific to the HAL @@ -111,6 +92,8 @@ enum { * cr_offset = y_size * cb_offset = y_size + c_size * + * When used with ANativeWindow, the dataSpace field describes the color + * space of the buffer. */ HAL_PIXEL_FORMAT_YV12 = 0x32315659, // YCrCb 4:2:0 Planar @@ -135,6 +118,8 @@ enum { * * size = stride * height * + * When used with ANativeWindow, the dataSpace field describes the color + * space of the buffer. */ HAL_PIXEL_FORMAT_Y8 = 0x20203859, @@ -159,6 +144,10 @@ enum { * * size = stride * height * 2 * + * When used with ANativeWindow, the dataSpace field describes the color + * space of the buffer, except that dataSpace field + * HAL_DATASPACE_DEPTH indicates that this buffer contains a depth + * image where each sample is a distance value measured by a depth camera. */ HAL_PIXEL_FORMAT_Y16 = 0x20363159, @@ -167,7 +156,7 @@ enum { * * This format is exposed outside of the camera HAL to applications. * - * RAW_SENSOR is a single-channel, 16-bit, little endian format, typically + * RAW16 is a single-channel, 16-bit, little endian format, typically * representing raw Bayer-pattern images from an image sensor, with minimal * processing. * @@ -193,9 +182,12 @@ enum { * - GRALLOC_USAGE_HW_CAMERA_* * - GRALLOC_USAGE_SW_* * - GRALLOC_USAGE_RENDERSCRIPT + * + * When used with ANativeWindow, the dataSpace should be + * HAL_DATASPACE_ARBITRARY, as raw image sensor buffers require substantial + * extra metadata to define. */ HAL_PIXEL_FORMAT_RAW16 = 0x20, - HAL_PIXEL_FORMAT_RAW_SENSOR = 0x20, // TODO(rubenbrunk): Remove RAW_SENSOR. /* * Android RAW10 format: @@ -244,6 +236,10 @@ enum { * - GRALLOC_USAGE_HW_CAMERA_* * - GRALLOC_USAGE_SW_* * - GRALLOC_USAGE_RENDERSCRIPT + * + * When used with ANativeWindow, the dataSpace field should be + * HAL_DATASPACE_ARBITRARY, as raw image sensor buffers require substantial + * extra metadata to define. */ HAL_PIXEL_FORMAT_RAW10 = 0x25, @@ -261,6 +257,10 @@ enum { * - GRALLOC_USAGE_HW_CAMERA_* * - GRALLOC_USAGE_SW_* * - GRALLOC_USAGE_RENDERSCRIPT + * + * When used with ANativeWindow, the dataSpace field should be + * HAL_DATASPACE_ARBITRARY, as raw image sensor buffers require substantial + * extra metadata to define. */ HAL_PIXEL_FORMAT_RAW_OPAQUE = 0x24, @@ -276,6 +276,16 @@ enum { * * Buffers of this format must have a height of 1, and width equal to their * size in bytes. + * + * When used with ANativeWindow, the mapping of the dataSpace field to + * buffer contents for BLOB is as follows: + * + * dataSpace value | Buffer contents + * -------------------------------+----------------------------------------- + * HAL_DATASPACE_JFIF | An encoded JPEG image + * HAL_DATASPACE_DEPTH | An android_depth_points buffer + * Other | Unsupported + * */ HAL_PIXEL_FORMAT_BLOB = 0x21, @@ -292,6 +302,8 @@ enum { * framework will assume that sampling the texture will always return an * alpha value of 1.0 (i.e. the buffer contains only opaque pixel values). * + * When used with ANativeWindow, the dataSpace field describes the color + * space of the buffer. */ HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED = 0x22, @@ -311,6 +323,9 @@ enum { * * This format is locked for use by gralloc's (*lock_ycbcr) method, and * locking with the (*lock) method will return an error. + * + * When used with ANativeWindow, the dataSpace field describes the color + * space of the buffer. */ HAL_PIXEL_FORMAT_YCbCr_420_888 = 0x23, @@ -355,6 +370,42 @@ struct android_ycbcr { }; /** + * Structure used to define depth point clouds for format HAL_PIXEL_FORMAT_BLOB + * with dataSpace value of HAL_DATASPACE_DEPTH. + * When locking a native buffer of the above format and dataSpace value, + * the vaddr pointer can be cast to this structure. + * + * A variable-length list of (x,y,z) 3D points, as floats. + * + * @num_points is the number of points in the list + * + * @xyz_points is the flexible array of floating-point values. + * It contains (num_points) * 3 floats. + * + * For example: + * android_depth_points d = get_depth_buffer(); + * struct { + * float x; float y; float z; + * } firstPoint, lastPoint; + * + * firstPoint.x = d.xyz_points[0]; + * firstPoint.y = d.xyz_points[1]; + * firstPoint.z = d.xyz_points[2]; + * lastPoint.x = d.xyz_points[(d.num_points - 1) * 3 + 0]; + * lastPoint.y = d.xyz_points[(d.num_points - 1) * 3 + 1]; + * lastPoint.z = d.xyz_points[(d.num_points - 1) * 3 + 2]; + */ + +struct android_depth_points { + uint32_t num_points; + + /** reserved for future use, set to 0 by gralloc's (*lock)() */ + uint32_t reserved[8]; + + float xyz_points[]; +}; + +/** * Transformation definitions * * IMPORTANT NOTE: @@ -378,19 +429,33 @@ enum { }; /** - * Colorspace Definitions + * Dataspace Definitions * ====================== * - * Colorspace is the definition of how pixel values should be interpreted. - * It includes primaries (including white point) and the transfer - * characteristic function, which describes both gamma curve and numeric - * range (within the bit depth). + * Dataspace is the definition of how pixel values should be interpreted. + * + * For many formats, this is the colorspace of the image data, which includes + * primaries (including white point) and the transfer characteristic function, + * which describes both gamma curve and numeric range (within the bit depth). + * + * Other dataspaces include depth measurement data from a depth camera. */ -enum { +typedef enum android_dataspace { + /* + * Default-assumption data space, when not explicitly specified. + * + * It is safest to assume the buffer is an image with sRGB primaries and + * encoding ranges, but the consumer and/or the producer of the data may + * simply be using defaults. No automatic gamma transform should be + * expected, except for a possible display gamma transform when drawn to a + * screen. + */ + HAL_DATASPACE_UNKNOWN = 0x0, + /* - * Arbitrary colorspace with manually defined characteristics. - * Colorspace definition must be communicated separately. + * Arbitrary dataspace with manually defined characteristics. Definition + * for colorspaces or other meaning must be communicated separately. * * This is used when specifying primaries, transfer characteristics, * etc. separately. @@ -399,7 +464,57 @@ enum { * where a colorspace can have separately defined primaries, transfer * characteristics, etc. */ - HAL_COLORSPACE_ARBITRARY = 0x1, + HAL_DATASPACE_ARBITRARY = 0x1, + + /* + * RGB Colorspaces + * ----------------- + * + * Primaries are given using (x,y) coordinates in the CIE 1931 definition + * of x and y specified by ISO 11664-1. + * + * Transfer characteristics are the opto-electronic transfer characteristic + * at the source as a function of linear optical intensity (luminance). + */ + + /* + * sRGB linear encoding: + * + * The red, green, and blue components are stored in sRGB space, but + * are linear, not gamma-encoded. + * The RGB primaries and the white point are the same as BT.709. + * + * The values are encoded using the full range ([0,255] for 8-bit) for all + * components. + */ + HAL_DATASPACE_SRGB_LINEAR = 0x200, + + /* + * sRGB gamma encoding: + * + * The red, green and blue components are stored in sRGB space, and + * converted to linear space when read, using the standard sRGB to linear + * equation: + * + * Clinear = Csrgb / 12.92 for Csrgb <= 0.04045 + * = (Csrgb + 0.055 / 1.055)^2.4 for Csrgb > 0.04045 + * + * When written the inverse transformation is performed: + * + * Csrgb = 12.92 * Clinear for Clinear <= 0.0031308 + * = 1.055 * Clinear^(1/2.4) - 0.055 for Clinear > 0.0031308 + * + * + * The alpha component, if present, is always stored in linear space and + * is left unmodified when read or written. + * + * The RGB primaries and the white point are the same as BT.709. + * + * The values are encoded using the full range ([0,255] for 8-bit) for all + * components. + * + */ + HAL_DATASPACE_SRGB = 0x201, /* * YCbCr Colorspaces @@ -429,7 +544,7 @@ enum { * red 0.640 0.330 * white (D65) 0.3127 0.3290 */ - HAL_COLORSPACE_JFIF = 0x101, + HAL_DATASPACE_JFIF = 0x101, /* * ITU-R Recommendation 601 (BT.601) - 625-line @@ -456,7 +571,7 @@ enum { * red 0.640 0.330 * white (D65) 0.3127 0.3290 */ - HAL_COLORSPACE_BT601_625 = 0x102, + HAL_DATASPACE_BT601_625 = 0x102, /* * ITU-R Recommendation 601 (BT.601) - 525-line @@ -483,7 +598,7 @@ enum { * red 0.630 0.340 * white (D65) 0.3127 0.3290 */ - HAL_COLORSPACE_BT601_525 = 0x103, + HAL_DATASPACE_BT601_525 = 0x103, /* * ITU-R Recommendation 709 (BT.709) @@ -504,8 +619,20 @@ enum { * red 0.640 0.330 * white (D65) 0.3127 0.3290 */ - HAL_COLORSPACE_BT709 = 0x104, -}; + HAL_DATASPACE_BT709 = 0x104, + + /* + * The buffer contains depth ranging measurements from a depth camera. + * This value is valid with formats: + * HAL_PIXEL_FORMAT_Y16: 16-bit single channel depth image. + * HAL_PIXEL_FORMAT_BLOB: A depth point cloud, as + * a variable-length float (x,y,z) coordinate point list. + * The point cloud will be represented with the android_depth_points + * structure. + */ + HAL_DATASPACE_DEPTH = 0x1000 + +} android_dataspace_t; #ifdef __cplusplus } diff --git a/include/system/radio.h b/include/system/radio.h new file mode 100644 index 0000000..a088526 --- /dev/null +++ b/include/system/radio.h @@ -0,0 +1,247 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_RADIO_H +#define ANDROID_RADIO_H + +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <sys/cdefs.h> +#include <sys/types.h> + + +#define RADIO_NUM_BANDS_MAX 16 +#define RADIO_NUM_SPACINGS_MAX 16 +#define RADIO_STRING_LEN_MAX 128 + +/* + * Radio hardware module class. A given radio hardware module HAL is of one class + * only. The platform can not have more than one hardware module of each class. + * Current version of the framework only supports RADIO_CLASS_AM_FM. + */ +typedef enum { + RADIO_CLASS_AM_FM = 0, /* FM (including HD radio) and AM */ + RADIO_CLASS_SAT = 1, /* Satellite Radio */ + RADIO_CLASS_DT = 2, /* Digital Radio (DAB) */ +} radio_class_t; + +/* value for field "type" of radio band described in struct radio_hal_band_config */ +typedef enum { + RADIO_BAND_AM = 0, /* Amplitude Modulation band: LW, MW, SW */ + RADIO_BAND_FM = 1, /* Frequency Modulation band: FM */ + RADIO_BAND_FM_HD = 2, /* FM HD Radio / DRM (IBOC) */ + RADIO_BAND_AM_HD = 3, /* AM HD Radio / DRM (IBOC) */ +} radio_band_t; + +/* RDS variant implemented. A struct radio_hal_fm_band_config can list none or several. */ +enum { + RADIO_RDS_NONE = 0x0, + RADIO_RDS_WORLD = 0x01, + RADIO_RDS_US = 0x02, +}; +typedef unsigned int radio_rds_t; + +/* FM deemphasis variant implemented. A struct radio_hal_fm_band_config can list one or more. */ +enum { + RADIO_DEEMPHASIS_50 = 0x1, + RADIO_DEEMPHASIS_75 = 0x2, +}; +typedef unsigned int radio_deemphasis_t; + +/* Region a particular radio band configuration corresponds to. Not used at the HAL. + * Derived by the framework when converting the band descriptors retrieved from the HAL to + * individual band descriptors for each supported region. */ +typedef enum { + RADIO_REGION_NONE = -1, + RADIO_REGION_ITU_1 = 0, + RADIO_REGION_ITU_2 = 1, + RADIO_REGION_OIRT = 2, + RADIO_REGION_JAPAN = 3, + RADIO_REGION_KOREA = 4, +} radio_region_t; + +/* scanning direction for scan() and step() tuner APIs */ +typedef enum { + RADIO_DIRECTION_UP, + RADIO_DIRECTION_DOWN +} radio_direction_t; + +/* unique handle allocated to a radio module */ +typedef unsigned int radio_handle_t; + +/* Opaque meta data structure used by radio meta data API (see system/radio_metadata.h) */ +typedef struct radio_medtadata radio_metadata_t; + + +/* Additional attributes for an FM band configuration */ +typedef struct radio_hal_fm_band_config { + radio_deemphasis_t deemphasis; /* deemphasis variant */ + bool stereo; /* stereo supported */ + radio_rds_t rds; /* RDS variants supported */ + bool ta; /* Traffic Announcement supported */ + bool af; /* Alternate Frequency supported */ +} radio_hal_fm_band_config_t; + +/* Additional attributes for an AM band configuration */ +typedef struct radio_hal_am_band_config { + bool stereo; /* stereo supported */ +} radio_hal_am_band_config_t; + +/* Radio band configuration. Describes a given band supported by the radio module. + * The HAL can expose only one band per type with the the maximum range supported and all options. + * THe framework will derive the actual regions were this module can operate and expose separate + * band configurations for applications to chose from. */ +typedef struct radio_hal_band_config { + radio_band_t type; + bool antenna_connected; + unsigned int lower_limit; + unsigned int upper_limit; + unsigned int num_spacings; + unsigned int spacings[RADIO_NUM_SPACINGS_MAX]; + union { + radio_hal_fm_band_config_t fm; + radio_hal_am_band_config_t am; + }; +} radio_hal_band_config_t; + +/* Used internally by the framework to represent a band for s specific region */ +typedef struct radio_band_config { + radio_region_t region; + radio_hal_band_config_t band; +} radio_band_config_t; + + +/* Exposes properties of a given hardware radio module. + * NOTE: current framework implementation supports only one audio source (num_audio_sources = 1). + * The source corresponds to AUDIO_DEVICE_IN_FM_TUNER. + * If more than one tuner is supported (num_tuners > 1), only one can be connected to the audio + * source. */ +typedef struct radio_hal_properties { + radio_class_t class_id; /* Class of this module. E.g RADIO_CLASS_AM_FM */ + char implementor[RADIO_STRING_LEN_MAX]; /* implementor name */ + char product[RADIO_STRING_LEN_MAX]; /* product name */ + char version[RADIO_STRING_LEN_MAX]; /* product version */ + char serial[RADIO_STRING_LEN_MAX]; /* serial number (for subscription services) */ + unsigned int num_tuners; /* number of tuners controllable independently */ + unsigned int num_audio_sources; /* number of audio sources driven simultaneously */ + bool supports_capture; /* the hardware supports capture of audio source audio HAL */ + unsigned int num_bands; /* number of band descriptors */ + radio_hal_band_config_t bands[RADIO_NUM_BANDS_MAX]; /* band descriptors */ +} radio_hal_properties_t; + +/* Used internally by the framework. Same information as in struct radio_hal_properties plus a + * unique handle and one band configuration per region. */ +typedef struct radio_properties { + radio_handle_t handle; + radio_class_t class_id; + char implementor[RADIO_STRING_LEN_MAX]; + char product[RADIO_STRING_LEN_MAX]; + char version[RADIO_STRING_LEN_MAX]; + char serial[RADIO_STRING_LEN_MAX]; + unsigned int num_tuners; + unsigned int num_audio_sources; + bool supports_capture; + unsigned int num_bands; + radio_band_config_t bands[RADIO_NUM_BANDS_MAX]; +} radio_properties_t; + +/* Radio program information. Returned by the HAL with event RADIO_EVENT_TUNED. + * Contains information on currently tuned channel. + */ +typedef struct radio_program_info { + unsigned int channel; /* current channel. (e.g kHz for band type RADIO_BAND_FM) */ + unsigned int sub_channel; /* current sub channel. (used for RADIO_BAND_FM_HD) */ + bool tuned; /* tuned to a program or not */ + bool stereo; /* program is stereo or not */ + bool digital; /* digital program or not (e.g HD Radio program) */ + unsigned int signal_strength; /* signal strength from 0 to 100 */ + radio_metadata_t *metadata; /* non null if meta data are present (e.g PTY, song title ...) */ +} radio_program_info_t; + + +/* Events sent to the framework via the HAL callback. An event can notify the completion of an + * asynchronous command (configuration, tune, scan ...) or a spontaneous change (antenna connection, + * failure, AF switching, meta data reception... */ +enum { + RADIO_EVENT_HW_FAILURE = 0, /* hardware module failure. Requires reopening the tuner */ + RADIO_EVENT_CONFIG = 1, /* configuration change completed */ + RADIO_EVENT_ANTENNA = 2, /* Antenna connected, disconnected */ + RADIO_EVENT_TUNED = 3, /* tune, step, scan completed */ + RADIO_EVENT_METADATA = 4, /* New meta data received */ + RADIO_EVENT_TA = 5, /* Traffic announcement start or stop */ + RADIO_EVENT_AF_SWITCH = 6, /* Switch to Alternate Frequency */ + // begin framework only events + RADIO_EVENT_CONTROL = 100, /* loss/gain of tuner control */ + RADIO_EVENT_SERVER_DIED = 101, /* radio service died */ +}; +typedef unsigned int radio_event_type_t; + +/* Event passed to the framework by the HAL callback */ +typedef struct radio_hal_event { + radio_event_type_t type; /* event type */ + int status; /* used by RADIO_EVENT_CONFIG, RADIO_EVENT_TUNED */ + union { + bool on; /* RADIO_EVENT_ANTENNA, RADIO_EVENT_TA */ + radio_hal_band_config_t config; /* RADIO_EVENT_CONFIG */ + radio_program_info_t info; /* RADIO_EVENT_TUNED, RADIO_EVENT_AF_SWITCH */ + radio_metadata_t *metadata; /* RADIO_EVENT_METADATA */ + }; +} radio_hal_event_t; + +/* Used internally by the framework. Same information as in struct radio_hal_event */ +typedef struct radio_event { + radio_event_type_t type; + int status; + union { + bool on; + radio_band_config_t config; + radio_program_info_t info; + radio_metadata_t *metadata; /* offset from start of struct when in shared memory */ + }; +} radio_event_t; + + +static radio_rds_t radio_rds_for_region(bool rds, radio_region_t region) { + if (!rds) + return RADIO_RDS_NONE; + switch(region) { + case RADIO_REGION_ITU_1: + case RADIO_REGION_OIRT: + case RADIO_REGION_JAPAN: + case RADIO_REGION_KOREA: + return RADIO_RDS_WORLD; + case RADIO_REGION_ITU_2: + return RADIO_RDS_US; + default: + return RADIO_REGION_NONE; + } +} + +static radio_deemphasis_t radio_demephasis_for_region(radio_region_t region) { + switch(region) { + case RADIO_REGION_KOREA: + case RADIO_REGION_ITU_2: + return RADIO_DEEMPHASIS_75; + case RADIO_REGION_ITU_1: + case RADIO_REGION_OIRT: + case RADIO_REGION_JAPAN: + default: + return RADIO_DEEMPHASIS_50; + } +} + +#endif // ANDROID_RADIO_H diff --git a/include/system/window.h b/include/system/window.h index bf93b79..af0418b 100644 --- a/include/system/window.h +++ b/include/system/window.h @@ -262,6 +262,12 @@ enum { * the aspect ratio of the buffers produced. */ NATIVE_WINDOW_STICKY_TRANSFORM = 11, + + /** + * The default data space for the buffers as set by the consumer. + * The values are defined in graphics.h. + */ + NATIVE_WINDOW_DEFAULT_DATASPACE = 12 }; /* Valid operations for the (*perform)() hook. @@ -294,6 +300,7 @@ enum { NATIVE_WINDOW_SET_POST_TRANSFORM_CROP = 16, /* private */ NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM = 17,/* private */ NATIVE_WINDOW_SET_SIDEBAND_STREAM = 18, + NATIVE_WINDOW_SET_BUFFERS_DATASPACE = 19 }; /* parameter for NATIVE_WINDOW_[API_][DIS]CONNECT */ @@ -498,6 +505,7 @@ struct ANativeWindow * NATIVE_WINDOW_SET_BUFFERS_GEOMETRY (deprecated) * NATIVE_WINDOW_SET_BUFFERS_TRANSFORM * NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP + * NATIVE_WINDOW_SET_BUFFERS_DATASPACE * NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS * NATIVE_WINDOW_SET_BUFFERS_FORMAT * NATIVE_WINDOW_SET_SCALING_MODE (private) @@ -799,6 +807,26 @@ static inline int native_window_set_buffers_format( } /* + * native_window_set_buffers_data_space(..., int dataSpace) + * All buffers queued after this call will be associated with the dataSpace + * parameter specified. + * + * dataSpace specifies additional information about the buffer that's dependent + * on the buffer format and the endpoints. For example, it can be used to convey + * the color space of the image data in the buffer, or it can be used to + * indicate that the buffers contain depth measurement data instead of color + * images. The default dataSpace is 0, HAL_DATASPACE_UNKNOWN, unless it has been + * overridden by the consumer. + */ +static inline int native_window_set_buffers_data_space( + struct ANativeWindow* window, + android_dataspace_t dataSpace) +{ + return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_DATASPACE, + dataSpace); +} + +/* * native_window_set_buffers_transform(..., int transform) * All buffers queued after this call will be displayed transformed according * to the transform parameter specified. diff --git a/include/sysutils/NetlinkEvent.h b/include/sysutils/NetlinkEvent.h index 4fa49c5..a428d37 100644 --- a/include/sysutils/NetlinkEvent.h +++ b/include/sysutils/NetlinkEvent.h @@ -21,13 +21,30 @@ #define NL_PARAMS_MAX 32 class NetlinkEvent { +public: + enum class Action { + kUnknown = 0, + kAdd = 1, + kRemove = 2, + kChange = 3, + kLinkUp = 4, + kLinkDown = 5, + kAddressUpdated = 6, + kAddressRemoved = 7, + kRdnss = 8, + kRouteUpdated = 9, + kRouteRemoved = 10, + }; + +private: int mSeq; char *mPath; - int mAction; + Action mAction; char *mSubsystem; char *mParams[NL_PARAMS_MAX]; public: + // STOPSHIP: remove these deprecated constants once we have updated prebuilts const static int NlActionUnknown; const static int NlActionAdd; const static int NlActionRemove; @@ -47,7 +64,7 @@ public: const char *findParam(const char *paramName); const char *getSubsystem() { return mSubsystem; } - int getAction() { return mAction; } + Action getAction() { return mAction; } void dump(); diff --git a/include/utils/Looper.h b/include/utils/Looper.h index 15c9891..a381251 100644 --- a/include/utils/Looper.h +++ b/include/utils/Looper.h @@ -386,11 +386,12 @@ public: void removeMessages(const sp<MessageHandler>& handler, int what); /** - * Return whether this looper's thread is currently idling -- that is, whether it - * stopped waiting for more work to do. Note that this is intrinsically racy, since - * its state can change before you get the result back. + * Returns whether this looper's thread is currently polling for more work to do. + * This is a good signal that the loop is still alive rather than being stuck + * handling a callback. Note that this method is intrinsically racy, since the + * state of the loop can change before you get the result back. */ - bool isIdling() const; + bool isPolling() const; /** * Prepares a looper associated with the calling thread, and returns it. @@ -419,8 +420,12 @@ private: struct Request { int fd; int ident; + int events; + int seq; sp<LooperCallback> callback; void* data; + + void initEventItem(struct epoll_event* eventItem) const; }; struct Response { @@ -451,12 +456,14 @@ private: // Whether we are currently waiting for work. Not protected by a lock, // any use of it is racy anyway. - volatile bool mIdling; + volatile bool mPolling; - int mEpollFd; // immutable + int mEpollFd; // guarded by mLock but only modified on the looper thread + bool mEpollRebuildRequired; // guarded by mLock // Locked list of file descriptor monitoring requests. KeyedVector<int, Request> mRequests; // guarded by mLock + int mNextRequestSeq; // This state is only used privately by pollOnce and does not require a lock since // it runs on a single thread. @@ -465,11 +472,15 @@ private: nsecs_t mNextMessageUptime; // set to LLONG_MAX when none int pollInner(int timeoutMillis); + int removeFd(int fd, int seq); void awoken(); void pushResponse(int events, const Request& request); + void rebuildEpollLocked(); + void scheduleEpollRebuildLocked(); static void initTLSKey(); static void threadDestructor(void *st); + static void initEpollEvent(struct epoll_event* eventItem); }; } // namespace android diff --git a/init/init.cpp b/init/init.cpp index e1c82a4..a27221a 100644 --- a/init/init.cpp +++ b/init/init.cpp @@ -15,6 +15,7 @@ */ #include <ctype.h> +#include <dirent.h> #include <errno.h> #include <fcntl.h> #include <libgen.h> @@ -34,12 +35,16 @@ #include <termios.h> #include <unistd.h> +#include <memory> + #include <mtd/mtd-user.h> #include <selinux/selinux.h> #include <selinux/label.h> #include <selinux/android.h> +#include <base/file.h> +#include <base/stringprintf.h> #include <cutils/android_reboot.h> #include <cutils/fs.h> #include <cutils/iosched_policy.h> @@ -59,6 +64,9 @@ #include "ueventd.h" #include "watchdogd.h" +using android::base::ReadFileToString; +using android::base::StringPrintf; + struct selabel_handle *sehandle; struct selabel_handle *sehandle_prop; @@ -66,8 +74,6 @@ static int property_triggers_enabled = 0; static char console[32]; static char bootmode[32]; -static char hardware[32]; -static unsigned revision = 0; static char qemu[32]; static struct action *cur_action = NULL; @@ -773,6 +779,8 @@ static void export_kernel_boot_props(void) { "ro.boot.mode", "ro.bootmode", "unknown", }, { "ro.boot.baseband", "ro.baseband", "unknown", }, { "ro.boot.bootloader", "ro.bootloader", "unknown", }, + { "ro.boot.hardware", "ro.hardware", "unknown", }, + { "ro.boot.revision", "ro.revision", "0", }, }; for (i = 0; i < ARRAY_SIZE(prop_map); i++) { @@ -791,16 +799,6 @@ static void export_kernel_boot_props(void) property_get("ro.bootmode", tmp); strlcpy(bootmode, tmp, sizeof(bootmode)); - /* if this was given on kernel command line, override what we read - * before (e.g. from /proc/cpuinfo), if anything */ - ret = property_get("ro.boot.hardware", tmp); - if (ret) - strlcpy(hardware, tmp, sizeof(hardware)); - property_set("ro.hardware", hardware); - - snprintf(tmp, PROP_VALUE_MAX, "%d", revision); - property_set("ro.revision", tmp); - /* TODO: these are obsolete. We should delete them */ if (!strcmp(bootmode,"factory")) property_set("ro.factorytest", "1"); @@ -810,6 +808,40 @@ static void export_kernel_boot_props(void) property_set("ro.factorytest", "0"); } +static void process_kernel_dt(void) +{ + static const char android_dir[] = "/proc/device-tree/firmware/android"; + + std::string file_name = StringPrintf("%s/compatible", android_dir); + + std::string dt_file; + ReadFileToString(file_name, &dt_file); + if (!dt_file.compare("android,firmware")) { + ERROR("firmware/android is not compatible with 'android,firmware'\n"); + return; + } + + std::unique_ptr<DIR, int(*)(DIR*)>dir(opendir(android_dir), closedir); + if (!dir) + return; + + struct dirent *dp; + while ((dp = readdir(dir.get())) != NULL) { + if (dp->d_type != DT_REG || !strcmp(dp->d_name, "compatible")) + continue; + + file_name = StringPrintf("%s/%s", android_dir, dp->d_name); + + ReadFileToString(file_name, &dt_file); + std::replace(dt_file.begin(), dt_file.end(), ',', '.'); + + std::string property_name = StringPrintf("ro.boot.%s", dp->d_name); + if (property_set(property_name.c_str(), dt_file.c_str())) { + ERROR("Could not set property %s to value %s", property_name.c_str(), dt_file.c_str()); + } + } +} + static void process_kernel_cmdline(void) { /* don't expose the raw commandline to nonpriv processes */ @@ -822,11 +854,6 @@ static void process_kernel_cmdline(void) import_kernel_cmdline(0, import_kernel_nv); if (qemu[0]) import_kernel_cmdline(1, import_kernel_nv); - - /* now propogate the info given on command line to internal variables - * used by init as well as the current required properties - */ - export_kernel_boot_props(); } static int property_service_init_action(int nargs, char **args) @@ -1014,10 +1041,17 @@ int main(int argc, char** argv) { klog_init(); property_init(); - get_hardware_name(hardware, &revision); - + process_kernel_dt(); + /* in case one is passing arguments both on the command line and in DT + * Properties set in DT always have priority over the command-line ones + */ process_kernel_cmdline(); + /* now propogate the kernel variables to internal variables + * used by init as well as the current required properties + */ + export_kernel_boot_props(); + selinux_callback cb; cb.func_log = log_callback; selinux_set_callback(SELINUX_CB_LOG, cb); diff --git a/init/ueventd.cpp b/init/ueventd.cpp index d56b91a..5af6e3d 100644 --- a/init/ueventd.cpp +++ b/init/ueventd.cpp @@ -30,28 +30,13 @@ #include "util.h" #include "devices.h" #include "ueventd_parser.h" - -static char hardware[32]; -static unsigned revision = 0; - -static void import_kernel_nv(char *name, int in_qemu) -{ - if (*name != '\0') { - char *value = strchr(name, '='); - if (value != NULL) { - *value++ = 0; - if (!strcmp(name,"androidboot.hardware")) - { - strlcpy(hardware, value, sizeof(hardware)); - } - } - } -} +#include "property_service.h" int ueventd_main(int argc, char **argv) { struct pollfd ufd; int nr; + char hardware[PROP_VALUE_MAX]; char tmp[32]; /* @@ -83,12 +68,7 @@ int ueventd_main(int argc, char **argv) INFO("starting ueventd\n"); - /* Respect hardware passed in through the kernel cmd line. Here we will look - * for androidboot.hardware param in kernel cmdline, and save its value in - * hardware[]. */ - import_kernel_cmdline(0, import_kernel_nv); - - get_hardware_name(hardware, &revision); + property_get("ro.hardware", hardware); ueventd_parse_config_file("/ueventd.rc"); diff --git a/init/util.cpp b/init/util.cpp index c805083..8b238d4 100644 --- a/init/util.cpp +++ b/init/util.cpp @@ -400,39 +400,6 @@ void open_devnull_stdio(void) exit(1); } -void get_hardware_name(char *hardware, unsigned int *revision) { - // Hardware string was provided on kernel command line. - if (hardware[0]) { - return; - } - - FILE* fp = fopen("/proc/cpuinfo", "re"); - if (fp == NULL) { - return; - } - char buf[1024]; - while (fgets(buf, sizeof(buf), fp) != NULL) { - if (strncmp(buf, "Hardware", 8) == 0) { - const char* hw = strstr(buf, ": "); - if (hw) { - hw += 2; - size_t n = 0; - while (*hw) { - if (!isspace(*hw)) { - hardware[n++] = tolower(*hw); - } - hw++; - if (n == 31) break; - } - hardware[n] = 0; - } - } else if (strncmp(buf, "Revision", 8) == 0) { - sscanf(buf, "Revision : %ux", revision); - } - } - fclose(fp); -} - void import_kernel_cmdline(int in_qemu, void (*import_kernel_nv)(char *name, int in_qemu)) { diff --git a/init/util.h b/init/util.h index 77da3ac..e0b3c69 100644 --- a/init/util.h +++ b/init/util.h @@ -42,7 +42,6 @@ void make_link(const char *oldpath, const char *newpath); void remove_link(const char *oldpath, const char *newpath); int wait_for_file(const char *filename, int timeout); void open_devnull_stdio(void); -void get_hardware_name(char *hardware, unsigned int *revision); void import_kernel_cmdline(int in_qemu, void (*import_kernel_nv)(char *name, int in_qemu)); int make_dir(const char *path, mode_t mode); int restorecon(const char *pathname); diff --git a/libion/ion.c b/libion/ion.c index 4908932..d1984bd 100644 --- a/libion/ion.c +++ b/libion/ion.c @@ -91,6 +91,7 @@ int ion_map(int fd, ion_user_handle_t handle, size_t length, int prot, int flags, off_t offset, unsigned char **ptr, int *map_fd) { int ret; + unsigned char *tmp_ptr; struct ion_fd_data data = { .handle = handle, }; @@ -103,16 +104,17 @@ int ion_map(int fd, ion_user_handle_t handle, size_t length, int prot, ret = ion_ioctl(fd, ION_IOC_MAP, &data); if (ret < 0) return ret; - *map_fd = data.fd; - if (*map_fd < 0) { + if (data.fd < 0) { ALOGE("map ioctl returned negative fd\n"); return -EINVAL; } - *ptr = mmap(NULL, length, prot, flags, *map_fd, offset); - if (*ptr == MAP_FAILED) { + tmp_ptr = mmap(NULL, length, prot, flags, data.fd, offset); + if (tmp_ptr == MAP_FAILED) { ALOGE("mmap failed: %s\n", strerror(errno)); return -errno; } + *map_fd = data.fd; + *ptr = tmp_ptr; return ret; } @@ -129,11 +131,11 @@ int ion_share(int fd, ion_user_handle_t handle, int *share_fd) ret = ion_ioctl(fd, ION_IOC_SHARE, &data); if (ret < 0) return ret; - *share_fd = data.fd; - if (*share_fd < 0) { + if (data.fd < 0) { ALOGE("share ioctl returned negative fd\n"); return -EINVAL; } + *share_fd = data.fd; return ret; } diff --git a/libnetutils/dhcp_utils.c b/libnetutils/dhcp_utils.c index 70e37c6..c6b9fe4 100644 --- a/libnetutils/dhcp_utils.c +++ b/libnetutils/dhcp_utils.c @@ -1,16 +1,16 @@ /* * Copyright 2008, 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 + * 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 + * 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 + * 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. */ @@ -33,7 +33,7 @@ static const char DHCP_CONFIG_PATH[] = "/system/etc/dhcpcd/dhcpcd.conf"; static const int NAP_TIME = 200; /* wait for 200ms at a time */ /* when polling for property values */ static const char DAEMON_NAME_RENEW[] = "iprenew"; -static char errmsg[100]; +static char errmsg[100] = "\0"; /* interface length for dhcpcd daemon start (dhcpcd_<interface> as defined in init.rc file) * or for filling up system properties dhcpcd.<interface>.ipaddress, dhcpcd.<interface>.dns1 * and other properties on a successful bind @@ -74,7 +74,7 @@ static int wait_for_property(const char *name, const char *desired_value, int ma while (maxnaps-- >= 0) { if (property_get(name, value, NULL)) { - if (desired_value == NULL || + if (desired_value == NULL || strcmp(value, desired_value) == 0) { return 0; } @@ -169,6 +169,47 @@ static int fill_ip_info(const char *interface, } /* + * Get any available DHCP results. + */ +int dhcp_get_results(const char *interface, + char *ipaddr, + char *gateway, + uint32_t *prefixLength, + char *dns[], + char *server, + uint32_t *lease, + char *vendorInfo, + char *domain, + char *mtu) +{ + char result_prop_name[PROPERTY_KEY_MAX]; + char prop_value[PROPERTY_VALUE_MAX]; + + /* Interface name after converting p2p0-p2p0-X to p2p to reuse system properties */ + char p2p_interface[MAX_INTERFACE_LENGTH]; + get_p2p_interface_replacement(interface, p2p_interface); + snprintf(result_prop_name, sizeof(result_prop_name), "%s.%s.result", + DHCP_PROP_NAME_PREFIX, + p2p_interface); + + memset(prop_value, '\0', PROPERTY_VALUE_MAX); + if (!property_get(result_prop_name, prop_value, NULL)) { + snprintf(errmsg, sizeof(errmsg), "%s", "DHCP result property was not set"); + return -1; + } + if (strcmp(prop_value, "ok") == 0) { + if (fill_ip_info(interface, ipaddr, gateway, prefixLength, dns, + server, lease, vendorInfo, domain, mtu) == -1) { + return -1; + } + return 0; + } else { + snprintf(errmsg, sizeof(errmsg), "DHCP result was %s", prop_value); + return -1; + } +} + +/* * Start the dhcp client daemon, and wait for it to finish * configuring the interface. * @@ -177,16 +218,7 @@ static int fill_ip_info(const char *interface, * Example: * service dhcpcd_<interface> /system/bin/dhcpcd -ABKL -f dhcpcd.conf */ -int dhcp_do_request(const char *interface, - char *ipaddr, - char *gateway, - uint32_t *prefixLength, - char *dns[], - char *server, - uint32_t *lease, - char *vendorInfo, - char *domain, - char *mtu) +int dhcp_start(const char *interface) { char result_prop_name[PROPERTY_KEY_MAX]; char daemon_prop_name[PROPERTY_KEY_MAX]; @@ -230,21 +262,7 @@ int dhcp_do_request(const char *interface, return -1; } - if (!property_get(result_prop_name, prop_value, NULL)) { - /* shouldn't ever happen, given the success of wait_for_property() */ - snprintf(errmsg, sizeof(errmsg), "%s", "DHCP result property was not set"); - return -1; - } - if (strcmp(prop_value, "ok") == 0) { - if (fill_ip_info(interface, ipaddr, gateway, prefixLength, dns, - server, lease, vendorInfo, domain, mtu) == -1) { - return -1; - } - return 0; - } else { - snprintf(errmsg, sizeof(errmsg), "DHCP result was %s", prop_value); - return -1; - } + return 0; } /** @@ -320,16 +338,7 @@ char *dhcp_get_errmsg() { * service iprenew_<interface> /system/bin/dhcpcd -n * */ -int dhcp_do_request_renew(const char *interface, - char *ipaddr, - char *gateway, - uint32_t *prefixLength, - char *dns[], - char *server, - uint32_t *lease, - char *vendorInfo, - char *domain, - char *mtu) +int dhcp_start_renew(const char *interface) { char result_prop_name[PROPERTY_KEY_MAX]; char prop_value[PROPERTY_VALUE_MAX] = {'\0'}; @@ -359,16 +368,5 @@ int dhcp_do_request_renew(const char *interface, return -1; } - if (!property_get(result_prop_name, prop_value, NULL)) { - /* shouldn't ever happen, given the success of wait_for_property() */ - snprintf(errmsg, sizeof(errmsg), "%s", "DHCP Renew result property was not set"); - return -1; - } - if (strcmp(prop_value, "ok") == 0) { - return fill_ip_info(interface, ipaddr, gateway, prefixLength, dns, - server, lease, vendorInfo, domain, mtu); - } else { - snprintf(errmsg, sizeof(errmsg), "DHCP Renew result was %s", prop_value); - return -1; - } + return 0; } diff --git a/libsysutils/src/NetlinkEvent.cpp b/libsysutils/src/NetlinkEvent.cpp index 909df86..29a86d8 100644 --- a/libsysutils/src/NetlinkEvent.cpp +++ b/libsysutils/src/NetlinkEvent.cpp @@ -47,20 +47,21 @@ const int LOCAL_NFLOG_PACKET = NFNL_SUBSYS_ULOG << 8 | NFULNL_MSG_PACKET; #include <netlink/handlers.h> #include <netlink/msg.h> -const int NetlinkEvent::NlActionUnknown = 0; -const int NetlinkEvent::NlActionAdd = 1; -const int NetlinkEvent::NlActionRemove = 2; -const int NetlinkEvent::NlActionChange = 3; -const int NetlinkEvent::NlActionLinkUp = 4; -const int NetlinkEvent::NlActionLinkDown = 5; -const int NetlinkEvent::NlActionAddressUpdated = 6; -const int NetlinkEvent::NlActionAddressRemoved = 7; -const int NetlinkEvent::NlActionRdnss = 8; -const int NetlinkEvent::NlActionRouteUpdated = 9; -const int NetlinkEvent::NlActionRouteRemoved = 10; +// STOPSHIP: remove these deprecated constants once we have updated prebuilts +const int NetlinkEvent::NlActionUnknown = static_cast<int>(Action::kUnknown); +const int NetlinkEvent::NlActionAdd = static_cast<int>(Action::kAdd); +const int NetlinkEvent::NlActionRemove = static_cast<int>(Action::kRemove); +const int NetlinkEvent::NlActionChange = static_cast<int>(Action::kChange); +const int NetlinkEvent::NlActionLinkDown = static_cast<int>(Action::kLinkDown); +const int NetlinkEvent::NlActionLinkUp = static_cast<int>(Action::kLinkUp); +const int NetlinkEvent::NlActionAddressUpdated = static_cast<int>(Action::kAddressUpdated); +const int NetlinkEvent::NlActionAddressRemoved = static_cast<int>(Action::kAddressRemoved); +const int NetlinkEvent::NlActionRdnss = static_cast<int>(Action::kRdnss); +const int NetlinkEvent::NlActionRouteUpdated = static_cast<int>(Action::kRouteUpdated); +const int NetlinkEvent::NlActionRouteRemoved = static_cast<int>(Action::kRouteRemoved); NetlinkEvent::NetlinkEvent() { - mAction = NlActionUnknown; + mAction = Action::kUnknown; memset(mParams, 0, sizeof(mParams)); mPath = NULL; mSubsystem = NULL; @@ -154,8 +155,8 @@ bool NetlinkEvent::parseIfInfoMessage(const struct nlmsghdr *nh) { switch(rta->rta_type) { case IFLA_IFNAME: asprintf(&mParams[0], "INTERFACE=%s", (char *) RTA_DATA(rta)); - mAction = (ifi->ifi_flags & IFF_LOWER_UP) ? NlActionLinkUp : - NlActionLinkDown; + mAction = (ifi->ifi_flags & IFF_LOWER_UP) ? Action::kLinkUp : + Action::kLinkDown; mSubsystem = strdup("net"); return true; } @@ -244,8 +245,8 @@ bool NetlinkEvent::parseIfAddrMessage(const struct nlmsghdr *nh) { } // Fill in netlink event information. - mAction = (type == RTM_NEWADDR) ? NlActionAddressUpdated : - NlActionAddressRemoved; + mAction = (type == RTM_NEWADDR) ? Action::kAddressUpdated : + Action::kAddressRemoved; mSubsystem = strdup("net"); asprintf(&mParams[0], "ADDRESS=%s/%d", addrstr, ifaddr->ifa_prefixlen); @@ -276,7 +277,7 @@ bool NetlinkEvent::parseUlogPacketMessage(const struct nlmsghdr *nh) { asprintf(&mParams[0], "ALERT_NAME=%s", pm->prefix); asprintf(&mParams[1], "INTERFACE=%s", devname); mSubsystem = strdup("qlog"); - mAction = NlActionChange; + mAction = Action::kChange; return true; } @@ -311,7 +312,7 @@ bool NetlinkEvent::parseNfPacketMessage(struct nlmsghdr *nh) { asprintf(&mParams[0], "UID=%d", uid); mParams[1] = hex; mSubsystem = strdup("strict"); - mAction = NlActionChange; + mAction = Action::kChange; return true; } @@ -397,8 +398,8 @@ bool NetlinkEvent::parseRtMessage(const struct nlmsghdr *nh) { return false; // Fill in netlink event information. - mAction = (type == RTM_NEWROUTE) ? NlActionRouteUpdated : - NlActionRouteRemoved; + mAction = (type == RTM_NEWROUTE) ? Action::kRouteUpdated : + Action::kRouteRemoved; mSubsystem = strdup("net"); asprintf(&mParams[0], "ROUTE=%s/%d", dst, prefixLength); asprintf(&mParams[1], "GATEWAY=%s", (*gw) ? gw : ""); @@ -497,7 +498,7 @@ bool NetlinkEvent::parseNdUserOptMessage(const struct nlmsghdr *nh) { } buf[pos] = '\0'; - mAction = NlActionRdnss; + mAction = Action::kRdnss; mSubsystem = strdup("net"); asprintf(&mParams[0], "INTERFACE=%s", ifname); asprintf(&mParams[1], "LIFETIME=%u", lifetime); @@ -617,11 +618,11 @@ bool NetlinkEvent::parseAsciiNetlinkMessage(char *buffer, int size) { const char* a; if ((a = HAS_CONST_PREFIX(s, end, "ACTION=")) != NULL) { if (!strcmp(a, "add")) - mAction = NlActionAdd; + mAction = Action::kAdd; else if (!strcmp(a, "remove")) - mAction = NlActionRemove; + mAction = Action::kRemove; else if (!strcmp(a, "change")) - mAction = NlActionChange; + mAction = Action::kChange; } else if ((a = HAS_CONST_PREFIX(s, end, "SEQNUM=")) != NULL) { mSeq = atoi(a); } else if ((a = HAS_CONST_PREFIX(s, end, "SUBSYSTEM=")) != NULL) { diff --git a/libutils/Looper.cpp b/libutils/Looper.cpp index 9a2dd6c..d739f11 100644 --- a/libutils/Looper.cpp +++ b/libutils/Looper.cpp @@ -20,6 +20,7 @@ #include <unistd.h> #include <fcntl.h> #include <limits.h> +#include <inttypes.h> namespace android { @@ -68,7 +69,8 @@ static pthread_key_t gTLSKey = 0; Looper::Looper(bool allowNonCallbacks) : mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false), - mResponseIndex(0), mNextMessageUptime(LLONG_MAX) { + mPolling(false), mEpollFd(-1), mEpollRebuildRequired(false), + mNextRequestSeq(0), mResponseIndex(0), mNextMessageUptime(LLONG_MAX) { int wakeFds[2]; int result = pipe(wakeFds); LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe. errno=%d", errno); @@ -84,25 +86,16 @@ Looper::Looper(bool allowNonCallbacks) : LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking. errno=%d", errno); - mIdling = false; - - // Allocate the epoll instance and register the wake pipe. - mEpollFd = epoll_create(EPOLL_SIZE_HINT); - LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance. errno=%d", errno); - - struct epoll_event eventItem; - memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union - eventItem.events = EPOLLIN; - eventItem.data.fd = mWakeReadPipeFd; - result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, & eventItem); - LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance. errno=%d", - errno); + AutoMutex _l(mLock); + rebuildEpollLocked(); } Looper::~Looper() { close(mWakeReadPipeFd); close(mWakeWritePipeFd); - close(mEpollFd); + if (mEpollFd >= 0) { + close(mEpollFd); + } } void Looper::initTLSKey() { @@ -156,6 +149,50 @@ bool Looper::getAllowNonCallbacks() const { return mAllowNonCallbacks; } +void Looper::rebuildEpollLocked() { + // Close old epoll instance if we have one. + if (mEpollFd >= 0) { +#if DEBUG_CALLBACKS + ALOGD("%p ~ rebuildEpollLocked - rebuilding epoll set", this); +#endif + close(mEpollFd); + } + + // Allocate the new epoll instance and register the wake pipe. + mEpollFd = epoll_create(EPOLL_SIZE_HINT); + LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance. errno=%d", errno); + + struct epoll_event eventItem; + memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union + eventItem.events = EPOLLIN; + eventItem.data.fd = mWakeReadPipeFd; + int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, & eventItem); + LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance. errno=%d", + errno); + + for (size_t i = 0; i < mRequests.size(); i++) { + const Request& request = mRequests.valueAt(i); + struct epoll_event eventItem; + request.initEventItem(&eventItem); + + int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, request.fd, & eventItem); + if (epollResult < 0) { + ALOGE("Error adding epoll events for fd %d while rebuilding epoll set, errno=%d", + request.fd, errno); + } + } +} + +void Looper::scheduleEpollRebuildLocked() { + if (!mEpollRebuildRequired) { +#if DEBUG_CALLBACKS + ALOGD("%p ~ scheduleEpollRebuildLocked - scheduling epoll set rebuild", this); +#endif + mEpollRebuildRequired = true; + wake(); + } +} + int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) { int result = 0; for (;;) { @@ -206,7 +243,7 @@ int Looper::pollInner(int timeoutMillis) { timeoutMillis = messageTimeoutMillis; } #if DEBUG_POLL_AND_WAKE - ALOGD("%p ~ pollOnce - next message in %lldns, adjusted timeout: timeoutMillis=%d", + ALOGD("%p ~ pollOnce - next message in %" PRId64 "ns, adjusted timeout: timeoutMillis=%d", this, mNextMessageUptime - now, timeoutMillis); #endif } @@ -217,17 +254,24 @@ int Looper::pollInner(int timeoutMillis) { mResponseIndex = 0; // We are about to idle. - mIdling = true; + mPolling = true; struct epoll_event eventItems[EPOLL_MAX_EVENTS]; int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis); // No longer idling. - mIdling = false; + mPolling = false; // Acquire lock. mLock.lock(); + // Rebuild epoll set if needed. + if (mEpollRebuildRequired) { + mEpollRebuildRequired = false; + rebuildEpollLocked(); + goto Done; + } + // Check for poll error. if (eventCount < 0) { if (errno == EINTR) { @@ -326,10 +370,14 @@ Done: ; ALOGD("%p ~ pollOnce - invoking fd event callback %p: fd=%d, events=0x%x, data=%p", this, response.request.callback.get(), fd, events, data); #endif + // Invoke the callback. Note that the file descriptor may be closed by + // the callback (and potentially even reused) before the function returns so + // we need to be a little careful when removing the file descriptor afterwards. int callbackResult = response.request.callback->handleEvent(fd, events, data); if (callbackResult == 0) { - removeFd(fd); + removeFd(fd, response.request.seq); } + // Clear the callback reference in the response structure promptly because we // will not clear the response vector itself until the next poll. response.request.callback.clear(); @@ -425,23 +473,20 @@ int Looper::addFd(int fd, int ident, int events, const sp<LooperCallback>& callb ident = POLL_CALLBACK; } - int epollEvents = 0; - if (events & EVENT_INPUT) epollEvents |= EPOLLIN; - if (events & EVENT_OUTPUT) epollEvents |= EPOLLOUT; - { // acquire lock AutoMutex _l(mLock); Request request; request.fd = fd; request.ident = ident; + request.events = events; + request.seq = mNextRequestSeq++; request.callback = callback; request.data = data; + if (mNextRequestSeq == -1) mNextRequestSeq = 0; // reserve sequence number -1 struct epoll_event eventItem; - memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union - eventItem.events = epollEvents; - eventItem.data.fd = fd; + request.initEventItem(&eventItem); ssize_t requestIndex = mRequests.indexOfKey(fd); if (requestIndex < 0) { @@ -454,8 +499,36 @@ int Looper::addFd(int fd, int ident, int events, const sp<LooperCallback>& callb } else { int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_MOD, fd, & eventItem); if (epollResult < 0) { - ALOGE("Error modifying epoll events for fd %d, errno=%d", fd, errno); - return -1; + if (errno == ENOENT) { + // Tolerate ENOENT because it means that an older file descriptor was + // closed before its callback was unregistered and meanwhile a new + // file descriptor with the same number has been created and is now + // being registered for the first time. This error may occur naturally + // when a callback has the side-effect of closing the file descriptor + // before returning and unregistering itself. Callback sequence number + // checks further ensure that the race is benign. + // + // Unfortunately due to kernel limitations we need to rebuild the epoll + // set from scratch because it may contain an old file handle that we are + // now unable to remove since its file descriptor is no longer valid. + // No such problem would have occurred if we were using the poll system + // call instead, but that approach carries others disadvantages. +#if DEBUG_CALLBACKS + ALOGD("%p ~ addFd - EPOLL_CTL_MOD failed due to file descriptor " + "being recycled, falling back on EPOLL_CTL_ADD, errno=%d", + this, errno); +#endif + epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem); + if (epollResult < 0) { + ALOGE("Error modifying or adding epoll events for fd %d, errno=%d", + fd, errno); + return -1; + } + scheduleEpollRebuildLocked(); + } else { + ALOGE("Error modifying epoll events for fd %d, errno=%d", fd, errno); + return -1; + } } mRequests.replaceValueAt(requestIndex, request); } @@ -464,8 +537,12 @@ int Looper::addFd(int fd, int ident, int events, const sp<LooperCallback>& callb } int Looper::removeFd(int fd) { + return removeFd(fd, -1); +} + +int Looper::removeFd(int fd, int seq) { #if DEBUG_CALLBACKS - ALOGD("%p ~ removeFd - fd=%d", this, fd); + ALOGD("%p ~ removeFd - fd=%d, seq=%d", this, fd, seq); #endif { // acquire lock @@ -475,13 +552,43 @@ int Looper::removeFd(int fd) { return 0; } - int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_DEL, fd, NULL); - if (epollResult < 0) { - ALOGE("Error removing epoll events for fd %d, errno=%d", fd, errno); - return -1; + // Check the sequence number if one was given. + if (seq != -1 && mRequests.valueAt(requestIndex).seq != seq) { +#if DEBUG_CALLBACKS + ALOGD("%p ~ removeFd - sequence number mismatch, oldSeq=%d", + this, mRequests.valueAt(requestIndex).seq); +#endif + return 0; } + // Always remove the FD from the request map even if an error occurs while + // updating the epoll set so that we avoid accidentally leaking callbacks. mRequests.removeItemsAt(requestIndex); + + int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_DEL, fd, NULL); + if (epollResult < 0) { + if (seq != -1 && (errno == EBADF || errno == ENOENT)) { + // Tolerate EBADF or ENOENT when the sequence number is known because it + // means that the file descriptor was closed before its callback was + // unregistered. This error may occur naturally when a callback has the + // side-effect of closing the file descriptor before returning and + // unregistering itself. + // + // Unfortunately due to kernel limitations we need to rebuild the epoll + // set from scratch because it may contain an old file handle that we are + // now unable to remove since its file descriptor is no longer valid. + // No such problem would have occurred if we were using the poll system + // call instead, but that approach carries others disadvantages. +#if DEBUG_CALLBACKS + ALOGD("%p ~ removeFd - EPOLL_CTL_DEL failed due to file descriptor " + "being closed, errno=%d", this, errno); +#endif + scheduleEpollRebuildLocked(); + } else { + ALOGE("Error removing epoll events for fd %d, errno=%d", fd, errno); + return -1; + } + } } // release lock return 1; } @@ -500,7 +607,7 @@ void Looper::sendMessageDelayed(nsecs_t uptimeDelay, const sp<MessageHandler>& h void Looper::sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler, const Message& message) { #if DEBUG_CALLBACKS - ALOGD("%p ~ sendMessageAtTime - uptime=%lld, handler=%p, what=%d", + ALOGD("%p ~ sendMessageAtTime - uptime=%" PRId64 ", handler=%p, what=%d", this, uptime, handler.get(), message.what); #endif @@ -566,8 +673,18 @@ void Looper::removeMessages(const sp<MessageHandler>& handler, int what) { } // release lock } -bool Looper::isIdling() const { - return mIdling; +bool Looper::isPolling() const { + return mPolling; +} + +void Looper::Request::initEventItem(struct epoll_event* eventItem) const { + int epollEvents = 0; + if (events & EVENT_INPUT) epollEvents |= EPOLLIN; + if (events & EVENT_OUTPUT) epollEvents |= EPOLLOUT; + + memset(eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union + eventItem->events = epollEvents; + eventItem->data.fd = fd; } } // namespace android diff --git a/logwrapper/logwrap.c b/logwrapper/logwrap.c index 3a6276e..83576fb 100644 --- a/logwrapper/logwrap.c +++ b/logwrapper/logwrap.c @@ -325,7 +325,7 @@ static int parent(const char *tag, int parent_read, pid_t pid, if (log_target & LOG_KLOG) { snprintf(log_info.klog_fmt, sizeof(log_info.klog_fmt), - "<6>%.*s: %%s", MAX_KLOG_TAG, log_info.btag); + "<6>%.*s: %%s\n", MAX_KLOG_TAG, log_info.btag); } if ((log_target & LOG_FILE) && !file_path) { diff --git a/rootdir/init.rc b/rootdir/init.rc index bc36c3e..9748fed 100644 --- a/rootdir/init.rc +++ b/rootdir/init.rc @@ -113,6 +113,10 @@ on init # set fwmark on accepted sockets write /proc/sys/net/ipv4/tcp_fwmark_accept 1 + # disable icmp redirects + write /proc/sys/net/ipv4/conf/all/accept_redirects 0 + write /proc/sys/net/ipv6/conf/all/accept_redirects 0 + # Create cgroup mount points for process groups mkdir /dev/cpuctl mount cgroup none /dev/cpuctl cpu |