Commit 11a6c5d9 authored by Guido Gunther's avatar Guido Gunther
Browse files

Lookup screen size limitations from application metainfo too



TODO:
- keep cache up to date on app add/removal
- cache succesfull lookups to avoid reparsing the data
- flatpaks user metainfo is not found
- add desktop info as well?
- Don't filter before metainfo cache is up to date
Signed-off-by: Guido Gunther's avatarGuido Günther <guido.gunther@puri.sm>
parent 6a49244b
Pipeline #69560 passed with stages
in 44 minutes and 49 seconds
......@@ -5,6 +5,7 @@ Maintainer: Guido Günther <agx@sigxcpu.org>
Build-Depends:
debhelper-compat (= 13),
gtk-doc-tools <!nodoc>,
libappstream-dev,
libsecret-1-dev,
libsystemd-dev,
libfeedback-dev,
......
......@@ -100,6 +100,7 @@ else
glib_ver = '>= 2.62'
endif
appstream_dep = dependency('appstream', version: '>= 0.14')
gcr_dep = dependency('gcr-3', version: '>= 3.7.5')
glib_dep = dependency('glib-2.0',
version: glib_ver,
......
......@@ -16,6 +16,7 @@
#include "app-grid-button.h"
#include "app-list-model.h"
#include "favorite-list-model.h"
#include "metainfo-cache.h"
#include "shell.h"
#include "gtk-list-models/gtksortlistmodel.h"
......@@ -151,6 +152,7 @@ filter_adaptive (PhoshAppGrid *self, GDesktopAppInfo *info)
PhoshAppGridPrivate *priv = phosh_app_grid_get_instance_private (self);
g_autofree char *mobile = NULL;
const char *id;
PhoshMetainfoCache *cache = phosh_metainfo_cache_get_default ();
if (!(priv->filter_mode & PHOSH_APP_FILTER_MODE_FLAGS_ADAPTIVE))
return TRUE;
......@@ -158,6 +160,12 @@ filter_adaptive (PhoshAppGrid *self, GDesktopAppInfo *info)
if (!priv->filter_adaptive)
return TRUE;
/* Check via application metainfo */
id = g_app_info_get_id (G_APP_INFO (info));
if (id && phosh_metainfo_fits (cache, id))
return TRUE;
/* Legacy fallback */
mobile = g_desktop_app_info_get_string (G_DESKTOP_APP_INFO (info),
"X-Purism-FormFactor");
if (mobile && strcasestr (mobile, "mobile;"))
......@@ -169,7 +177,6 @@ filter_adaptive (PhoshAppGrid *self, GDesktopAppInfo *info)
if (mobile && strcasestr (mobile, "handset;"))
return TRUE;
id = g_app_info_get_id (G_APP_INFO (info));
if (id && g_strv_contains ((const char * const*)priv->force_adaptive, id))
return TRUE;
......
......@@ -91,6 +91,8 @@ libphosh_tool_sources = files(
'manager.c',
'media-player.c',
'media-player.h',
'metainfo-cache.c',
'metainfo-cache.h',
'mode-manager.c',
'mode-manager.h',
'mount-manager.c',
......@@ -217,6 +219,7 @@ libphosh_sources = files(
]
phosh_deps = [
appstream_dep,
gcr_dep,
gio_dep,
gio_unix_dep,
......
/*
* Copyright (C) 2021 Purism SPC
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
* Author: Guido Günther <agx@sigxcpu.org>
*/
#define G_LOG_DOMAIN "phosh-metainfo-cache"
#include "config.h"
#include "metainfo-cache.h"
#include "util.h"
#include <appstream.h>
#include <gio/gio.h>
/**
* SECTION:metainfo-cache
* @short_description: Cache for application meta information
* @Title: PhoshMetainfoCache
*
* Cache application metainfo for quick query.
*/
typedef struct _PhoshMetainfoCache {
GObject parent;
AsPool *as_pool;
GCancellable *cancel;
gboolean ready;
} PhoshMetainfoCache;
G_DEFINE_TYPE (PhoshMetainfoCache, phosh_metainfo_cache, G_TYPE_OBJECT)
static void
on_as_pool_load_ready (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
gboolean success;
PhoshMetainfoCache *self;
g_autoptr (GError) err = NULL;
success = as_pool_load_finish (AS_POOL (source_object), res, &err);
if (!success) {
phosh_async_error_warn (err, "Failed to load metainfo pool");
return;
}
g_return_if_fail (PHOSH_IS_METAINFO_CACHE (user_data));
self = PHOSH_METAINFO_CACHE (user_data);
self->ready = TRUE;
g_debug ("Metainfo cache loaded from %s", as_pool_get_cache_location (self->as_pool));
}
static void
phosh_metainfo_cache_constructed (GObject *object)
{
PhoshMetainfoCache *self = PHOSH_METAINFO_CACHE (object);
self->as_pool = as_pool_new ();
/* We only bother about metainfo in a non-system cache */
as_pool_set_flags (self->as_pool, AS_POOL_FLAG_READ_METAINFO);
as_pool_load_async (self->as_pool, self->cancel,
on_as_pool_load_ready,
self);
G_OBJECT_CLASS (phosh_metainfo_cache_parent_class)->constructed (object);
}
static void
phosh_metainfo_cache_dispose (GObject *object)
{
PhoshMetainfoCache *self = PHOSH_METAINFO_CACHE (object);
g_cancellable_cancel (self->cancel);
g_clear_object (&self->cancel);
g_clear_object (&self->as_pool);
G_OBJECT_CLASS (phosh_metainfo_cache_parent_class)->dispose (object);
}
static void
phosh_metainfo_cache_class_init (PhoshMetainfoCacheClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = phosh_metainfo_cache_constructed;
object_class->dispose = phosh_metainfo_cache_dispose;
}
static void
phosh_metainfo_cache_init (PhoshMetainfoCache *self)
{
self->cancel = g_cancellable_new ();
}
PhoshMetainfoCache *
phosh_metainfo_cache_get_default (void)
{
static PhoshMetainfoCache *instance;
if (instance == NULL) {
instance = g_object_new (PHOSH_TYPE_METAINFO_CACHE, NULL);
g_object_add_weak_pointer (G_OBJECT (instance), (gpointer *)&instance);
}
return instance;
}
#define MIN_DISPLAY_LENGTH 360
gboolean
phosh_metainfo_fits (PhoshMetainfoCache *self, const char *cid)
{
g_autoptr (GPtrArray) result = NULL;
GPtrArray *rels;
guint min_len = 0;
gboolean wants_touch = FALSE;
result = as_pool_get_components_by_id (self->as_pool, cid);
/* TODO: check for two dots */
if (!result || result->len == 0)
return FALSE;
/* TODO: just use the first for now: */
rels = as_component_get_requires (g_ptr_array_index (result, 0));
for (int i = 0; i < rels->len; i++) {
AsRelation *rel = g_ptr_array_index (rels, i);
if (as_relation_get_item_kind (rel) == AS_RELATION_ITEM_KIND_DISPLAY_LENGTH &&
as_relation_get_compare (rel) == AS_RELATION_COMPARE_GE) {
/* TODO: take more complex constraints into account */
min_len = as_relation_get_value_px (rel);
}
if (as_relation_get_item_kind (rel) == AS_RELATION_ITEM_KIND_CONTROL &&
as_relation_get_value_control_kind (rel) == AS_CONTROL_KIND_TOUCH) {
wants_touch = TRUE;
}
}
if (!min_len || min_len > MIN_DISPLAY_LENGTH)
return FALSE;
rels = as_component_get_recommends (g_ptr_array_index (result, 0));
for (int i = 0; i < rels->len; i++) {
AsRelation *rel = g_ptr_array_index (rels, i);
if (as_relation_get_item_kind (rel) == AS_RELATION_ITEM_KIND_CONTROL &&
as_relation_get_value_control_kind (rel) == AS_CONTROL_KIND_TOUCH) {
wants_touch = TRUE;
break;
}
}
if (!wants_touch)
return FALSE;
g_debug ("%s matches device constraints", cid);
return TRUE;
}
/*
* Copyright (C) 2021 Purism SPC
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#pragma once
#include <glib-object.h>
G_BEGIN_DECLS
#define PHOSH_TYPE_METAINFO_CACHE phosh_metainfo_cache_get_type ()
G_DECLARE_FINAL_TYPE (PhoshMetainfoCache, phosh_metainfo_cache,
PHOSH, METAINFO_CACHE, GObject)
PhoshMetainfoCache *phosh_metainfo_cache_get_default (void);
gboolean phosh_metainfo_fits (PhoshMetainfoCache *self, const char *cid);
G_END_DECLS
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment