#define EXPORT __attribute__ ((visibility("default")))
+#define MAX_WINDOW_STACK_SIZE 50
+#define INIT_PROCESS_ID 1
+#define MINIMUM_Z_VALUE 1
+
/**
* -900 is very low oom_score_adj (-1000 to 1000), so
* focused app will not be choosen as victim regardless of memory size.
static int get_kill_candidates_post_with_foreground(GArray *candidates,
enum syscommon_resourced_memory_lmk_oom_level oom_level)
{
+ struct task_info *z_candidates[MAX_WINDOW_STACK_SIZE] = { NULL, };
+ int foreground_app_count = 0;
+ int foreground_app_index;
+ int focused_app_index;
+ int z_index;
+ int z_min;
+ int z_max;
int ret = is_valid_candidates_list(candidates);
if (ret < 0)
return ret;
- if (oom_level != OOM_LEVEL_FOREGROUND)
+ if (candidates->len == 1)
+ return 0;
+
+ switch (oom_level) {
+ case OOM_LEVEL_BACKGROUND_LEAST_RECENTLY_USED:
+ case OOM_LEVEL_BACKGROUND_MOST_RECENTLY_USED:
+ case OOM_LEVEL_FOREGROUND_AND_PROC:
+ case OOM_LEVEL_ALL:
return 0;
+ case OOM_LEVEL_FOREGROUND:
+ break;
+ default:
+ _E("Unknown oom level");
+ return -EINVAL;
+ }
+
+ z_min = MAX_WINDOW_STACK_SIZE;
+ z_max = 0;
for (int i = 0; i < candidates->len; ++i) {
- /**
- * TODO: Each task_info can have more than one window information.
- * Therefore, trace all of windows of each task_info
- */
struct task_info *task = g_array_index(candidates,
struct task_info *, i);
+ assert(task);
- if (!task)
- continue;
+ if (task->window_pid < INIT_PROCESS_ID) {
+ _W("Cannot prioritize between apps w/ window and apps w/o window");
+ return 0;
+ }
+
+ if (task->z < MINIMUM_Z_VALUE) {
+ _E("Window z value (%d) should be larger than 0", task->z);
+ return -EINVAL;
+ }
+
+ if (task->z >= MAX_WINDOW_STACK_SIZE) {
+ _E("Window z value (%d) should be smaller than %d",
+ task->z, MAX_WINDOW_STACK_SIZE);
+ return -EINVAL;
+ }
+
+ if (z_min > task->z)
+ z_min = task->z;
+
+ if (z_max < task->z)
+ z_max = task->z;
+
+ if (task->oom_score_lru == OOMADJ_APP_IN_FOREGROUND_APP_LIST)
+ foreground_app_count++;
+
+ z_candidates[task->z] = task;
}
- /**
- * TODO: Reorder foreground app candidates according to policy.
- *
- * 1. Basically, sorting candidates from high value of z to low one.
- * 2. If window information's is_focus is equal to 1,
- * put it to end of candidates.
- * 3. If task_info's oom_score_lru is OOMADJ_APP_IN_FOREGROUND_APP_LIST,
- * put it to end of candidates.
- * 4. App memory size is out of interest
- *
- * candidates will be sorted like below:
- *
- * |(high z) --> (low z)|(is_focused = 1)|(OOMADJ_APP_IN_FOREGROUND_APP_LIST)|
- */
+ foreground_app_index = candidates->len - foreground_app_count;
+ if (foreground_app_index < 0)
+ return -EINVAL;
+
+ focused_app_index = foreground_app_index - 1;
+ if (focused_app_index < 0)
+ return -EINVAL;
+
+ z_index = 0;
+
+ for (int index = z_max; index >= z_min; index--) {
+ struct task_info **task_ptr;
+
+ struct task_info *z_task = z_candidates[index];
+ if (!z_task) {
+ _E("z value of foreground app windows should be continuous");
+ return -EINVAL;
+ }
+
+ /**
+ * Reorder foreground app candidates according to policy.
+ *
+ * 1. Basically, sorting candidates from high value of z to low one.
+ * 2. If window information's is_focus is equal to 1,
+ * put it before foreground app list.
+ * 3. If task_info's oom_score_lru is OOMADJ_APP_IN_FOREGROUND_APP_LIST,
+ * put it to end of candidates.
+ * 4. App memory size is out of interest
+ *
+ * candidates will be sorted like below:
+ *
+ * |(high z) --> (low z)|(is_focused = 1)|(OOMADJ_APP_IN_FOREGROUND_APP_LIST)|
+ */
+ if (z_task->oom_score_lru == OOMADJ_APP_IN_FOREGROUND_APP_LIST) {
+ task_ptr = &g_array_index(candidates,
+ struct task_info *, foreground_app_index);
+ *task_ptr = z_task;
+ foreground_app_index++;
+ continue;
+ }
+
+ if (z_task->is_focused) {
+ task_ptr = &g_array_index(candidates,
+ struct task_info *, focused_app_index);
+ *task_ptr = z_task;
+ continue;
+ }
+
+ task_ptr = &g_array_index(candidates,
+ struct task_info *, z_index);
+ *task_ptr = z_task;
+ z_index++;
+ }
return 0;
}