blob: 679f7362ade02ebf196c9a7dc2887c51bb58df60 [file] [log] [blame]
// Copyright 2018 The Chromium 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 "chromeos/services/ime/ime_service.h"
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/location.h"
#include "base/sequenced_task_runner.h"
#include "build/buildflag.h"
#include "chromeos/constants/chromeos_features.h"
#include "chromeos/services/ime/constants.h"
#include "chromeos/services/ime/decoder/decoder_engine.h"
#include "chromeos/services/ime/public/cpp/buildflags.h"
namespace chromeos {
namespace ime {
namespace {
enum SimpleDownloadError {
SIMPLE_DOWNLOAD_ERROR_OK = 0,
SIMPLE_DOWNLOAD_ERROR_FAILED = -1,
SIMPLE_DOWNLOAD_ERROR_ABORTED = -2,
};
} // namespace
ImeService::ImeService(mojo::PendingReceiver<mojom::ImeService> receiver)
: receiver_(this, std::move(receiver)),
main_task_runner_(base::SequencedTaskRunnerHandle::Get()) {
input_engine_ = chromeos::features::IsImeDecoderWithSandboxEnabled()
? std::make_unique<DecoderEngine>(this)
: std::make_unique<InputEngine>();
}
ImeService::~ImeService() = default;
void ImeService::SetPlatformAccessProvider(
mojo::PendingRemote<mojom::PlatformAccessProvider> provider) {
platform_access_.Bind(std::move(provider));
}
void ImeService::BindInputEngineManager(
mojo::PendingReceiver<mojom::InputEngineManager> receiver) {
manager_receivers_.Add(this, std::move(receiver));
}
void ImeService::ConnectToImeEngine(
const std::string& ime_spec,
mojo::PendingReceiver<mojom::InputChannel> to_engine_request,
mojo::PendingRemote<mojom::InputChannel> from_engine,
const std::vector<uint8_t>& extra,
ConnectToImeEngineCallback callback) {
DCHECK(input_engine_);
bool bound = input_engine_->BindRequest(
ime_spec, std::move(to_engine_request), std::move(from_engine), extra);
std::move(callback).Run(bound);
}
void ImeService::SimpleDownloadFinished(SimpleDownloadCallback callback,
const base::FilePath& file) {
if (file.empty()) {
callback(SIMPLE_DOWNLOAD_ERROR_FAILED, "");
} else {
// Convert downloaded file path to an whitelisted path.
base::FilePath target(kUserInputMethodsDirPath);
target = target.Append(kLanguageDataDirName).Append(file.BaseName());
callback(SIMPLE_DOWNLOAD_ERROR_OK, target.MaybeAsASCII().c_str());
}
}
const char* ImeService::GetImeBundleDir() {
return kBundledInputMethodsDirPath;
}
const char* ImeService::GetImeGlobalDir() {
// Global IME data is supported yet.
return "";
}
const char* ImeService::GetImeUserHomeDir() {
return kUserInputMethodsDirPath;
}
void ImeService::RunInMainSequence(ImeSequencedTask task, int task_id) {
// This helps ensure that tasks run in the **main** SequencedTaskRunner.
// E.g. the Mojo Remotes are bound on the main_task_runner_, so that any task
// invoked Mojo call from other threads (sequences) should be posted to
// main_task_runner_ by this function.
main_task_runner_->PostTask(FROM_HERE, base::BindOnce(task, task_id));
}
int ImeService::SimpleDownloadToFile(const char* url,
const char* file_path,
SimpleDownloadCallback callback) {
if (!platform_access_.is_bound()) {
callback(SIMPLE_DOWNLOAD_ERROR_ABORTED, "");
LOG(ERROR) << "Failed to download due to missing binding.";
} else {
// Target path MUST be relative for security concerns.
// Compose a relative download path beased on the request.
base::FilePath initial_path(file_path);
base::FilePath relative_path(kInputMethodsDirName);
relative_path = relative_path.Append(kLanguageDataDirName)
.Append(initial_path.BaseName());
GURL download_url(url);
platform_access_->DownloadImeFileTo(
download_url, relative_path,
base::BindOnce(&ImeService::SimpleDownloadFinished,
base::Unretained(this), std::move(callback)));
}
// For |SimpleDownloadToFile|, always returns 0.
return 0;
}
ImeCrosDownloader* ImeService::GetDownloader() {
// TODO(https://crbug.com/837156): Create an ImeCrosDownloader based on its
// specification defined in interfaces. The caller should free it after use.
return nullptr;
}
} // namespace ime
} // namespace chromeos