Merge "Fix misleading comments" am: 384a6820cb am: 814299c5a3
am: 33dd59e539

Change-Id: I7589eb74347d77a109b2eb25c72aa9bd70dbd420
diff --git a/healthd/Android.bp b/healthd/Android.bp
index cefe09d..8bd51e7 100644
--- a/healthd/Android.bp
+++ b/healthd/Android.bp
@@ -57,15 +57,10 @@
 cc_binary {
     name: "android.hardware.health@2.0-service",
     defaults: ["android.hardware.health@2.0-service_defaults"],
-}
-
-cc_binary {
-    name: "android.hardware.health@2.0-service.override",
-    defaults: ["android.hardware.health@2.0-service_defaults"],
 
     overrides: [
         "healthd",
-    ],
+    ]
 }
 
 cc_binary {
@@ -101,4 +96,7 @@
         "android.hardware.health@2.0",
     ],
 
+    vintf_fragments: [
+        "manifest_healthd.xml"
+    ],
 }
diff --git a/healthd/Android.mk b/healthd/Android.mk
index 86f7cf0..f7214c6 100644
--- a/healthd/Android.mk
+++ b/healthd/Android.mk
@@ -24,6 +24,8 @@
 LOCAL_CFLAGS += -DHEALTHD_DRAW_SPLIT_OFFSET=0
 endif
 
