1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/enterprise/reporting/android_app_info_generator.h"
6 
7 #include <map>
8 #include <sstream>
9 
10 #include "base/strings/stringprintf.h"
11 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
12 #include "components/arc/mojom/app_permissions.mojom.h"
13 #include "components/policy/proto/device_management_backend.pb.h"
14 
15 namespace em = enterprise_management;
16 
17 namespace {
18 
ExtractPackagePermissions(const base::flat_map<arc::mojom::AppPermission,arc::mojom::PermissionStatePtr> & permissions,em::AndroidAppInfo * app_info)19 void ExtractPackagePermissions(
20     const base::flat_map<arc::mojom::AppPermission,
21                          arc::mojom::PermissionStatePtr>& permissions,
22     em::AndroidAppInfo* app_info) {
23   for (auto it = permissions.begin(); it != permissions.end(); it++) {
24     std::stringstream stream;
25     stream << it->first;
26 
27     em::AndroidAppPermission* app_permission = app_info->add_permissions();
28     app_permission->set_name(stream.str());
29     app_permission->set_granted(it->second->granted);
30     app_permission->set_managed(it->second->managed);
31   }
32 }
33 
ExtractAppStatus(const ArcAppListPrefs::AppInfo & app)34 em::AndroidAppInfo::AndroidAppStatus ExtractAppStatus(
35     const ArcAppListPrefs::AppInfo& app) {
36   if (app.suspended)
37     return em::AndroidAppInfo::STATUS_SUSPENDED;
38   else if (app.ready)
39     return em::AndroidAppInfo::STATUS_ENABLED;
40   else
41     return em::AndroidAppInfo::STATUS_DISABLED;
42 }
43 
ExtractInstalledSource(const ArcAppListPrefs & prefs,const ArcAppListPrefs::AppInfo & app)44 em::AndroidAppInfo::InstalledSource ExtractInstalledSource(
45     const ArcAppListPrefs& prefs,
46     const ArcAppListPrefs::AppInfo& app) {
47   if (!app.ready)
48     return em::AndroidAppInfo::SOURCE_NOT_INSTALLED;
49 
50   if (prefs.IsControlledByPolicy(app.package_name))
51     return em::AndroidAppInfo::SOURCE_BY_ADMIN;
52   else
53     return em::AndroidAppInfo::SOURCE_BY_USER;
54 }
55 
56 }  // namespace
57 
58 namespace enterprise_reporting {
59 
Generate(ArcAppListPrefs * prefs,const std::string & app_id) const60 std::unique_ptr<em::AndroidAppInfo> AndroidAppInfoGenerator::Generate(
61     ArcAppListPrefs* prefs,
62     const std::string& app_id) const {
63   // An AppInfo instance will always be generated.
64   auto info = std::make_unique<em::AndroidAppInfo>();
65 
66   // Collect application information if possible.
67   std::unique_ptr<ArcAppListPrefs::AppInfo> app = prefs->GetApp(app_id);
68 
69   if (app) {
70     info->set_app_id(prefs->GetAppIdByPackageName(app->package_name));
71     info->set_app_name(app->name);
72     info->set_package_name(app->package_name);
73     info->set_status(ExtractAppStatus(*app));
74     info->set_installed_source(ExtractInstalledSource(*prefs, *app));
75 
76     // Collect package information if possible.
77     std::unique_ptr<ArcAppListPrefs::PackageInfo> package =
78         prefs->GetPackage(app->package_name);
79 
80     if (package) {
81       info->set_version(package->package_version);
82       ExtractPackagePermissions(package->permissions, info.get());
83     } else {
84       LOG(ERROR) << base::StringPrintf(
85           "Package (package name: %s) can not be found.",
86           app->package_name.c_str());
87     }
88   } else {
89     LOG(ERROR) << base::StringPrintf("App (app id: %s) can not be found.",
90                                      app_id.c_str());
91   }
92 
93   return info;
94 }
95 
96 }  // namespace enterprise_reporting
97