blob: 6872c060e1a55ac234a9b5dc24e2c17d26897abc [file] [log] [blame]
// Copyright (C) 2016 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.
#include "android/emulation/control/ScreenCapturer.h"
#include "android/base/files/PathUtils.h"
#include "android/base/StringFormat.h"
#include "android/base/system/System.h"
#include "android/base/threads/Async.h"
namespace android {
namespace emulation {
using android::base::Looper;
using android::base::ParallelTask;
using android::base::StringView;
using android::base::System;
using std::string;
using std::vector;
// static
const System::Duration ScreenCapturer::kPullTimeoutMs = 5000;
const char ScreenCapturer::kRemoteScreenshotFilePath[] =
"/data/local/tmp/screen.png";
// If you run screencap while using emulator over remote desktop, this can
// take... a while.
const System::Duration ScreenCapturer::kScreenCaptureTimeoutMs =
System::kInfinite;
ScreenCapturer::~ScreenCapturer() {
if (mCaptureCommand) {
mCaptureCommand->cancel();
}
if (mPullCommand) {
mPullCommand->cancel();
}
}
void ScreenCapturer::capture(android::base::StringView outputDirectoryPath,
ResultCallback resultCallback) {
if (mCaptureCommand || mPullCommand) {
resultCallback(Result::kOperationInProgress);
}
std::string out_path = outputDirectoryPath;
mCaptureCommand =
mAdb->runAdbCommand(
{"shell", "screencap", "-p", kRemoteScreenshotFilePath },
[this, resultCallback, out_path](const OptionalAdbCommandResult& result) {
if (!result || result->exit_code) {
resultCallback(Result::kCaptureFailed);
} else {
pullScreencap(resultCallback, out_path);
}
mCaptureCommand.reset();
},
kScreenCaptureTimeoutMs,
false);
}
void ScreenCapturer::pullScreencap(ResultCallback resultCallback,
android::base::StringView outputDirectoryPath) {
if (!System::get()->pathIsDir(outputDirectoryPath) ||
!System::get()->pathCanWrite(outputDirectoryPath)) {
resultCallback(Result::kSaveLocationInvalid);
} else {
auto fileName =
android::base::StringFormat(
"Screenshot_%lu.png",
static_cast<unsigned long>(System::get()->getUnixTime()));
auto filePath =
android::base::PathUtils::join(outputDirectoryPath, fileName);
mPullCommand =
mAdb->runAdbCommand(
{"pull", kRemoteScreenshotFilePath, filePath},
[this, resultCallback](const OptionalAdbCommandResult& result) {
resultCallback(
(!result || result->exit_code)
? Result::kPullFailed
: Result::kSuccess);
mPullCommand.reset();
},
kPullTimeoutMs,
false);
}
}
} // namespace emulation
} // namespace android