+LOCAL_HEADER_LIBRARIES := libbatteryservice_headers
+
 include $(BUILD_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
diff --git a/healthd/healthd_draw.cpp b/healthd/healthd_draw.cpp
index ea3d991..30f2cf3 100644
--- a/healthd/healthd_draw.cpp
+++ b/healthd/healthd_draw.cpp
@@ -21,77 +21,96 @@
 #include "healthd_draw.h"
 
 #define LOGE(x...) KLOG_ERROR("charger", x);
+#define LOGW(x...) KLOG_WARNING("charger", x);
 #define LOGV(x...) KLOG_DEBUG("charger", x);
 
 HealthdDraw::HealthdDraw(animation* anim)
   : kSplitScreen(HEALTHD_DRAW_SPLIT_SCREEN),
     kSplitOffset(HEALTHD_DRAW_SPLIT_OFFSET) {
-  gr_init();
-  gr_font_size(gr_sys_font(), &char_width_, &char_height_);
+    int ret = gr_init();
 
-  screen_width_ = gr_fb_width() / (kSplitScreen ? 2 : 1);
-  screen_height_ = gr_fb_height();
+    if (ret < 0) {
+        LOGE("gr_init failed\n");
+        graphics_available = false;
+        return;
+    }
 
-  int res;
-  if (!anim->text_clock.font_file.empty() &&
-      (res = gr_init_font(anim->text_clock.font_file.c_str(),
-                          &anim->text_clock.font)) < 0) {
-    LOGE("Could not load time font (%d)\n", res);
-  }
-  if (!anim->text_percent.font_file.empty() &&
-      (res = gr_init_font(anim->text_percent.font_file.c_str(),
-                          &anim->text_percent.font)) < 0) {
-    LOGE("Could not load percent font (%d)\n", res);
-  }
+    graphics_available = true;
+    sys_font = gr_sys_font();
+    if (sys_font == nullptr) {
+        LOGW("No system font, screen fallback text not available\n");
+    } else {
+        gr_font_size(sys_font, &char_width_, &char_height_);
+    }
+
+    screen_width_ = gr_fb_width() / (kSplitScreen ? 2 : 1);
+    screen_height_ = gr_fb_height();
+
+    int res;
+    if (!anim->text_clock.font_file.empty() &&
+        (res = gr_init_font(anim->text_clock.font_file.c_str(), &anim->text_clock.font)) < 0) {
+        LOGE("Could not load time font (%d)\n", res);
+    }
+    if (!anim->text_percent.font_file.empty() &&
+        (res = gr_init_font(anim->text_percent.font_file.c_str(), &anim->text_percent.font)) < 0) {
+        LOGE("Could not load percent font (%d)\n", res);
+    }
 }
 
 HealthdDraw::~HealthdDraw() {}
 
 void HealthdDraw::redraw_screen(const animation* batt_anim, GRSurface* surf_unknown) {
-  clear_screen();
+    if (!graphics_available) return;
+    clear_screen();
 
-  /* try to display *something* */
-  if (batt_anim->cur_level < 0 || batt_anim->num_frames == 0)
-    draw_unknown(surf_unknown);
-  else
-    draw_battery(batt_anim);
-  gr_flip();
+    /* try to display *something* */
+    if (batt_anim->cur_level < 0 || batt_anim->num_frames == 0)
+        draw_unknown(surf_unknown);
+    else
+        draw_battery(batt_anim);
+    gr_flip();
 }
 
-void HealthdDraw::blank_screen(bool blank) { gr_fb_blank(blank); }
+void HealthdDraw::blank_screen(bool blank) {
+    if (!graphics_available) return;
+    gr_fb_blank(blank);
+}
 
 void HealthdDraw::clear_screen(void) {
-  gr_color(0, 0, 0, 255);
-  gr_clear();
+    if (!graphics_available) return;
+    gr_color(0, 0, 0, 255);
+    gr_clear();
 }
 
 int HealthdDraw::draw_surface_centered(GRSurface* surface) {
-  int w = gr_get_width(surface);
-  int h = gr_get_height(surface);
-  int x = (screen_width_ - w) / 2 + kSplitOffset;
-  int y = (screen_height_ - h) / 2;
+    if (!graphics_available) return 0;
 
-  LOGV("drawing surface %dx%d+%d+%d\n", w, h, x, y);
-  gr_blit(surface, 0, 0, w, h, x, y);
-  if (kSplitScreen) {
-    x += screen_width_ - 2 * kSplitOffset;
+    int w = gr_get_width(surface);
+    int h = gr_get_height(surface);
+    int x = (screen_width_ - w) / 2 + kSplitOffset;
+    int y = (screen_height_ - h) / 2;
+
     LOGV("drawing surface %dx%d+%d+%d\n", w, h, x, y);
     gr_blit(surface, 0, 0, w, h, x, y);
-  }
+    if (kSplitScreen) {
+        x += screen_width_ - 2 * kSplitOffset;
+        LOGV("drawing surface %dx%d+%d+%d\n", w, h, x, y);
+        gr_blit(surface, 0, 0, w, h, x, y);
+    }
 
-  return y + h;
+    return y + h;
 }
 
 int HealthdDraw::draw_text(const GRFont* font, int x, int y, const char* str) {
-  int str_len_px = gr_measure(font, str);
+    if (!graphics_available) return 0;
+    int str_len_px = gr_measure(font, str);
 
-  if (x < 0) x = (screen_width_ - str_len_px) / 2;
-  if (y < 0) y = (screen_height_ - char_height_) / 2;
-  gr_text(font, x + kSplitOffset, y, str, false /* bold */);
-  if (kSplitScreen)
-    gr_text(font, x - kSplitOffset + screen_width_, y, str, false /* bold */);
+    if (x < 0) x = (screen_width_ - str_len_px) / 2;
+    if (y < 0) y = (screen_height_ - char_height_) / 2;
+    gr_text(font, x + kSplitOffset, y, str, false /* bold */);
+    if (kSplitScreen) gr_text(font, x - kSplitOffset + screen_width_, y, str, false /* bold */);
 
-  return y + char_height_;
+    return y + char_height_;
 }
 
 void HealthdDraw::determine_xy(const animation::text_field& field,
@@ -119,77 +138,80 @@
 }
 
 void HealthdDraw::draw_clock(const animation* anim) {
-  static constexpr char CLOCK_FORMAT[] = "%H:%M";
-  static constexpr int CLOCK_LENGTH = 6;
+    static constexpr char CLOCK_FORMAT[] = "%H:%M";
+    static constexpr int CLOCK_LENGTH = 6;
 
-  const animation::text_field& field = anim->text_clock;
+    const animation::text_field& field = anim->text_clock;
 
-  if (field.font == nullptr || field.font->char_width == 0 ||
-      field.font->char_height == 0)
-    return;
+    if (!graphics_available || field.font == nullptr || field.font->char_width == 0 ||
+        field.font->char_height == 0)
+        return;
 
-  time_t rawtime;
-  time(&rawtime);
-  tm* time_info = localtime(&rawtime);
+    time_t rawtime;
+    time(&rawtime);
+    tm* time_info = localtime(&rawtime);
 
-  char clock_str[CLOCK_LENGTH];
-  size_t length = strftime(clock_str, CLOCK_LENGTH, CLOCK_FORMAT, time_info);
-  if (length != CLOCK_LENGTH - 1) {
-    LOGE("Could not format time\n");
-    return;
-  }
+    char clock_str[CLOCK_LENGTH];
+    size_t length = strftime(clock_str, CLOCK_LENGTH, CLOCK_FORMAT, time_info);
+    if (length != CLOCK_LENGTH - 1) {
+        LOGE("Could not format time\n");
+        return;
+    }
 
-  int x, y;
-  determine_xy(field, length, &x, &y);
+    int x, y;
+    determine_xy(field, length, &x, &y);
 
-  LOGV("drawing clock %s %d %d\n", clock_str, x, y);
-  gr_color(field.color_r, field.color_g, field.color_b, field.color_a);
-  draw_text(field.font, x, y, clock_str);
+    LOGV("drawing clock %s %d %d\n", clock_str, x, y);
+    gr_color(field.color_r, field.color_g, field.color_b, field.color_a);
+    draw_text(field.font, x, y, clock_str);
 }
 
 void HealthdDraw::draw_percent(const animation* anim) {
-  int cur_level = anim->cur_level;
-  if (anim->cur_status == BATTERY_STATUS_FULL) {
-    cur_level = 100;
-  }
+    if (!graphics_available) return;
+    int cur_level = anim->cur_level;
+    if (anim->cur_status == BATTERY_STATUS_FULL) {
+        cur_level = 100;
+    }
 
-  if (cur_level <= 0) return;
+    if (cur_level <= 0) return;
 
-  const animation::text_field& field = anim->text_percent;
-  if (field.font == nullptr || field.font->char_width == 0 ||
-      field.font->char_height == 0) {
-    return;
-  }
+    const animation::text_field& field = anim->text_percent;
+    if (field.font == nullptr || field.font->char_width == 0 || field.font->char_height == 0) {
+        return;
+    }
 
-  std::string str = base::StringPrintf("%d%%", cur_level);
+    std::string str = base::StringPrintf("%d%%", cur_level);
 
-  int x, y;
-  determine_xy(field, str.size(), &x, &y);
+    int x, y;
+    determine_xy(field, str.size(), &x, &y);
 
-  LOGV("drawing percent %s %d %d\n", str.c_str(), x, y);
-  gr_color(field.color_r, field.color_g, field.color_b, field.color_a);
-  draw_text(field.font, x, y, str.c_str());
+    LOGV("drawing percent %s %d %d\n", str.c_str(), x, y);
+    gr_color(field.color_r, field.color_g, field.color_b, field.color_a);
+    draw_text(field.font, x, y, str.c_str());
 }
 
 void HealthdDraw::draw_battery(const animation* anim) {
-  const animation::frame& frame = anim->frames[anim->cur_frame];
+    if (!graphics_available) return;
+    const animation::frame& frame = anim->frames[anim->cur_frame];
 
-  if (anim->num_frames != 0) {
-    draw_surface_centered(frame.surface);
-    LOGV("drawing frame #%d min_cap=%d time=%d\n", anim->cur_frame,
-         frame.min_level, frame.disp_time);
-  }
-  draw_clock(anim);
-  draw_percent(anim);
+    if (anim->num_frames != 0) {
+        draw_surface_centered(frame.surface);
+        LOGV("drawing frame #%d min_cap=%d time=%d\n", anim->cur_frame, frame.min_level,
+             frame.disp_time);
+    }
+    draw_clock(anim);
+    draw_percent(anim);
 }
 
 void HealthdDraw::draw_unknown(GRSurface* surf_unknown) {
   int y;
   if (surf_unknown) {
-    draw_surface_centered(surf_unknown);
+      draw_surface_centered(surf_unknown);
+  } else if (sys_font) {
+      gr_color(0xa4, 0xc6, 0x39, 255);
+      y = draw_text(sys_font, -1, -1, "Charging!");
+      draw_text(sys_font, -1, y + 25, "?\?/100");
   } else {
-    gr_color(0xa4, 0xc6, 0x39, 255);
-    y = draw_text(gr_sys_font(), -1, -1, "Charging!");
-    draw_text(gr_sys_font(), -1, y + 25, "?\?/100");
+      LOGW("Charging, level unknown\n");
   }
 }
diff --git a/healthd/healthd_draw.h b/healthd/healthd_draw.h
index 6a6ba76..7c847bd 100644
--- a/healthd/healthd_draw.h
+++ b/healthd/healthd_draw.h
@@ -70,6 +70,12 @@
   const bool kSplitScreen;
   // Pixels to offset graphics towards center split.
   const int kSplitOffset;
+
+  // system text font, may be nullptr
+  const GRFont* sys_font;
+
+  // true if minui init'ed OK, false if minui init failed
+  bool graphics_available;
 };
 
 #endif  // HEALTHD_DRAW_H
