1 // Copyright 2020 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 #ifndef CHROME_BROWSER_CHROMEOS_CROSTINI_CROSTINI_DISK_H_
6 #define CHROME_BROWSER_CHROMEOS_CROSTINI_CROSTINI_DISK_H_
7 
8 #include <memory>
9 #include <string>
10 #include <vector>
11 
12 #include "base/optional.h"
13 #include "chrome/browser/chromeos/crostini/crostini_simple_types.h"
14 #include "chrome/browser/chromeos/crostini/crostini_types.mojom-forward.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chromeos/dbus/concierge/concierge_service.pb.h"
17 
18 namespace crostini {
19 
20 struct CrostiniDiskInfo {
21   CrostiniDiskInfo();
22   CrostiniDiskInfo(CrostiniDiskInfo&&);
23   CrostiniDiskInfo(const CrostiniDiskInfo&) = delete;
24   CrostiniDiskInfo& operator=(CrostiniDiskInfo&&);
25   CrostiniDiskInfo& operator=(const CrostiniDiskInfo&) = delete;
26   ~CrostiniDiskInfo();
27   bool can_resize{};
28   bool is_user_chosen_size{};
29   bool is_low_space_available{};
30   int default_index{};
31   std::vector<crostini::mojom::DiskSliderTickPtr> ticks;
32 };
33 
34 namespace disk {
35 
36 constexpr int64_t kGiB = 1024 * 1024 * 1024;
37 constexpr int64_t kDiskHeadroomBytes = 1 * kGiB;
38 constexpr int64_t kMinimumDiskSizeBytes = 2 * kGiB;
39 constexpr int64_t kRecommendedDiskSizeBytes = 7.5 * kGiB;
40 
41 // A number which influences the interval size and number of ticks selected for
42 // a given range. At 400 >400 GiB gets 1 GiB ticks, smaller sizes get smaller
43 // intervals. 400 is arbitrary, chosen because it keeps ticks at least 1px each
44 // on sliders and feels nice.
45 constexpr int kGranularityFactor = 400;
46 
47 // The size of the download for the VM image.
48 // As of 2020-01-10 the Termina files.zip is ~90MiB and the squashfs container
49 // is ~330MiB.
50 constexpr int64_t kDownloadSizeBytes = 450ll * 1024 * 1024;  // 450 MiB
51 
52 using OnceDiskInfoCallback =
53     base::OnceCallback<void(std::unique_ptr<CrostiniDiskInfo> info)>;
54 
55 // Constructs a CrostiniDiskInfo for the requested vm under the given profile
56 // then calls callback with it once done. |full_info| requests extra disk info
57 // that is only available from a running VM.
58 void GetDiskInfo(OnceDiskInfoCallback callback,
59                  Profile* profile,
60                  std::string vm_name,
61                  bool full_info);
62 
63 // Callback for OnAmountOfFreeDiskSpace which passes off to the next step in the
64 // chain. Not intended to be called directly unless you're crostini_disk or
65 // tests.
66 void OnAmountOfFreeDiskSpace(OnceDiskInfoCallback callback,
67                              Profile* profile,
68                              std::string vm_name,
69                              int64_t free_space);
70 
71 // Combined callback for EnsureConciergeRunning or EnsureVmRunning which passes
72 // off to the next step in the chain. For getting full disk info, the VM must be
73 // running. Otherwise it is sufficient for Concierge to be running, but not
74 // necessarily the VM.Not intended to be called directly unless you're
75 // crostini_disk or tests.
76 void OnCrostiniSufficientlyRunning(OnceDiskInfoCallback callback,
77                                    Profile* profile,
78                                    std::string vm_name,
79                                    int64_t free_space,
80                                    CrostiniResult result);
81 
82 // Callback for EnsureVmRunning which passes off to the next step in the chain.
83 // Not intended to be called directly unless you're crostini_disk or tests.
84 void OnVMRunning(base::OnceCallback<void(bool)> callback,
85                  Profile* profile,
86                  std::string vm_name,
87                  int64_t free_space,
88                  CrostiniResult result);
89 
90 // Callback for OnListVmDisks which passes off to the next step in the chain.
91 // Not intended to be called directly unless you're crostini_disk or tests.
92 void OnListVmDisks(
93     OnceDiskInfoCallback callback,
94     std::string vm_name,
95     int64_t free_space,
96     base::Optional<vm_tools::concierge::ListVmDisksResponse> response);
97 
98 // Given a minimum, currently selected and maximum value, constructs a range of
99 // DiskSliderTicks spanning from min to max. Ensures that one of the ticks
100 // matches the current value and will write the index of that value to
101 // out_default_index.
102 std::vector<crostini::mojom::DiskSliderTickPtr> GetTicks(
103     int64_t min,
104     int64_t current,
105     int64_t max,
106     int* out_default_index);
107 
108 // Requests the disk for |vm_name| to be resized to |size_bytes|.
109 // Once complete |callback| is called with true (succeeded resizing) or false
110 // for any error.
111 void ResizeCrostiniDisk(Profile* profile,
112                         std::string vm_name,
113                         uint64_t size_bytes,
114                         base::OnceCallback<void(bool)> callback);
115 
116 // Callback provided to Concierge, not intended to be called unless you're
117 // crostini_disk or tests.
118 void OnResize(
119     base::OnceCallback<void(bool)> callback,
120     base::Optional<vm_tools::concierge::ResizeDiskImageResponse> response);
121 
122 // Splits the range between |min_size| and |available_space| into enough
123 // evenly-spaced intervals you can use them as ticks on a slider. Will return an
124 // empty set if the range is invalid (e.g. any numbers are negative).
125 std::vector<int64_t> GetTicksForDiskSize(
126     int64_t min_size,
127     int64_t available_space,
128     int granularity_factor_for_testing = kGranularityFactor);
129 
130 }  // namespace disk
131 }  // namespace crostini
132 #endif  // CHROME_BROWSER_CHROMEOS_CROSTINI_CROSTINI_DISK_H_
133