From 3ec5cc792e932dc668bf9fb2cf5e6c6288a7f9b4 Mon Sep 17 00:00:00 2001 From: Yi Jin Date: Fri, 26 Jan 2018 13:42:43 -0800 Subject: Modify SystemApi so it can be used by CTS to trigger incident report Bug: 72502621 Test: Cts/Gts tests covered, see the cls from the same topic Change-Id: Id0c1cc0fc0054e620de1349dab66513e554b1caa --- cmds/incidentd/src/Privacy.cpp | 7 +++-- cmds/incidentd/src/Privacy.h | 11 ++++---- cmds/incidentd/src/Reporter.cpp | 12 +++++++- cmds/incidentd/src/Reporter.h | 3 ++ cmds/incidentd/src/Section.cpp | 19 ++++++++----- cmds/incidentd/tests/PrivacyBuffer_test.cpp | 5 ++-- core/java/android/os/IncidentManager.java | 42 +++++++++++++++++++++++----- core/java/android/os/IncidentReportArgs.java | 13 ++++++++- core/proto/android/os/incident.proto | 1 - 9 files changed, 87 insertions(+), 26 deletions(-) diff --git a/cmds/incidentd/src/Privacy.cpp b/cmds/incidentd/src/Privacy.cpp index 44adaecfe97f..3f0e331c8b55 100644 --- a/cmds/incidentd/src/Privacy.cpp +++ b/cmds/incidentd/src/Privacy.cpp @@ -65,7 +65,7 @@ PrivacySpec::CheckPremission(const Privacy* privacy, const uint8_t defaultDest) bool PrivacySpec::RequireAll() const { return dest == android::os::DEST_LOCAL; } -PrivacySpec new_spec_from_args(int dest) +PrivacySpec PrivacySpec::new_spec(int dest) { switch (dest) { case android::os::DEST_AUTOMATIC: @@ -77,4 +77,7 @@ PrivacySpec new_spec_from_args(int dest) } } -PrivacySpec get_default_dropbox_spec() { return PrivacySpec(android::os::DEST_AUTOMATIC); } \ No newline at end of file +PrivacySpec PrivacySpec::get_default_dropbox_spec() +{ + return PrivacySpec(android::os::DEST_AUTOMATIC); +} diff --git a/cmds/incidentd/src/Privacy.h b/cmds/incidentd/src/Privacy.h index 9e15ff43be06..4f3db678f765 100644 --- a/cmds/incidentd/src/Privacy.h +++ b/cmds/incidentd/src/Privacy.h @@ -65,8 +65,6 @@ public: const uint8_t dest; PrivacySpec() : dest(DEST_DEFAULT_VALUE) {} - PrivacySpec(uint8_t dest) : dest(dest) {} - bool operator<(const PrivacySpec& other) const; // check permission of a policy, if returns true, don't strip the data. @@ -74,9 +72,12 @@ public: // if returns true, no data need to be stripped. bool RequireAll() const; -}; -PrivacySpec new_spec_from_args(int dest); -PrivacySpec get_default_dropbox_spec(); + // Constructs spec using static methods below. + static PrivacySpec new_spec(int dest); + static PrivacySpec get_default_dropbox_spec(); +private: + PrivacySpec(uint8_t dest) : dest(dest) {} +}; #endif // PRIVACY_H diff --git a/cmds/incidentd/src/Reporter.cpp b/cmds/incidentd/src/Reporter.cpp index bd559d6980f1..b9f479bd683f 100644 --- a/cmds/incidentd/src/Reporter.cpp +++ b/cmds/incidentd/src/Reporter.cpp @@ -64,7 +64,8 @@ ReportRequest::ok() ReportRequestSet::ReportRequestSet() :mRequests(), mSections(), - mMainFd(-1) + mMainFd(-1), + mMainDest(-1) { } @@ -86,6 +87,12 @@ ReportRequestSet::setMainFd(int fd) mMainFd = fd; } +void +ReportRequestSet::setMainDest(int dest) +{ + mMainDest = dest; +} + bool ReportRequestSet::containsSection(int id) { return mSections.containsSection(id); @@ -125,12 +132,14 @@ Reporter::runReport() status_t err = NO_ERROR; bool needMainFd = false; int mainFd = -1; + int mainDest = -1; HeaderSection headers; // See if we need the main file for (ReportRequestSet::iterator it=batch.begin(); it!=batch.end(); it++) { if ((*it)->fd < 0 && mainFd < 0) { needMainFd = true; + mainDest = (*it)->args.dest(); break; } } @@ -154,6 +163,7 @@ Reporter::runReport() // Add to the set batch.setMainFd(mainFd); + batch.setMainDest(mainDest); } // Tell everyone that we're starting. diff --git a/cmds/incidentd/src/Reporter.h b/cmds/incidentd/src/Reporter.h index 2615c6202d3d..f30ecf0dd648 100644 --- a/cmds/incidentd/src/Reporter.h +++ b/cmds/incidentd/src/Reporter.h @@ -53,6 +53,7 @@ public: void add(const sp& request); void setMainFd(int fd); + void setMainDest(int dest); typedef vector>::iterator iterator; @@ -61,10 +62,12 @@ public: int mainFd() { return mMainFd; } bool containsSection(int id); + int mainDest() { return mMainDest; } private: vector> mRequests; IncidentReportArgs mSections; int mMainFd; + int mMainDest; }; // ================================================================================ diff --git a/cmds/incidentd/src/Section.cpp b/cmds/incidentd/src/Section.cpp index 0827785811b6..faeab87f8178 100644 --- a/cmds/incidentd/src/Section.cpp +++ b/cmds/incidentd/src/Section.cpp @@ -152,36 +152,40 @@ write_report_requests(const int id, const FdBuffer& buffer, ReportRequestSet* re // The streaming ones, group requests by spec in order to save unnecessary strip operations map>> requestsBySpec; - for (ReportRequestSet::iterator it = requests->begin(); it != requests->end(); it++) { + for (auto it = requests->begin(); it != requests->end(); it++) { sp request = *it; if (!request->ok() || !request->args.containsSection(id)) { continue; // skip invalid request } - PrivacySpec spec = new_spec_from_args(request->args.dest()); + PrivacySpec spec = PrivacySpec::new_spec(request->args.dest()); requestsBySpec[spec].push_back(request); } - for (map>>::iterator mit = requestsBySpec.begin(); mit != requestsBySpec.end(); mit++) { + for (auto mit = requestsBySpec.begin(); mit != requestsBySpec.end(); mit++) { PrivacySpec spec = mit->first; err = privacyBuffer.strip(spec); if (err != NO_ERROR) return err; // it means the privacyBuffer data is corrupted. if (privacyBuffer.size() == 0) continue; - for (vector>::iterator it = mit->second.begin(); it != mit->second.end(); it++) { + for (auto it = mit->second.begin(); it != mit->second.end(); it++) { sp request = *it; err = write_section_header(request->fd, id, privacyBuffer.size()); if (err != NO_ERROR) { request->err = err; continue; } err = privacyBuffer.flush(request->fd); if (err != NO_ERROR) { request->err = err; continue; } writeable++; - ALOGD("Section %d flushed %zu bytes to fd %d with spec %d", id, privacyBuffer.size(), request->fd, spec.dest); + ALOGD("Section %d flushed %zu bytes to fd %d with spec %d", id, + privacyBuffer.size(), request->fd, spec.dest); } privacyBuffer.clear(); } // The dropbox file if (requests->mainFd() >= 0) { - err = privacyBuffer.strip(get_default_dropbox_spec()); + PrivacySpec spec = requests->mainDest() < 0 ? + PrivacySpec::get_default_dropbox_spec() : + PrivacySpec::new_spec(requests->mainDest()); + err = privacyBuffer.strip(spec); if (err != NO_ERROR) return err; // the buffer data is corrupted. if (privacyBuffer.size() == 0) goto DONE; @@ -190,7 +194,8 @@ write_report_requests(const int id, const FdBuffer& buffer, ReportRequestSet* re err = privacyBuffer.flush(requests->mainFd()); if (err != NO_ERROR) { requests->setMainFd(-1); goto DONE; } writeable++; - ALOGD("Section %d flushed %zu bytes to dropbox %d", id, privacyBuffer.size(), requests->mainFd()); + ALOGD("Section %d flushed %zu bytes to dropbox %d with spec %d", id, + privacyBuffer.size(), requests->mainFd(), spec.dest); } DONE: diff --git a/cmds/incidentd/tests/PrivacyBuffer_test.cpp b/cmds/incidentd/tests/PrivacyBuffer_test.cpp index 32b9e42d270c..c7bfe5555743 100644 --- a/cmds/incidentd/tests/PrivacyBuffer_test.cpp +++ b/cmds/incidentd/tests/PrivacyBuffer_test.cpp @@ -73,7 +73,7 @@ public: } void assertStrip(uint8_t dest, string expected, Privacy* policy) { - PrivacySpec spec(dest); + PrivacySpec spec = PrivacySpec::new_spec(dest); EncodedBuffer::iterator bufData = buffer.data(); PrivacyBuffer privacyBuf(policy, bufData); ASSERT_EQ(privacyBuf.strip(spec), NO_ERROR); @@ -224,7 +224,8 @@ TEST_F(PrivacyBufferTest, ClearAndStrip) { Privacy* list[] = { create_privacy(1, OTHER_TYPE, DEST_LOCAL), NULL }; EncodedBuffer::iterator bufData = buffer.data(); PrivacyBuffer privacyBuf(create_message_privacy(300, list), bufData); - PrivacySpec spec1(DEST_EXPLICIT), spec2(DEST_LOCAL); + PrivacySpec spec1 = PrivacySpec::new_spec(DEST_EXPLICIT); + PrivacySpec spec2 = PrivacySpec::new_spec(DEST_LOCAL); ASSERT_EQ(privacyBuf.strip(spec1), NO_ERROR); assertBuffer(privacyBuf, STRING_FIELD_0); diff --git a/core/java/android/os/IncidentManager.java b/core/java/android/os/IncidentManager.java index 1336c66b7133..9b6d6e56407a 100644 --- a/core/java/android/os/IncidentManager.java +++ b/core/java/android/os/IncidentManager.java @@ -33,10 +33,12 @@ import android.util.Slog; @TestApi @SystemService(Context.INCIDENT_SERVICE) public class IncidentManager { - private static final String TAG = "incident"; + private static final String TAG = "IncidentManager"; private final Context mContext; + private IIncidentManager mService; + /** * @hide */ @@ -96,19 +98,45 @@ public class IncidentManager { reportIncidentInternal(args); } - private void reportIncidentInternal(IncidentReportArgs args) { - final IIncidentManager service = IIncidentManager.Stub.asInterface( - ServiceManager.getService(Context.INCIDENT_SERVICE)); - if (service == null) { - Slog.e(TAG, "reportIncident can't find incident binder service"); - return; + private class IncidentdDeathRecipient implements IBinder.DeathRecipient { + @Override + public void binderDied() { + synchronized (this) { + mService = null; + } } + } + private void reportIncidentInternal(IncidentReportArgs args) { try { + final IIncidentManager service = getIIncidentManagerLocked(); + if (service == null) { + Slog.e(TAG, "reportIncident can't find incident binder service"); + return; + } service.reportIncident(args); } catch (RemoteException ex) { Slog.e(TAG, "reportIncident failed", ex); } } + + private IIncidentManager getIIncidentManagerLocked() throws RemoteException { + if (mService != null) { + return mService; + } + + synchronized (this) { + if (mService != null) { + return mService; + } + mService = IIncidentManager.Stub.asInterface( + ServiceManager.getService(Context.INCIDENT_SERVICE)); + if (mService != null) { + mService.asBinder().linkToDeath(new IncidentdDeathRecipient(), 0); + } + return mService; + } + } + } diff --git a/core/java/android/os/IncidentReportArgs.java b/core/java/android/os/IncidentReportArgs.java index fd0ebcfea080..9fa129cb98b4 100644 --- a/core/java/android/os/IncidentReportArgs.java +++ b/core/java/android/os/IncidentReportArgs.java @@ -32,6 +32,9 @@ import java.util.ArrayList; @TestApi public final class IncidentReportArgs implements Parcelable { + private static final int DEST_EXPLICIT = 100; + private static final int DEST_AUTO = 200; + private final IntArray mSections = new IntArray(); private final ArrayList mHeaders = new ArrayList(); private boolean mAll; @@ -41,6 +44,7 @@ public final class IncidentReportArgs implements Parcelable { * Construct an incident report args with no fields. */ public IncidentReportArgs() { + mDest = DEST_AUTO; } /** @@ -143,7 +147,14 @@ public final class IncidentReportArgs implements Parcelable { * @hide */ public void setPrivacyPolicy(int dest) { - mDest = dest; + switch (dest) { + case DEST_EXPLICIT: + case DEST_AUTO: + mDest = dest; + break; + default: + mDest = DEST_AUTO; + } } /** diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto index 3ec6f057af88..8a04bf7253e4 100644 --- a/core/proto/android/os/incident.proto +++ b/core/proto/android/os/incident.proto @@ -16,7 +16,6 @@ syntax = "proto2"; option java_multiple_files = true; -option java_outer_classname = "IncidentProtoMetadata"; import "frameworks/base/core/proto/android/os/batterytype.proto"; import "frameworks/base/core/proto/android/os/cpufreq.proto"; -- cgit v1.2.3-59-g8ed1b