Merge "Add getStagedSessionInfo binder call."
diff --git a/apexd/Android.bp b/apexd/Android.bp
index 2a9419d..a090e4b 100644
--- a/apexd/Android.bp
+++ b/apexd/Android.bp
@@ -31,6 +31,7 @@
srcs: [
"aidl/android/apex/ApexInfo.aidl",
"aidl/android/apex/ApexInfoList.aidl",
+ "aidl/android/apex/ApexSessionInfo.aidl",
"aidl/android/apex/IApexService.aidl",
],
local_include_dir: "aidl",
diff --git a/apexd/aidl/android/apex/ApexSessionInfo.aidl b/apexd/aidl/android/apex/ApexSessionInfo.aidl
new file mode 100644
index 0000000..cca1ff9
--- /dev/null
+++ b/apexd/aidl/android/apex/ApexSessionInfo.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+package android.apex;
+
+parcelable ApexSessionInfo {
+ // Maps to apex::proto::SessionState::State enum.
+ boolean isUnknown;
+ boolean isVerified;
+ boolean isStaged;
+ boolean isActivated;
+ boolean isActivationPendingRetry;
+ boolean isActivationFailed;
+}
diff --git a/apexd/aidl/android/apex/IApexService.aidl b/apexd/aidl/android/apex/IApexService.aidl
index b88c27b..a32816e 100644
--- a/apexd/aidl/android/apex/IApexService.aidl
+++ b/apexd/aidl/android/apex/IApexService.aidl
@@ -18,11 +18,13 @@
import android.apex.ApexInfo;
import android.apex.ApexInfoList;
+import android.apex.ApexSessionInfo;
interface IApexService {
boolean stagePackage(in @utf8InCpp String package_tmp_path);
boolean stagePackages(in @utf8InCpp List<String> package_tmp_paths);
boolean submitStagedSession(int session_id, out ApexInfoList packages);
+ ApexSessionInfo getStagedSessionInfo(int session_id);
ApexInfo[] getActivePackages();
/**
diff --git a/apexd/apexservice.cpp b/apexd/apexservice.cpp
index a43befd..066bef3 100644
--- a/apexd/apexservice.cpp
+++ b/apexd/apexservice.cpp
@@ -32,6 +32,7 @@
#include <utils/String16.h>
#include "apexd.h"
+#include "apexd_session.h"
#include "status.h"
#include "string_log.h"
@@ -56,6 +57,8 @@
bool* aidl_return) override;
BinderStatus submitStagedSession(int session_id, ApexInfoList* apex_info_list,
bool* aidl_return) override;
+ BinderStatus getStagedSessionInfo(
+ int session_id, ApexSessionInfo* apex_session_info) override;
BinderStatus activatePackage(const std::string& packagePath) override;
BinderStatus deactivatePackage(const std::string& packagePath) override;
BinderStatus getActivePackages(std::vector<ApexInfo>* aidl_return) override;
@@ -131,6 +134,49 @@
return BinderStatus::ok();
}
+BinderStatus ApexService::getStagedSessionInfo(
+ int session_id, ApexSessionInfo* apex_session_info) {
+ LOG(DEBUG) << "getStagedSessionInfo() received by ApexService, session id "
+ << session_id;
+ apex_session_info->isUnknown = true;
+ apex_session_info->isVerified = false;
+ apex_session_info->isStaged = false;
+ apex_session_info->isActivated = false;
+ apex_session_info->isActivationPendingRetry = false;
+ apex_session_info->isActivationFailed = false;
+ auto state = readSessionState(session_id);
+ if (!state.Ok()) {
+ // Unknown session.
+ return BinderStatus::ok();
+ }
+
+ apex_session_info->isUnknown = false;
+ auto session_state = *state;
+ switch (session_state.state()) {
+ case session_state.VERIFIED:
+ apex_session_info->isVerified = true;
+ break;
+ case session_state.STAGED:
+ apex_session_info->isStaged = true;
+ break;
+ case session_state.ACTIVATED:
+ apex_session_info->isActivated = true;
+ break;
+ case session_state.ACTIVATION_PENDING_RETRY:
+ apex_session_info->isActivationPendingRetry = true;
+ break;
+ case session_state.ACTIVATION_FAILED:
+ apex_session_info->isActivationFailed = true;
+ break;
+ case session_state.UNKNOWN:
+ default:
+ apex_session_info->isUnknown = true;
+ break;
+ }
+
+ return BinderStatus::ok();
+}
+
BinderStatus ApexService::activatePackage(const std::string& packagePath) {
BinderStatus debugCheck = CheckDebuggable("activatePackage");
if (!debugCheck.isOk()) {
@@ -259,6 +305,8 @@
<< " deactivatePackage [packagePath] - deactivate package from the "
"given path"
<< std::endl
+ << " getStagedSessionInfo [sessionId] - displays information about a "
+ "given session previously submitted"
<< " submitStagedSession [sessionId] - attempts to submit the "
"installer session with given id"
<< std::endl;
@@ -377,6 +425,41 @@
return BAD_VALUE;
}
+ if (cmd == String16("getStagedSessionInfo")) {
+ if (args.size() != 2) {
+ print_help(err, "getStagedSessionInfo requires one session id");
+ return BAD_VALUE;
+ }
+ int session_id = strtol(String8(args[1]).c_str(), nullptr, 10);
+ if (session_id < 0) {
+ std::string msg = StringLog()
+ << "Failed to parse session id. Must be an integer.";
+ dprintf(err, "%s", msg.c_str());
+ return BAD_VALUE;
+ }
+
+ ApexSessionInfo session_info;
+ BinderStatus status = getStagedSessionInfo(session_id, &session_info);
+ if (status.isOk()) {
+ std::string msg = StringLog()
+ << "session_info: "
+ << " isUnknown: " << session_info.isUnknown
+ << " isVerified: " << session_info.isVerified
+ << " isStaged: " << session_info.isStaged
+ << " isActivated: " << session_info.isActivated
+ << " isActivationPendingRetry: "
+ << session_info.isActivationPendingRetry
+ << " isActivationFailed: "
+ << session_info.isActivationFailed << std::endl;
+ dprintf(out, "%s", msg.c_str());
+ return OK;
+ }
+ std::string msg = StringLog() << "Failed to query session: "
+ << status.toString8().string() << std::endl;
+ dprintf(err, "%s", msg.c_str());
+ return BAD_VALUE;
+ }
+
if (cmd == String16("submitStagedSession")) {
if (args.size() != 2) {
print_help(err, "submitStagedSession requires one session id");
diff --git a/apexd/apexservice_test.cpp b/apexd/apexservice_test.cpp
index 24852e1..d10996f 100644
--- a/apexd/apexservice_test.cpp
+++ b/apexd/apexservice_test.cpp
@@ -701,12 +701,23 @@
ASSERT_EQ(installer.package, match.packageName);
ASSERT_EQ(installer.version, static_cast<uint64_t>(match.versionCode));
ASSERT_EQ(installer.test_file, match.packagePath);
+
+ ApexSessionInfo session;
+ status = service_->getStagedSessionInfo(123, &session);
+ ASSERT_TRUE(status.isOk())
+ << status.toString8().c_str() << " " << GetDebugStr(&installer);
+ EXPECT_FALSE(session.isUnknown);
+ EXPECT_FALSE(session.isVerified);
+ EXPECT_TRUE(session.isStaged);
+ EXPECT_FALSE(session.isActivated);
+ EXPECT_FALSE(session.isActivationPendingRetry);
+ EXPECT_FALSE(session.isActivationFailed);
}
TEST_F(ApexServiceTest, SubmitSessionTestFail) {
PrepareTestApexForInstall installer(
GetTestFile("apex.apexd_test_no_inst_key.apex"),
- "/data/staging/session_123", "staging_data_file");
+ "/data/staging/session_456", "staging_data_file");
if (!installer.Prepare()) {
FAIL() << GetDebugStr(&installer);
}
@@ -714,11 +725,22 @@
ApexInfoList list;
bool ret_value;
android::binder::Status status =
- service_->submitStagedSession(123, &list, &ret_value);
+ service_->submitStagedSession(456, &list, &ret_value);
ASSERT_TRUE(status.isOk())
<< status.toString8().c_str() << " " << GetDebugStr(&installer);
EXPECT_FALSE(ret_value);
+
+ ApexSessionInfo session;
+ status = service_->getStagedSessionInfo(456, &session);
+ ASSERT_TRUE(status.isOk())
+ << status.toString8().c_str() << " " << GetDebugStr(&installer);
+ EXPECT_TRUE(session.isUnknown);
+ EXPECT_FALSE(session.isVerified);
+ EXPECT_FALSE(session.isStaged);
+ EXPECT_FALSE(session.isActivated);
+ EXPECT_FALSE(session.isActivationPendingRetry);
+ EXPECT_FALSE(session.isActivationFailed);
}
class LogTestToLogcat : public testing::EmptyTestEventListener {