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