| /* |
| * Copyright (C) 2019 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| #pragma once |
| |
| #include <map> |
| #include <memory> |
| #include <mutex> |
| #include <sstream> |
| #include <string> |
| #include <vector> |
| |
| #include <android-base/unique_fd.h> |
| #include <android/gsi/BnGsiService.h> |
| #include <binder/BinderService.h> |
| #include <libfiemap/split_fiemap_writer.h> |
| #include <liblp/builder.h> |
| #include "libgsi/libgsi.h" |
| |
| #include "partition_installer.h" |
| |
| namespace android { |
| namespace gsi { |
| |
| class GsiService : public BinderService<GsiService>, public BnGsiService { |
| public: |
| static void Register(const std::string& name); |
| |
| binder::Status openInstall(const std::string& install_dir, int* _aidl_return) override; |
| binder::Status closeInstall(int32_t* _aidl_return) override; |
| binder::Status createPartition(const ::std::string& name, int64_t size, bool readOnly, |
| int32_t* _aidl_return) override; |
| binder::Status closePartition(int32_t* _aidl_return) override; |
| binder::Status commitGsiChunkFromStream(const ::android::os::ParcelFileDescriptor& stream, |
| int64_t bytes, bool* _aidl_return) override; |
| binder::Status getInstallProgress(::android::gsi::GsiProgress* _aidl_return) override; |
| binder::Status setGsiAshmem(const ::android::os::ParcelFileDescriptor& ashmem, int64_t size, |
| bool* _aidl_return) override; |
| binder::Status commitGsiChunkFromAshmem(int64_t bytes, bool* _aidl_return) override; |
| binder::Status cancelGsiInstall(bool* _aidl_return) override; |
| binder::Status enableGsi(bool oneShot, const std::string& dsuSlot, int* _aidl_return) override; |
| binder::Status enableGsiAsync(bool oneShot, const ::std::string& dsuSlot, |
| const sp<IGsiServiceCallback>& resultCallback) override; |
| binder::Status isGsiEnabled(bool* _aidl_return) override; |
| binder::Status removeGsi(bool* _aidl_return) override; |
| binder::Status removeGsiAsync(const sp<IGsiServiceCallback>& resultCallback) override; |
| binder::Status disableGsi(bool* _aidl_return) override; |
| binder::Status isGsiInstalled(bool* _aidl_return) override; |
| binder::Status isGsiRunning(bool* _aidl_return) override; |
| binder::Status isGsiInstallInProgress(bool* _aidl_return) override; |
| binder::Status getInstalledGsiImageDir(std::string* _aidl_return) override; |
| binder::Status getActiveDsuSlot(std::string* _aidl_return) override; |
| binder::Status getInstalledDsuSlots(std::vector<std::string>* _aidl_return) override; |
| binder::Status zeroPartition(const std::string& name, int* _aidl_return) override; |
| binder::Status openImageService(const std::string& prefix, |
| android::sp<IImageService>* _aidl_return) override; |
| binder::Status dumpDeviceMapperDevices(std::string* _aidl_return) override; |
| binder::Status getAvbPublicKey(AvbPublicKey* dst, int32_t* _aidl_return) override; |
| binder::Status suggestScratchSize(int64_t* _aidl_return) override; |
| |
| // This is in GsiService, rather than GsiInstaller, since we need to access |
| // it outside of the main lock which protects the unique_ptr. |
| void StartAsyncOperation(const std::string& step, int64_t total_bytes); |
| void UpdateProgress(int status, int64_t bytes_processed); |
| |
| // Helper methods for GsiInstaller. |
| static bool RemoveGsiFiles(const std::string& install_dir); |
| bool should_abort() const { return should_abort_; } |
| |
| static void RunStartupTasks(); |
| static void VerifyImageMaps(); |
| static std::string GetInstalledImageDir(); |
| std::string GetActiveDsuSlot(); |
| std::string GetActiveInstalledImageDir(); |
| |
| static std::vector<std::string> GetInstalledDsuSlots(); |
| |
| private: |
| friend class ImageService; |
| |
| GsiService(); |
| static int ValidateInstallParams(std::string& install_dir); |
| int EnableGsi(bool one_shot, const std::string& dsu_slot); |
| bool DisableGsiInstall(); |
| static void CleanCorruptedInstallation(); |
| static int SaveInstallation(const std::string&); |
| static bool IsInstallationComplete(const std::string&); |
| static std::string GetCompleteIndication(const std::string&); |
| |
| enum class AccessLevel { System, SystemOrShell }; |
| binder::Status CheckUid(AccessLevel level = AccessLevel::System); |
| |
| // Mark install completion, and reset boot attempt counter. |
| // Next boot will try to boot into DSU. |
| bool ResetBootAttemptCounter(); |
| |
| bool SetBootMode(bool one_shot); |
| |
| static android::wp<GsiService> sInstance; |
| |
| std::string install_dir_ = {}; |
| std::unique_ptr<PartitionInstaller> installer_; |
| std::mutex lock_; |
| std::mutex& lock() { return lock_; } |
| // These are initialized or set in StartInstall(). |
| std::atomic<bool> should_abort_ = false; |
| |
| // Progress bar state. |
| std::mutex progress_lock_; |
| GsiProgress progress_; |
| }; |
| |
| } // namespace gsi |
| } // namespace android |