diff options
-rw-r--r-- | cmds/incident/Android.bp | 2 | ||||
-rw-r--r-- | cmds/incidentd/Android.bp | 4 | ||||
-rw-r--r-- | cmds/incidentd/TEST_MAPPING | 13 | ||||
-rw-r--r-- | cmds/statsd/Android.bp | 1 | ||||
-rw-r--r-- | cmds/statsd/src/subscriber/IncidentdReporter.cpp | 27 | ||||
-rw-r--r-- | libs/incident/Android.bp | 69 | ||||
-rw-r--r-- | libs/incident/TEST_MAPPING | 21 | ||||
-rw-r--r-- | libs/incident/include/incident/incident_report.h | 192 | ||||
-rw-r--r-- | libs/incident/include_priv/android/os/IncidentReportArgs.h (renamed from libs/incident/include/android/os/IncidentReportArgs.h) | 10 | ||||
-rw-r--r-- | libs/incident/libincident.map.txt | 15 | ||||
-rw-r--r-- | libs/incident/src/incident_report.cpp | 83 | ||||
-rw-r--r-- | libs/incident/tests/IncidentReportArgs_test.cpp (renamed from cmds/statsd/tests/external/IncidentReportArgs_test.cpp) | 2 | ||||
-rw-r--r-- | libs/incident/tests/IncidentReportRequest_test.cpp | 65 | ||||
-rw-r--r-- | libs/incident/tests/c_api_compile_test.c | 11 |
14 files changed, 486 insertions, 29 deletions
diff --git a/cmds/incident/Android.bp b/cmds/incident/Android.bp index 9e9dac14c802..94855aa0311f 100644 --- a/cmds/incident/Android.bp +++ b/cmds/incident/Android.bp @@ -26,7 +26,7 @@ cc_binary { "libcutils", "liblog", "libutils", - "libincident", + "libincidentpriv", ], static_libs: [ diff --git a/cmds/incidentd/Android.bp b/cmds/incidentd/Android.bp index 25e0328b4f38..cc724a626baf 100644 --- a/cmds/incidentd/Android.bp +++ b/cmds/incidentd/Android.bp @@ -54,7 +54,7 @@ cc_binary { "libbinder", "libdebuggerd_client", "libdumputils", - "libincident", + "libincidentpriv", "liblog", "libprotoutil", "libservices", @@ -128,7 +128,7 @@ cc_test { "libbinder", "libdebuggerd_client", "libdumputils", - "libincident", + "libincidentpriv", "liblog", "libprotobuf-cpp-full", "libprotoutil", diff --git a/cmds/incidentd/TEST_MAPPING b/cmds/incidentd/TEST_MAPPING new file mode 100644 index 000000000000..f5b0b7a120ca --- /dev/null +++ b/cmds/incidentd/TEST_MAPPING @@ -0,0 +1,13 @@ +{ + "presubmit": [ + { + "name": "incidentd_test" + } + ], + "postsubmit": [ + ], + "imports": [ + ] +} + + diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp index 2237bf2b2acb..6f71d97d9dad 100644 --- a/cmds/statsd/Android.bp +++ b/cmds/statsd/Android.bp @@ -278,7 +278,6 @@ cc_test { "tests/e2e/ValueMetric_pull_e2e_test.cpp", "tests/e2e/WakelockDuration_e2e_test.cpp", "tests/external/GpuStatsPuller_test.cpp", - "tests/external/IncidentReportArgs_test.cpp", "tests/external/puller_util_test.cpp", "tests/external/StatsCallbackPuller_test.cpp", "tests/external/StatsPuller_test.cpp", diff --git a/cmds/statsd/src/subscriber/IncidentdReporter.cpp b/cmds/statsd/src/subscriber/IncidentdReporter.cpp index d86e29131661..30c90b1e1f71 100644 --- a/cmds/statsd/src/subscriber/IncidentdReporter.cpp +++ b/cmds/statsd/src/subscriber/IncidentdReporter.cpp @@ -21,10 +21,8 @@ #include "packages/UidMap.h" #include "stats_log_util.h" -#include <android/os/IIncidentManager.h> -#include <android/os/IncidentReportArgs.h> #include <android/util/ProtoOutputStream.h> -#include <binder/IServiceManager.h> +#include <incident/incident_report.h> #include <vector> @@ -132,7 +130,7 @@ bool GenerateIncidentReport(const IncidentdDetails& config, int64_t rule_id, int return false; } - IncidentReportArgs incidentReport; + android::os::IncidentReportRequest incidentReport; vector<uint8_t> protoData; getProtoData(rule_id, metricId, dimensionKey, metricValue, configKey, @@ -146,30 +144,21 @@ bool GenerateIncidentReport(const IncidentdDetails& config, int64_t rule_id, int uint8_t dest; switch (config.dest()) { case IncidentdDetails_Destination_AUTOMATIC: - dest = android::os::PRIVACY_POLICY_AUTOMATIC; + dest = INCIDENT_REPORT_PRIVACY_POLICY_AUTOMATIC; break; case IncidentdDetails_Destination_EXPLICIT: - dest = android::os::PRIVACY_POLICY_EXPLICIT; + dest = INCIDENT_REPORT_PRIVACY_POLICY_EXPLICIT; break; default: - dest = android::os::PRIVACY_POLICY_AUTOMATIC; + dest = INCIDENT_REPORT_PRIVACY_POLICY_AUTOMATIC; } incidentReport.setPrivacyPolicy(dest); - incidentReport.setReceiverPkg(config.receiver_pkg()); + incidentReport.setReceiverPackage(config.receiver_pkg()); - incidentReport.setReceiverCls(config.receiver_cls()); + incidentReport.setReceiverClass(config.receiver_cls()); - sp<IIncidentManager> service = interface_cast<IIncidentManager>( - defaultServiceManager()->getService(android::String16("incident"))); - if (service == nullptr) { - ALOGW("Failed to fetch incident service."); - return false; - } - VLOG("Calling incidentd %p", service.get()); - binder::Status s = service->reportIncident(incidentReport); - VLOG("Report incident status: %s", s.toString8().string()); - return s.isOk(); + return incidentReport.takeReport() == NO_ERROR; } } // namespace statsd diff --git a/libs/incident/Android.bp b/libs/incident/Android.bp index 150f6dcde5d0..512b8c439dcf 100644 --- a/libs/incident/Android.bp +++ b/libs/incident/Android.bp @@ -12,8 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -cc_library_shared { - name: "libincident", + +cc_defaults { + name: "libincidentpriv_defaults", cflags: [ "-Wall", @@ -50,6 +51,70 @@ cc_library_shared { ":libincident_aidl", "src/IncidentReportArgs.cpp", ], +} + +cc_library_shared { + name: "libincidentpriv", + defaults: ["libincidentpriv_defaults"], + export_include_dirs: ["include_priv"], +} + +cc_library_shared { + name: "libincident", + + cflags: [ + "-Wall", + "-Werror", + "-Wno-missing-field-initializers", + "-Wno-unused-variable", + "-Wunused-parameter", + ], + + shared_libs: [ + "libbinder", + "liblog", + "libutils", + "libincidentpriv", + ], + + srcs: [ + "src/incident_report.cpp", + ], export_include_dirs: ["include"], + + stubs: { + symbol_file: "libincident.map.txt", + versions: [ + "30", + ], + }, } + +cc_test { + name: "libincident_test", + defaults: ["libincidentpriv_defaults"], + test_suites: ["device-tests"], + + include_dirs: [ + "frameworks/base/libs/incident/include", + "frameworks/base/libs/incident/include_priv", + ], + + srcs: [ + "tests/IncidentReportArgs_test.cpp", + "tests/IncidentReportRequest_test.cpp", + "tests/c_api_compile_test.c", + ], + + shared_libs: [ + "libincident", + ], + + static_libs: [ + "libgmock", + ], +} + + + diff --git a/libs/incident/TEST_MAPPING b/libs/incident/TEST_MAPPING new file mode 100644 index 000000000000..b49513543cb1 --- /dev/null +++ b/libs/incident/TEST_MAPPING @@ -0,0 +1,21 @@ +{ + "presubmit": [ + { + "name": "libincident_c_api_test" + }, + { + "name": "GtsIncidentConfirmationTestCases" + }, + { + "name": "GtsIncidentManagerTestCases" + } + ], + "postsubmit": [ + ], + "imports": [ + { + "path": "frameworks/base/cmds/incidentd" + } + ] +} + diff --git a/libs/incident/include/incident/incident_report.h b/libs/incident/include/incident/incident_report.h new file mode 100644 index 000000000000..49fe5b9b73b4 --- /dev/null +++ b/libs/incident/include/incident/incident_report.h @@ -0,0 +1,192 @@ +/** + * Copyright (c) 2020, 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. + */ + +/** + * @file incident_report.h + */ + +#ifndef ANDROID_INCIDENT_INCIDENT_REPORT_H +#define ANDROID_INCIDENT_INCIDENT_REPORT_H + +#include <stdbool.h> + +#if __cplusplus +#include <set> +#include <string> +#include <vector> + +extern "C" { +#endif // __cplusplus + +struct AIncidentReportArgs; +/** + * Opaque class to represent the arguments to an incident report request. + * Incident reports contain debugging data about the device at runtime. + * For more information see the android.os.IncidentManager java class. + */ +typedef struct AIncidentReportArgs AIncidentReportArgs; + +// Privacy policy enum value, sync with frameworks/base/core/proto/android/privacy.proto, +// IncidentReportArgs.h and IncidentReportArgs.java. +enum { + /** + * Flag marking fields and incident reports than can be taken + * off the device only via adb. + */ + INCIDENT_REPORT_PRIVACY_POLICY_LOCAL = 0, + + /** + * Flag marking fields and incident reports than can be taken + * off the device with contemporary consent. + */ + INCIDENT_REPORT_PRIVACY_POLICY_EXPLICIT = 100, + + /** + * Flag marking fields and incident reports than can be taken + * off the device with prior consent. + */ + INCIDENT_REPORT_PRIVACY_POLICY_AUTOMATIC = 200, + + /** + * Flag to indicate that a given field has not been marked + * with a privacy policy. + */ + INCIDENT_REPORT_PRIVACY_POLICY_UNSET = 255 +}; + +/** + * Allocate and initialize an AIncidentReportArgs object. + */ +AIncidentReportArgs* AIncidentReportArgs_init(); + +/** + * Duplicate an existing AIncidentReportArgs object. + */ +AIncidentReportArgs* AIncidentReportArgs_clone(AIncidentReportArgs* that); + +/** + * Clean up and delete an AIncidentReportArgs object. + */ +void AIncidentReportArgs_delete(AIncidentReportArgs* args); + +/** + * Set this incident report to include all sections. + */ +void AIncidentReportArgs_setAll(AIncidentReportArgs* args, bool all); + +/** + * Set this incident report privacy policy spec. + */ +void AIncidentReportArgs_setPrivacyPolicy(AIncidentReportArgs* args, int privacyPolicy); + +/** + * Add this section to the incident report. The section IDs are the field numbers + * from the android.os.IncidentProto protobuf message. + */ +void AIncidentReportArgs_addSection(AIncidentReportArgs* args, int section); + +/** + * Set the apk package name that will be sent a broadcast when the incident + * report completes. Must be called in conjunction with AIncidentReportArgs_setReceiverClass. + */ +void AIncidentReportArgs_setReceiverPackage(AIncidentReportArgs* args, char const* pkg); + +/** + * Set the fully qualified class name of the java BroadcastReceiver class that will be + * sent a broadcast when the report completes. Must be called in conjunction with + * AIncidentReportArgs_setReceiverPackage. + */ +void AIncidentReportArgs_setReceiverClass(AIncidentReportArgs* args, char const* cls); + +/** + * Add protobuf data as a header to the incident report. The buffer should be a serialized + * android.os.IncidentHeaderProto object. + */ +void AIncidentReportArgs_addHeader(AIncidentReportArgs* args, uint8_t const* buf, size_t size); + +/** + * Initiate taking the report described in the args object. Returns 0 on success, + * and non-zero otherwise. + */ +int AIncidentReportArgs_takeReport(AIncidentReportArgs* args); + +#if __cplusplus +} // extern "C" + +namespace android { +namespace os { + +class IncidentReportRequest { +public: + inline IncidentReportRequest() { + mImpl = AIncidentReportArgs_init(); + } + + inline IncidentReportRequest(const IncidentReportRequest& that) { + mImpl = AIncidentReportArgs_clone(that.mImpl); + } + + inline ~IncidentReportRequest() { + AIncidentReportArgs_delete(mImpl); + } + + inline AIncidentReportArgs* getImpl() { + return mImpl; + } + + inline void setAll(bool all) { + AIncidentReportArgs_setAll(mImpl, all); + } + + inline void setPrivacyPolicy(int privacyPolicy) { + AIncidentReportArgs_setPrivacyPolicy(mImpl, privacyPolicy); + } + + inline void addSection(int section) { + AIncidentReportArgs_addSection(mImpl, section); + } + + inline void setReceiverPackage(const std::string& pkg) { + AIncidentReportArgs_setReceiverPackage(mImpl, pkg.c_str()); + }; + + inline void setReceiverClass(const std::string& cls) { + AIncidentReportArgs_setReceiverClass(mImpl, cls.c_str()); + }; + + inline void addHeader(const std::vector<uint8_t>& headerProto) { + AIncidentReportArgs_addHeader(mImpl, headerProto.data(), headerProto.size()); + }; + + inline void addHeader(const uint8_t* buf, size_t size) { + AIncidentReportArgs_addHeader(mImpl, buf, size); + }; + + // returns a status_t + inline int takeReport() { + return AIncidentReportArgs_takeReport(mImpl); + } + +private: + AIncidentReportArgs* mImpl; +}; + +} // namespace os +} // namespace android + +#endif // __cplusplus + +#endif // ANDROID_INCIDENT_INCIDENT_REPORT_H diff --git a/libs/incident/include/android/os/IncidentReportArgs.h b/libs/incident/include_priv/android/os/IncidentReportArgs.h index 94b4ad6eae31..0e6159032e45 100644 --- a/libs/incident/include/android/os/IncidentReportArgs.h +++ b/libs/incident/include_priv/android/os/IncidentReportArgs.h @@ -14,9 +14,10 @@ * limitations under the License. */ -#ifndef ANDROID_OS_DUMPSTATE_ARGS_H_ -#define ANDROID_OS_DUMPSTATE_ARGS_H_ +#ifndef ANDROID_OS_INCIDENT_REPORT_ARGS_H +#define ANDROID_OS_INCIDENT_REPORT_ARGS_H +#include <binder/IServiceManager.h> #include <binder/Parcel.h> #include <binder/Parcelable.h> #include <utils/String16.h> @@ -29,7 +30,8 @@ namespace os { using namespace std; -// DESTINATION enum value, sync with frameworks/base/core/proto/android/privacy.proto +// DESTINATION enum value, sync with frameworks/base/core/proto/android/privacy.proto, +// incident/incident_report.h and IncidentReportArgs.java const uint8_t PRIVACY_POLICY_LOCAL = 0; const uint8_t PRIVACY_POLICY_EXPLICIT = 100; const uint8_t PRIVACY_POLICY_AUTOMATIC = 200; @@ -74,4 +76,4 @@ private: } } -#endif // ANDROID_OS_DUMPSTATE_ARGS_H_ +#endif // ANDROID_OS_INCIDENT_REPORT_ARGS_H diff --git a/libs/incident/libincident.map.txt b/libs/incident/libincident.map.txt new file mode 100644 index 000000000000..f157763f1a03 --- /dev/null +++ b/libs/incident/libincident.map.txt @@ -0,0 +1,15 @@ +LIBINCIDENT { + global: + AIncidentReportArgs_init; # apex # introduced=30 + AIncidentReportArgs_clone; # apex # introduced=30 + AIncidentReportArgs_delete; # apex # introduced=30 + AIncidentReportArgs_setAll; # apex # introduced=30 + AIncidentReportArgs_setPrivacyPolicy; # apex # introduced=30 + AIncidentReportArgs_addSection; # apex # introduced=30 + AIncidentReportArgs_setReceiverPackage; # apex # introduced=30 + AIncidentReportArgs_setReceiverClass; # apex # introduced=30 + AIncidentReportArgs_addHeader; # apex # introduced=30 + AIncidentReportArgs_takeReport; # apex # introduced=30 + local: + *; +}; diff --git a/libs/incident/src/incident_report.cpp b/libs/incident/src/incident_report.cpp new file mode 100644 index 000000000000..7897ddf6d251 --- /dev/null +++ b/libs/incident/src/incident_report.cpp @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2020, 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. + */ + +#define LOG_TAG "libincident" + +#include <incident/incident_report.h> + +#include <android/os/IIncidentManager.h> +#include <android/os/IncidentReportArgs.h> +#include <binder/IServiceManager.h> +#include <binder/Status.h> +#include <log/log.h> + +using android::sp; +using android::binder::Status; +using android::os::IncidentReportArgs; +using android::os::IIncidentManager; +using std::string; +using std::vector; + +AIncidentReportArgs* AIncidentReportArgs_init() { + return reinterpret_cast<AIncidentReportArgs*>(new IncidentReportArgs()); +} + +AIncidentReportArgs* AIncidentReportArgs_clone(AIncidentReportArgs* that) { + return reinterpret_cast<AIncidentReportArgs*>( + new IncidentReportArgs(*reinterpret_cast<IncidentReportArgs*>(that))); +} + +void AIncidentReportArgs_delete(AIncidentReportArgs* args) { + delete reinterpret_cast<IncidentReportArgs*>(args); +} + +void AIncidentReportArgs_setAll(AIncidentReportArgs* args, bool all) { + reinterpret_cast<IncidentReportArgs*>(args)->setAll(all); +} + +void AIncidentReportArgs_setPrivacyPolicy(AIncidentReportArgs* args, int privacyPolicy) { + reinterpret_cast<IncidentReportArgs*>(args)->setPrivacyPolicy(privacyPolicy); +} + +void AIncidentReportArgs_addSection(AIncidentReportArgs* args, int section) { + reinterpret_cast<IncidentReportArgs*>(args)->addSection(section); +} + +void AIncidentReportArgs_setReceiverPackage(AIncidentReportArgs* args, char const* pkg) { + reinterpret_cast<IncidentReportArgs*>(args)->setReceiverPkg(string(pkg)); +} + +void AIncidentReportArgs_setReceiverClass(AIncidentReportArgs* args, char const* cls) { + reinterpret_cast<IncidentReportArgs*>(args)->setReceiverCls(string(cls)); +} + +void AIncidentReportArgs_addHeader(AIncidentReportArgs* args, uint8_t const* buf, size_t size) { + vector<uint8_t> vec(buf, buf+size); + reinterpret_cast<IncidentReportArgs*>(args)->addHeader(vec); +} + +int AIncidentReportArgs_takeReport(AIncidentReportArgs* argp) { + IncidentReportArgs* args = reinterpret_cast<IncidentReportArgs*>(argp); + + sp<IIncidentManager> service = android::interface_cast<IIncidentManager>( + android::defaultServiceManager()->getService(android::String16("incident"))); + if (service == nullptr) { + ALOGW("Failed to fetch incident service."); + return false; + } + Status s = service->reportIncident(*args); + return s.transactionError(); +} diff --git a/cmds/statsd/tests/external/IncidentReportArgs_test.cpp b/libs/incident/tests/IncidentReportArgs_test.cpp index 38bc19452afa..224b343c554a 100644 --- a/cmds/statsd/tests/external/IncidentReportArgs_test.cpp +++ b/libs/incident/tests/IncidentReportArgs_test.cpp @@ -20,6 +20,8 @@ namespace android { namespace os { namespace statsd { +// Checks that all of the inline methods on IncidentReportRequest and the real C functions +// result in a working IncidentReportArgs. TEST(IncidentReportArgsTest, testSerialization) { IncidentReportArgs args; args.setAll(0); diff --git a/libs/incident/tests/IncidentReportRequest_test.cpp b/libs/incident/tests/IncidentReportRequest_test.cpp new file mode 100644 index 000000000000..6d218b6682a3 --- /dev/null +++ b/libs/incident/tests/IncidentReportRequest_test.cpp @@ -0,0 +1,65 @@ +// Copyright (C) 2018 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/os/IncidentReportArgs.h> +#include <incident/incident_report.h> + +#include <gtest/gtest.h> + +namespace android { +namespace os { +namespace statsd { + +TEST(IncidentReportRequestTest, testWrite) { + IncidentReportRequest request; + request.setAll(0); + request.addSection(1000); + request.addSection(1001); + + vector<uint8_t> header1; + header1.push_back(0x1); + header1.push_back(0x2); + vector<uint8_t> header2; + header1.push_back(0x22); + header1.push_back(0x33); + + request.addHeader(header1); + request.addHeader(header2); + + request.setPrivacyPolicy(1); + + request.setReceiverPackage("com.android.os"); + request.setReceiverClass("com.android.os.Receiver"); + + IncidentReportArgs* args = reinterpret_cast<IncidentReportArgs*>(request.getImpl()); + + EXPECT_EQ(0, args->all()); + set<int> sections; + sections.insert(1000); + sections.insert(1001); + EXPECT_EQ(sections, args->sections()); + EXPECT_EQ(1, args->getPrivacyPolicy()); + + EXPECT_EQ(string("com.android.os"), args->receiverPkg()); + EXPECT_EQ(string("com.android.os.Receiver"), args->receiverCls()); + + vector<vector<uint8_t>> headers; + headers.push_back(header1); + headers.push_back(header2); + EXPECT_EQ(headers, args->headers()); +} + +} // namespace statsd +} // namespace os +} // namespace android diff --git a/libs/incident/tests/c_api_compile_test.c b/libs/incident/tests/c_api_compile_test.c new file mode 100644 index 000000000000..e1620dfe3280 --- /dev/null +++ b/libs/incident/tests/c_api_compile_test.c @@ -0,0 +1,11 @@ +#include <stdio.h> +#include <incident/incident_report.h> + +/* + * This file ensures that incident/incident_report.h actually compiles with C, + * since there is no other place in the tree that actually uses it from C. + */ +int not_called() { + return 0; +} + |