Use StatsDimensionsValueParcel within statsd apex
Because statsd now uses StatsDimensionsValueParcel instead of
StatsDimensionsValue.h/c, statsd no longer has to depend on libservices.
Test: m -j
Test: atest StatsdHostTestCases#testBroadcastSubscriber
Bug: 148604617
Change-Id: I6d65383ccec99f4672d6575232981c0f6cc40fcf
diff --git a/apex/statsd/aidl/android/os/IPendingIntentRef.aidl b/apex/statsd/aidl/android/os/IPendingIntentRef.aidl
index 0ec052f..000a699 100644
--- a/apex/statsd/aidl/android/os/IPendingIntentRef.aidl
+++ b/apex/statsd/aidl/android/os/IPendingIntentRef.aidl
@@ -42,5 +42,5 @@
*/
oneway void sendSubscriberBroadcast(long configUid, long configId, long subscriptionId,
long subscriptionRuleId, in String[] cookies,
- in StatsDimensionsValueParcel dimensionsValue);
+ in StatsDimensionsValueParcel dimensionsValueParcel);
}
diff --git a/apex/statsd/aidl/android/os/StatsDimensionsValueParcel.aidl b/apex/statsd/aidl/android/os/StatsDimensionsValueParcel.aidl
index 83faa72..a8685e3 100644
--- a/apex/statsd/aidl/android/os/StatsDimensionsValueParcel.aidl
+++ b/apex/statsd/aidl/android/os/StatsDimensionsValueParcel.aidl
@@ -4,7 +4,12 @@
* @hide
*/
parcelable StatsDimensionsValueParcel {
- int atomTag;
+ /**
+ * Field equals:
+ * - atomTag for top level StatsDimensionsValueParcel
+ * - position in dimension for all other levels
+ */
+ int field;
int valueType;
String stringValue;
@@ -12,5 +17,5 @@
long longValue;
boolean boolValue;
float floatValue;
- StatsDimensionsValueParcel[] arrayValue;
+ StatsDimensionsValueParcel[] tupleValue;
}
diff --git a/apex/statsd/framework/java/android/os/StatsDimensionsValue.java b/apex/statsd/framework/java/android/os/StatsDimensionsValue.java
index 886130f..71d4359 100644
--- a/apex/statsd/framework/java/android/os/StatsDimensionsValue.java
+++ b/apex/statsd/framework/java/android/os/StatsDimensionsValue.java
@@ -96,6 +96,47 @@
}
/**
+ * Creates a {@code StatsDimensionsValue} from a StatsDimensionsValueParcel
+ * TODO(b/149103391): Make StatsDimensionsValue a wrapper on top of
+ * StatsDimensionsValueParcel.
+ *
+ * @hide
+ */
+ public StatsDimensionsValue(StatsDimensionsValueParcel parcel) {
+ mField = parcel.field;
+ mValueType = parcel.valueType;
+ switch (mValueType) {
+ case STRING_VALUE_TYPE:
+ mValue = parcel.stringValue;
+ break;
+ case INT_VALUE_TYPE:
+ mValue = parcel.intValue;
+ break;
+ case LONG_VALUE_TYPE:
+ mValue = parcel.longValue;
+ break;
+ case BOOLEAN_VALUE_TYPE:
+ mValue = parcel.boolValue;
+ break;
+ case FLOAT_VALUE_TYPE:
+ mValue = parcel.floatValue;
+ break;
+ case TUPLE_VALUE_TYPE:
+ StatsDimensionsValue[] values = new StatsDimensionsValue[parcel.tupleValue.length];
+ for (int i = 0; i < parcel.tupleValue.length; i++) {
+ values[i] = new StatsDimensionsValue(parcel.tupleValue[i]);
+ }
+ mValue = values;
+ break;
+ default:
+ Slog.w(TAG, "StatsDimensionsValueParcel contains bad valueType: " + mValueType);
+ mValue = null;
+ break;
+ }
+ }
+
+
+ /**
* Return the field, i.e. the tag of a statsd atom.
*
* @return the field
diff --git a/apex/statsd/service/java/com/android/server/stats/StatsCompanion.java b/apex/statsd/service/java/com/android/server/stats/StatsCompanion.java
index de6723a..7cc6760 100644
--- a/apex/statsd/service/java/com/android/server/stats/StatsCompanion.java
+++ b/apex/statsd/service/java/com/android/server/stats/StatsCompanion.java
@@ -147,8 +147,9 @@
@Override
public void sendSubscriberBroadcast(long configUid, long configId, long subscriptionId,
long subscriptionRuleId, String[] cookies,
- StatsDimensionsValueParcel dimensionsValue) {
- enforceStatsCompanionPermission(mContext);
+ StatsDimensionsValueParcel dimensionsValueParcel) {
+ enforceStatsdCallingUid();
+ StatsDimensionsValue dimensionsValue = new StatsDimensionsValue(dimensionsValueParcel);
Intent intent =
new Intent()
.putExtra(StatsManager.EXTRA_STATS_CONFIG_UID, configUid)
@@ -169,8 +170,6 @@
"Statsd sendSubscriberBroadcast with params {%d %d %d %d %s %s}",
configUid, configId, subscriptionId, subscriptionRuleId,
Arrays.toString(cookies),
- // TODO (b/148604617): convert StatsDimensionsValueParcel into
- // StatsDimensionsValue
dimensionsValue));
}
try {
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index c8aae7b..956fd29 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -126,7 +126,6 @@
"libbinder",
"libincident",
"liblog",
- "libservices",
"libstatssocket",
"statsd-aidl-cpp",
],
diff --git a/cmds/statsd/src/HashableDimensionKey.cpp b/cmds/statsd/src/HashableDimensionKey.cpp
index 5b75b97..6b9d0e4 100644
--- a/cmds/statsd/src/HashableDimensionKey.cpp
+++ b/cmds/statsd/src/HashableDimensionKey.cpp
@@ -26,6 +26,86 @@
using std::string;
using std::vector;
+// These constants must be kept in sync with those in StatsDimensionsValue.java
+const static int STATS_DIMENSIONS_VALUE_STRING_TYPE = 2;
+const static int STATS_DIMENSIONS_VALUE_INT_TYPE = 3;
+const static int STATS_DIMENSIONS_VALUE_LONG_TYPE = 4;
+// const static int STATS_DIMENSIONS_VALUE_BOOL_TYPE = 5; (commented out because
+// unused -- statsd does not correctly support bool types)
+const static int STATS_DIMENSIONS_VALUE_FLOAT_TYPE = 6;
+const static int STATS_DIMENSIONS_VALUE_TUPLE_TYPE = 7;
+
+/**
+ * Recursive helper function that populates a parent StatsDimensionsValueParcel
+ * with children StatsDimensionsValueParcels.
+ *
+ * \param dims vector of FieldValues stored by HashableDimensionKey
+ * \param index positions in dims vector to start reading children from
+ * \param depth level of parent parcel in the full StatsDimensionsValueParcel
+ * tree
+ */
+static void populateStatsDimensionsValueParcelChildren(StatsDimensionsValueParcel &parentParcel,
+ const vector<FieldValue>& dims, size_t& index,
+ int depth, int prefix) {
+ while (index < dims.size()) {
+ const FieldValue& dim = dims[index];
+ int fieldDepth = dim.mField.getDepth();
+ int fieldPrefix = dim.mField.getPrefix(depth);
+ StatsDimensionsValueParcel childParcel;
+ childParcel.field = dim.mField.getPosAtDepth(depth);
+ if (depth > 2) {
+ ALOGE("Depth > 2 not supported by StatsDimensionsValueParcel.");
+ return;
+ }
+ if (depth == fieldDepth && prefix == fieldPrefix) {
+ switch (dim.mValue.getType()) {
+ case INT:
+ childParcel.valueType = STATS_DIMENSIONS_VALUE_INT_TYPE;
+ childParcel.intValue = dim.mValue.int_value;
+ break;
+ case LONG:
+ childParcel.valueType = STATS_DIMENSIONS_VALUE_LONG_TYPE;
+ childParcel.longValue = dim.mValue.long_value;
+ break;
+ case FLOAT:
+ childParcel.valueType = STATS_DIMENSIONS_VALUE_FLOAT_TYPE;
+ childParcel.floatValue = dim.mValue.float_value;
+ break;
+ case STRING:
+ childParcel.valueType = STATS_DIMENSIONS_VALUE_STRING_TYPE;
+ childParcel.stringValue = String16(dim.mValue.str_value.c_str());
+ break;
+ default:
+ ALOGE("Encountered FieldValue with unsupported value type.");
+ break;
+ }
+ index++;
+ parentParcel.tupleValue.push_back(childParcel);
+ } else if (fieldDepth > depth && fieldPrefix == prefix) {
+ childParcel.valueType = STATS_DIMENSIONS_VALUE_TUPLE_TYPE;
+ populateStatsDimensionsValueParcelChildren(childParcel, dims, index, depth + 1,
+ dim.mField.getPrefix(depth + 1));
+ parentParcel.tupleValue.push_back(childParcel);
+ } else {
+ return;
+ }
+ }
+}
+
+StatsDimensionsValueParcel HashableDimensionKey::toStatsDimensionsValueParcel() const {
+ StatsDimensionsValueParcel parcel;
+ if (mValues.size() == 0) {
+ return parcel;
+ }
+
+ parcel.field = mValues[0].mField.getTag();
+ parcel.valueType = STATS_DIMENSIONS_VALUE_TUPLE_TYPE;
+
+ size_t index = 0;
+ populateStatsDimensionsValueParcelChildren(parcel, mValues, index, /*depth=*/0, /*prefix=*/0);
+ return parcel;
+}
+
android::hash_t hashDimension(const HashableDimensionKey& value) {
android::hash_t hash = 0;
for (const auto& fieldValue : value.getValues()) {
diff --git a/cmds/statsd/src/HashableDimensionKey.h b/cmds/statsd/src/HashableDimensionKey.h
index 654e135..4adcf96 100644
--- a/cmds/statsd/src/HashableDimensionKey.h
+++ b/cmds/statsd/src/HashableDimensionKey.h
@@ -16,10 +16,11 @@
#pragma once
+#include <android/os/StatsDimensionsValueParcel.h>
#include <utils/JenkinsHash.h>
#include <vector>
-#include "FieldValue.h"
#include "android-base/stringprintf.h"
+#include "FieldValue.h"
#include "logd/LogEvent.h"
namespace android {
@@ -69,6 +70,8 @@
return nullptr;
}
+ StatsDimensionsValueParcel toStatsDimensionsValueParcel() const;
+
std::string toString() const;
bool operator!=(const HashableDimensionKey& that) const;
diff --git a/cmds/statsd/src/subscriber/SubscriberReporter.cpp b/cmds/statsd/src/subscriber/SubscriberReporter.cpp
index 2ddecc7..8fd6b46 100644
--- a/cmds/statsd/src/subscriber/SubscriberReporter.cpp
+++ b/cmds/statsd/src/subscriber/SubscriberReporter.cpp
@@ -115,15 +115,13 @@
const vector<String16>& cookies,
const MetricDimensionKey& dimKey) const {
VLOG("SubscriberReporter::sendBroadcastLocked called.");
- // TODO (b/148604617): convert MetricDimensionKey to StatsDimensiosnValueParcel
- StatsDimensionsValueParcel parcel;
pir->sendSubscriberBroadcast(
configKey.GetUid(),
configKey.GetId(),
subscription.id(),
subscription.rule_id(),
cookies,
- parcel);
+ dimKey.getDimensionKeyInWhat().toStatsDimensionsValueParcel());
}
sp<IPendingIntentRef> SubscriberReporter::getBroadcastSubscriber(const ConfigKey& configKey,
@@ -140,61 +138,6 @@
return pirMapIt->second;
}
-void getStatsDimensionsValueHelper(const vector<FieldValue>& dims, size_t* index, int depth,
- int prefix, vector<StatsDimensionsValue>* output) {
- size_t count = dims.size();
- while (*index < count) {
- const auto& dim = dims[*index];
- const int valueDepth = dim.mField.getDepth();
- const int valuePrefix = dim.mField.getPrefix(depth);
- if (valueDepth > 2) {
- ALOGE("Depth > 2 not supported");
- return;
- }
- if (depth == valueDepth && valuePrefix == prefix) {
- switch (dim.mValue.getType()) {
- case INT:
- output->push_back(StatsDimensionsValue(dim.mField.getPosAtDepth(depth),
- dim.mValue.int_value));
- break;
- case LONG:
- output->push_back(StatsDimensionsValue(dim.mField.getPosAtDepth(depth),
- dim.mValue.long_value));
- break;
- case FLOAT:
- output->push_back(StatsDimensionsValue(dim.mField.getPosAtDepth(depth),
- dim.mValue.float_value));
- break;
- case STRING:
- output->push_back(StatsDimensionsValue(dim.mField.getPosAtDepth(depth),
- String16(dim.mValue.str_value.c_str())));
- break;
- default:
- break;
- }
- (*index)++;
- } else if (valueDepth > depth && valuePrefix == prefix) {
- vector<StatsDimensionsValue> childOutput;
- getStatsDimensionsValueHelper(dims, index, depth + 1, dim.mField.getPrefix(depth + 1),
- &childOutput);
- output->push_back(StatsDimensionsValue(dim.mField.getPosAtDepth(depth), childOutput));
- } else {
- return;
- }
- }
-}
-
-StatsDimensionsValue SubscriberReporter::getStatsDimensionsValue(const HashableDimensionKey& dim) {
- if (dim.getValues().size() == 0) {
- return StatsDimensionsValue();
- }
-
- vector<StatsDimensionsValue> fields;
- size_t index = 0;
- getStatsDimensionsValueHelper(dim.getValues(), &index, 0, 0, &fields);
- return StatsDimensionsValue(dim.getValues()[0].mField.getTag(), fields);
-}
-
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/cmds/statsd/src/subscriber/SubscriberReporter.h b/cmds/statsd/src/subscriber/SubscriberReporter.h
index 087a1b8..42599f5 100644
--- a/cmds/statsd/src/subscriber/SubscriberReporter.h
+++ b/cmds/statsd/src/subscriber/SubscriberReporter.h
@@ -22,7 +22,6 @@
#include "config/ConfigKey.h"
#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" // subscription
-#include "android/os/StatsDimensionsValue.h"
#include "HashableDimensionKey.h"
#include <mutex>
@@ -70,8 +69,6 @@
sp<IPendingIntentRef> getBroadcastSubscriber(const ConfigKey& configKey, int64_t subscriberId);
- static StatsDimensionsValue getStatsDimensionsValue(const HashableDimensionKey& dim);
-
private:
SubscriberReporter() {};
diff --git a/cmds/statsd/tests/FieldValue_test.cpp b/cmds/statsd/tests/FieldValue_test.cpp
index f4a59ed..9e69d97 100644
--- a/cmds/statsd/tests/FieldValue_test.cpp
+++ b/cmds/statsd/tests/FieldValue_test.cpp
@@ -290,33 +290,34 @@
}
}
-TEST(AtomMatcherTest, TestSubscriberDimensionWrite) {
- HashableDimensionKey dim;
-
- int pos1[] = {1, 1, 1};
- int pos2[] = {1, 1, 2};
- int pos3[] = {1, 1, 3};
- int pos4[] = {2, 0, 0};
-
- Field field1(10, pos1, 2);
- Field field2(10, pos2, 2);
- Field field3(10, pos3, 2);
- Field field4(10, pos4, 0);
-
- Value value1((int32_t)10025);
- Value value2("tag");
- Value value3((int32_t)987654);
- Value value4((int32_t)99999);
-
- dim.addValue(FieldValue(field1, value1));
- dim.addValue(FieldValue(field2, value2));
- dim.addValue(FieldValue(field3, value3));
- dim.addValue(FieldValue(field4, value4));
-
- SubscriberReporter::getStatsDimensionsValue(dim);
- // TODO(b/110562792): can't test anything here because StatsDimensionsValue class doesn't
- // have any read api.
-}
+//TODO(b/149050405) Update this test for StatsDimensionValueParcel
+//TEST(AtomMatcherTest, TestSubscriberDimensionWrite) {
+// HashableDimensionKey dim;
+//
+// int pos1[] = {1, 1, 1};
+// int pos2[] = {1, 1, 2};
+// int pos3[] = {1, 1, 3};
+// int pos4[] = {2, 0, 0};
+//
+// Field field1(10, pos1, 2);
+// Field field2(10, pos2, 2);
+// Field field3(10, pos3, 2);
+// Field field4(10, pos4, 0);
+//
+// Value value1((int32_t)10025);
+// Value value2("tag");
+// Value value3((int32_t)987654);
+// Value value4((int32_t)99999);
+//
+// dim.addValue(FieldValue(field1, value1));
+// dim.addValue(FieldValue(field2, value2));
+// dim.addValue(FieldValue(field3, value3));
+// dim.addValue(FieldValue(field4, value4));
+//
+// SubscriberReporter::getStatsDimensionsValue(dim);
+// // TODO(b/110562792): can't test anything here because StatsDimensionsValue class doesn't
+// // have any read api.
+//}
TEST(AtomMatcherTest, TestWriteDimensionToProto) {
HashableDimensionKey dim;
diff --git a/core/java/android/os/StatsDimensionsValue.aidl b/core/java/android/os/StatsDimensionsValue.aidl
deleted file mode 100644
index 81a14a4..0000000
--- a/core/java/android/os/StatsDimensionsValue.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/**
- * 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.
- */
-
-package android.os;
-
-/** @hide */
-parcelable StatsDimensionsValue cpp_header "android/os/StatsDimensionsValue.h";
\ No newline at end of file
diff --git a/libs/services/Android.bp b/libs/services/Android.bp
index 9b047ca..1e62107 100644
--- a/libs/services/Android.bp
+++ b/libs/services/Android.bp
@@ -20,7 +20,6 @@
":IDropBoxManagerService.aidl",
"src/content/ComponentName.cpp",
"src/os/DropBoxManager.cpp",
- "src/os/StatsDimensionsValue.cpp",
],
shared_libs: [
diff --git a/libs/services/include/android/os/StatsDimensionsValue.h b/libs/services/include/android/os/StatsDimensionsValue.h
deleted file mode 100644
index cc0b056..0000000
--- a/libs/services/include/android/os/StatsDimensionsValue.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.
- */
-#ifndef STATS_DIMENSIONS_VALUE_H
-#define STATS_DIMENSIONS_VALUE_H
-
-#include <binder/Parcel.h>
-#include <binder/Parcelable.h>
-#include <binder/Status.h>
-#include <utils/String16.h>
-#include <vector>
-
-namespace android {
-namespace os {
-
-// Represents a parcelable object. Used to send data from statsd to StatsCompanionService.java.
-class StatsDimensionsValue : public android::Parcelable {
-public:
- StatsDimensionsValue();
-
- StatsDimensionsValue(int32_t field, String16 value);
- StatsDimensionsValue(int32_t field, int32_t value);
- StatsDimensionsValue(int32_t field, int64_t value);
- StatsDimensionsValue(int32_t field, bool value);
- StatsDimensionsValue(int32_t field, float value);
- StatsDimensionsValue(int32_t field, std::vector<StatsDimensionsValue> value);
-
- virtual ~StatsDimensionsValue();
-
- virtual android::status_t writeToParcel(android::Parcel* out) const override;
- virtual android::status_t readFromParcel(const android::Parcel* in) override;
-
-private:
- // Keep constants in sync with android/os/StatsDimensionsValue.java
- // and stats_log.proto's DimensionValue.
- static const int kStrValueType = 2;
- static const int kIntValueType = 3;
- static const int kLongValueType = 4;
- static const int kBoolValueType = 5;
- static const int kFloatValueType = 6;
- static const int kTupleValueType = 7;
-
- int32_t mField;
- int32_t mValueType;
-
- // This isn't very clever, but it isn't used for long-term storage, so it'll do.
- String16 mStrValue;
- int32_t mIntValue;
- int64_t mLongValue;
- bool mBoolValue;
- float mFloatValue;
- std::vector<StatsDimensionsValue> mTupleValue;
-};
-
-} // namespace os
-} // namespace android
-
-#endif // STATS_DIMENSIONS_VALUE_H
diff --git a/libs/services/src/os/StatsDimensionsValue.cpp b/libs/services/src/os/StatsDimensionsValue.cpp
deleted file mode 100644
index 0052e0b..0000000
--- a/libs/services/src/os/StatsDimensionsValue.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "StatsDimensionsValue"
-
-#include "android/os/StatsDimensionsValue.h"
-
-#include <cutils/log.h>
-
-using android::Parcel;
-using android::Parcelable;
-using android::status_t;
-using std::vector;
-
-namespace android {
-namespace os {
-
-StatsDimensionsValue::StatsDimensionsValue() {};
-
-StatsDimensionsValue::StatsDimensionsValue(int32_t field, String16 value) :
- mField(field),
- mValueType(kStrValueType),
- mStrValue(value) {
-}
-StatsDimensionsValue::StatsDimensionsValue(int32_t field, int32_t value) :
- mField(field),
- mValueType(kIntValueType),
- mIntValue(value) {
-}
-StatsDimensionsValue::StatsDimensionsValue(int32_t field, int64_t value) :
- mField(field),
- mValueType(kLongValueType),
- mLongValue(value) {
-}
-StatsDimensionsValue::StatsDimensionsValue(int32_t field, bool value) :
- mField(field),
- mValueType(kBoolValueType),
- mBoolValue(value) {
-}
-StatsDimensionsValue::StatsDimensionsValue(int32_t field, float value) :
- mField(field),
- mValueType(kFloatValueType),
- mFloatValue(value) {
-}
-StatsDimensionsValue::StatsDimensionsValue(int32_t field, vector<StatsDimensionsValue> value) :
- mField(field),
- mValueType(kTupleValueType),
- mTupleValue(value) {
-}
-
-StatsDimensionsValue::~StatsDimensionsValue() {}
-
-status_t
-StatsDimensionsValue::writeToParcel(Parcel* out) const {
- status_t err ;
-
- err = out->writeInt32(mField);
- if (err != NO_ERROR) {
- return err;
- }
- err = out->writeInt32(mValueType);
- if (err != NO_ERROR) {
- return err;
- }
- switch (mValueType) {
- case kStrValueType:
- err = out->writeString16(mStrValue);
- break;
- case kIntValueType:
- err = out->writeInt32(mIntValue);
- break;
- case kLongValueType:
- err = out->writeInt64(mLongValue);
- break;
- case kBoolValueType:
- err = out->writeBool(mBoolValue);
- break;
- case kFloatValueType:
- err = out->writeFloat(mFloatValue);
- break;
- case kTupleValueType:
- {
- int sz = mTupleValue.size();
- err = out->writeInt32(sz);
- if (err != NO_ERROR) {
- return err;
- }
- for (int i = 0; i < sz; ++i) {
- err = mTupleValue[i].writeToParcel(out);
- if (err != NO_ERROR) {
- return err;
- }
- }
- }
- break;
- default:
- err = UNKNOWN_ERROR;
- break;
- }
- return err;
-}
-
-status_t
-StatsDimensionsValue::readFromParcel(const Parcel* in)
-{
- // Implement me if desired. We don't currently use this.
- ALOGE("Cannot do c++ StatsDimensionsValue.readFromParcel(); it is not implemented.");
- (void)in; // To prevent compile error of unused parameter 'in'
- return UNKNOWN_ERROR;
-}
-
-} // namespace os
-} // namespace android