blob: f0670fa84801d563e2a3f523fbe71bc9a4c32342 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/shell/platform/android/apk_asset_provider.h"
#include <unistd.h>
#include <algorithm>
#include <sstream>
#include "flutter/fml/logging.h"
namespace flutter {
class APKAssetMapping : public fml::Mapping {
public:
explicit APKAssetMapping(AAsset* asset) : asset_(asset) {}
~APKAssetMapping() override { AAsset_close(asset_); }
size_t GetSize() const override { return AAsset_getLength(asset_); }
const uint8_t* GetMapping() const override {
return reinterpret_cast<const uint8_t*>(AAsset_getBuffer(asset_));
}
bool IsDontNeedSafe() const override { return !AAsset_isAllocated(asset_); }
private:
AAsset* const asset_;
FML_DISALLOW_COPY_AND_ASSIGN(APKAssetMapping);
};
class APKAssetProviderImpl : public APKAssetProviderInternal {
public:
explicit APKAssetProviderImpl(JNIEnv* env,
jobject jassetManager,
std::string directory)
: java_asset_manager_(env, jassetManager),
directory_(std::move(directory)) {
asset_manager_ = AAssetManager_fromJava(env, jassetManager);
}
~APKAssetProviderImpl() = default;
std::unique_ptr<fml::Mapping> GetAsMapping(
const std::string& asset_name) const override {
std::stringstream ss;
ss << directory_.c_str() << "/" << asset_name;
AAsset* asset = AAssetManager_open(asset_manager_, ss.str().c_str(),
AASSET_MODE_BUFFER);
if (!asset) {
return nullptr;
}
return std::make_unique<APKAssetMapping>(asset);
};
private:
fml::jni::ScopedJavaGlobalRef<jobject> java_asset_manager_;
AAssetManager* asset_manager_;
const std::string directory_;
FML_DISALLOW_COPY_AND_ASSIGN(APKAssetProviderImpl);
};
APKAssetProvider::APKAssetProvider(JNIEnv* env,
jobject assetManager,
std::string directory)
: impl_(std::make_shared<APKAssetProviderImpl>(env,
assetManager,
std::move(directory))) {}
APKAssetProvider::APKAssetProvider(
std::shared_ptr<APKAssetProviderInternal> impl)
: impl_(impl) {}
// |AssetResolver|
bool APKAssetProvider::IsValid() const {
return true;
}
// |AssetResolver|
bool APKAssetProvider::IsValidAfterAssetManagerChange() const {
return true;
}
// |AssetResolver|
AssetResolver::AssetResolverType APKAssetProvider::GetType() const {
return AssetResolver::AssetResolverType::kApkAssetProvider;
}
// |AssetResolver|
std::unique_ptr<fml::Mapping> APKAssetProvider::GetAsMapping(
const std::string& asset_name) const {
return impl_->GetAsMapping(asset_name);
}
std::unique_ptr<APKAssetProvider> APKAssetProvider::Clone() const {
return std::make_unique<APKAssetProvider>(impl_);
}
} // namespace flutter