diff --git a/healthd/manifest_healthd.xml b/healthd/manifest_healthd.xml
new file mode 100644
index 0000000..097a7d8
--- /dev/null
+++ b/healthd/manifest_healthd.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="framework">
+    <hal>
+        <name>android.hardware.health</name>
+        <transport>hwbinder</transport>
+        <version>2.0</version>
+        <interface>
+            <name>IHealth</name>
+            <instance>backup</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
index e984ac8..c093246 100644
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -82,6 +82,9 @@
 /* Defined as ProcessList.SYSTEM_ADJ in ProcessList.java */
 #define SYSTEM_ADJ (-900)
 
+#define STRINGIFY(x) STRINGIFY_INTERNAL(x)
+#define STRINGIFY_INTERNAL(x) #x
+
 /* default to old in-kernel interface if no memory pressure events */
 static bool use_inkernel_interface = true;
 static bool has_inkernel_module;
@@ -115,6 +118,7 @@
 static bool kill_heaviest_task;
 static unsigned long kill_timeout_ms;
 static bool use_minfree_levels;
+static bool per_app_memcg;
 
 /* data required to handle events */
 struct event_handler_info {
@@ -481,7 +485,7 @@
         return;
     }
 
-    if (low_ram_device) {
+    if (per_app_memcg) {
         if (params.oomadj >= 900) {
             soft_limit_mult = 0;
         } else if (params.oomadj >= 800) {
@@ -729,10 +733,10 @@
 
 #ifdef LMKD_LOG_STATS
 static void memory_stat_parse_line(char *line, struct memory_stat *mem_st) {
-    char key[LINE_MAX];
+    char key[LINE_MAX + 1];
     int64_t value;
 
-    sscanf(line,"%s  %" SCNd64 "", key, &value);
+    sscanf(line, "%" STRINGIFY(LINE_MAX) "s  %" SCNd64 "", key, &value);
 
     if (strcmp(key, "total_") < 0) {
         return;
@@ -751,24 +755,31 @@
 }
 
 static int memory_stat_parse(struct memory_stat *mem_st,  int pid, uid_t uid) {
-   FILE *fp;
-   char buf[PATH_MAX];
+    FILE *fp;
+    char buf[PATH_MAX];
 
-   snprintf(buf, sizeof(buf), MEMCG_PROCESS_MEMORY_STAT_PATH, uid, pid);
+    /*
+     * Per-application memory.stat files are available only when
+     * per-application memcgs are enabled.
+     */
+    if (!per_app_memcg)
+        return -1;
 
-   fp = fopen(buf, "r");
+    snprintf(buf, sizeof(buf), MEMCG_PROCESS_MEMORY_STAT_PATH, uid, pid);
 
-   if (fp == NULL) {
-       ALOGE("%s open failed: %s", buf, strerror(errno));
-       return -1;
-   }
+    fp = fopen(buf, "r");
 
-   while (fgets(buf, PAGE_SIZE, fp) != NULL ) {
-       memory_stat_parse_line(buf, mem_st);
-   }
-   fclose(fp);
+    if (fp == NULL) {
+        ALOGE("%s open failed: %s", buf, strerror(errno));
+        return -1;
+    }
 
-   return 0;
+    while (fgets(buf, PAGE_SIZE, fp) != NULL ) {
+        memory_stat_parse_line(buf, mem_st);
+    }
+    fclose(fp);
+
+    return 0;
 }
 #endif
 
@@ -1577,6 +1588,8 @@
         (unsigned long)property_get_int32("ro.lmk.kill_timeout_ms", 0);
     use_minfree_levels =
         property_get_bool("ro.lmk.use_minfree_levels", false);
+    per_app_memcg =
+        property_get_bool("ro.config.per_app_memcg", low_ram_device);
 
 #ifdef LMKD_LOG_STATS
     statslog_init(&log_ctx, &enable_stats_log);
diff --git a/rootdir/etc/public.libraries.android.txt b/rootdir/etc/public.libraries.android.txt
index e20b95d..2a51d53 100644
--- a/rootdir/etc/public.libraries.android.txt
+++ b/rootdir/etc/public.libraries.android.txt
@@ -1,6 +1,7 @@
 # See https://android.googlesource.com/platform/ndk/+/master/docs/PlatformApis.md
 libandroid.so
 libaaudio.so
+libamidi.so
 libc.so
 libcamera2ndk.so
 libdl.so
diff --git a/rootdir/etc/public.libraries.iot.txt b/rootdir/etc/public.libraries.iot.txt
index ff0813d..6690770 100644
--- a/rootdir/etc/public.libraries.iot.txt
+++ b/rootdir/etc/public.libraries.iot.txt
@@ -2,6 +2,7 @@
 libandroid.so
 libandroidthings.so
 libaaudio.so
+libamidi.so
 libc.so
 libcamera2ndk.so
 libdl.so
diff --git a/rootdir/etc/public.libraries.wear.txt b/rootdir/etc/public.libraries.wear.txt
index 3c46094..56055ba 100644
--- a/rootdir/etc/public.libraries.wear.txt
+++ b/rootdir/etc/public.libraries.wear.txt
@@ -1,6 +1,7 @@
 # See https://android.googlesource.com/platform/ndk/+/master/docs/PlatformApis.md
 libandroid.so
 libaaudio.so
+libamidi.so
 libc.so
 libcamera2ndk.so
 libdl.so
diff --git a/storaged/Android.bp b/storaged/Android.bp
index b478f4a..7466728 100644
--- a/storaged/Android.bp
+++ b/storaged/Android.bp
@@ -66,6 +66,7 @@
     ],
 
     static_libs: ["libhealthhalutils"],
+    header_libs: ["libbatteryservice_headers"],
 
     logtags: ["EventLogTags.logtags"],
 
diff --git a/storaged/include/storaged.h b/storaged/include/storaged.h
index 400e734..6f92048 100644
--- a/storaged/include/storaged.h
+++ b/storaged/include/storaged.h
@@ -26,7 +26,6 @@
 #include <unordered_map>
 #include <vector>
 
-#include <batteryservice/IBatteryPropertiesListener.h>
 #include <utils/Mutex.h>
 
 #include <android/hardware/health/2.0/IHealth.h>
diff --git a/storaged/include/uid_info.h b/storaged/include/uid_info.h
index 4398a0d..c5533ac 100644
--- a/storaged/include/uid_info.h
+++ b/storaged/include/uid_info.h
@@ -19,6 +19,8 @@
 #include <string>
 #include <unordered_map>
 
+#include <binder/Parcelable.h>
+
 namespace android {
 namespace os {
 namespace storaged {
diff --git a/storaged/storaged.cpp b/storaged/storaged.cpp
index bf8b448..f346c38 100644
--- a/storaged/storaged.cpp
+++ b/storaged/storaged.cpp
@@ -30,6 +30,7 @@
 
 #include <android-base/file.h>
 #include <android-base/logging.h>
+#include <android-base/unique_fd.h>
 #include <android/hidl/manager/1.0/IServiceManager.h>
 #include <batteryservice/BatteryServiceConstants.h>
 #include <cutils/properties.h>