11bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe/* Copyright (C) 2017 The Android Open Source Project
21bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
31bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe *
41bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe * This file implements interfaces from the file jvmti.h. This implementation
51bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe * is licensed under the same terms as the file jvmti.h.  The
61bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe * copyright and license information for the file jvmti.h follows.
71bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe *
81bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
91bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
101bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe *
111bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe * This code is free software; you can redistribute it and/or modify it
121bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe * under the terms of the GNU General Public License version 2 only, as
131bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe * published by the Free Software Foundation.  Oracle designates this
141bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe * particular file as subject to the "Classpath" exception as provided
151bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe * by Oracle in the LICENSE file that accompanied this code.
161bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe *
171bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe * This code is distributed in the hope that it will be useful, but WITHOUT
181bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
191bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
201bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe * version 2 for more details (a copy is included in the LICENSE file that
211bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe * accompanied this code).
221bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe *
231bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe * You should have received a copy of the GNU General Public License version
241bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe * 2 along with this work; if not, write to the Free Software Foundation,
251bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
261bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe *
271bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
281bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe * or visit www.oracle.com if you need additional information or have any
291bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe * questions.
301bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe */
311bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe
321bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe#include "ti_properties.h"
331bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe
341bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe#include <string.h>
351bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe#include <vector>
361bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe
379e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe#include "jni.h"
38373a9b5c718a45ac484afcf4fe6ce84f4bb562b3Andreas Gampe#include "nativehelper/scoped_local_ref.h"
39373a9b5c718a45ac484afcf4fe6ce84f4bb562b3Andreas Gampe#include "nativehelper/scoped_utf_chars.h"
409e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe
411bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe#include "art_jvmti.h"
421bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe#include "runtime.h"
43b486a98aadc95d80548953410cf23edba62259faAndreas Gampe#include "thread-current-inl.h"
449e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe#include "ti_phase.h"
459e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe#include "well_known_classes.h"
461bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe
471bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampenamespace openjdkjvmti {
481bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe
491bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe// Hardcoded properties. Tests ensure that these are consistent with libcore's view, as seen
501bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe// in System.java and AndroidHardcodedSystemProperties.java.
511bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampestatic constexpr const char* kProperties[][2] = {
521bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    // Recommended by the spec.
531bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    { "java.vm.vendor", "The Android Project" },
541bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    { "java.vm.version", "2.1.0" },  // This is Runtime::GetVersion().
551bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    { "java.vm.name", "Dalvik" },
561bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    // Android does not provide java.vm.info.
571bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    //
581bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    // These are other values provided by AndroidHardcodedSystemProperties.
591bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    { "java.class.version", "50.0" },
601bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    { "java.version", "0" },
611bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    { "java.compiler", "" },
621bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    { "java.ext.dirs", "" },
631bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe
641bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    { "java.specification.name", "Dalvik Core Library" },
651bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    { "java.specification.vendor", "The Android Project" },
661bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    { "java.specification.version", "0.9" },
671bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe
681bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    { "java.vendor", "The Android Project" },
691bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    { "java.vendor.url", "http://www.android.com/" },
701bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    { "java.vm.name", "Dalvik" },
711bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    { "java.vm.specification.name", "Dalvik Virtual Machine Specification" },
721bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    { "java.vm.specification.vendor", "The Android Project" },
731bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    { "java.vm.specification.version", "0.9" },
741bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    { "java.vm.vendor", "The Android Project" },
751bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe
761bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    { "java.vm.vendor.url", "http://www.android.com/" },
771bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe
781bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    { "java.net.preferIPv6Addresses", "false" },
791bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe
801bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    { "file.encoding", "UTF-8" },
811bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe
821bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    { "file.separator", "/" },
831bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    { "line.separator", "\n" },
841bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    { "path.separator", ":" },
851bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe
861bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    { "os.name", "Linux" },
871bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe};
881bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampestatic constexpr size_t kPropertiesSize = arraysize(kProperties);
891bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampestatic constexpr const char* kPropertyLibraryPath = "java.library.path";
901bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampestatic constexpr const char* kPropertyClassPath = "java.class.path";
911bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe
921bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas GampejvmtiError PropertiesUtil::GetSystemProperties(jvmtiEnv* env,
931bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe                                               jint* count_ptr,
941bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe                                               char*** property_ptr) {
951bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe  if (count_ptr == nullptr || property_ptr == nullptr) {
961bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    return ERR(NULL_POINTER);
971bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe  }
985471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe  jvmtiError array_alloc_result;
995471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe  JvmtiUniquePtr<char*[]> array_data_ptr = AllocJvmtiUniquePtr<char*[]>(env,
1005471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe                                                                        kPropertiesSize + 2,
1015471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe                                                                        &array_alloc_result);
1025471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe  if (array_data_ptr == nullptr) {
1031bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    return array_alloc_result;
1041bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe  }
1051bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe
1065471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe  std::vector<JvmtiUniquePtr<char[]>> property_copies;
1071bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe
1081bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe  {
1095471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe    jvmtiError libpath_result;
1105471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe    JvmtiUniquePtr<char[]> libpath_data = CopyString(env, kPropertyLibraryPath, &libpath_result);
1115471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe    if (libpath_data == nullptr) {
1121bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe      return libpath_result;
1131bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    }
1145471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe    array_data_ptr.get()[0] = libpath_data.get();
1155471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe    property_copies.push_back(std::move(libpath_data));
1161bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe  }
1171bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe
1181bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe  {
1195471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe    jvmtiError classpath_result;
1205471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe    JvmtiUniquePtr<char[]> classpath_data = CopyString(env, kPropertyClassPath, &classpath_result);
1215471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe    if (classpath_data == nullptr) {
1221bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe      return classpath_result;
1231bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    }
1245471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe    array_data_ptr.get()[1] = classpath_data.get();
1255471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe    property_copies.push_back(std::move(classpath_data));
1261bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe  }
1271bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe
1281bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe  for (size_t i = 0; i != kPropertiesSize; ++i) {
1295471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe    jvmtiError data_result;
1305471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe    JvmtiUniquePtr<char[]> data = CopyString(env, kProperties[i][0], &data_result);
1315471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe    if (data == nullptr) {
1321bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe      return data_result;
1331bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    }
1345471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe    array_data_ptr.get()[i + 2] = data.get();
1355471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe    property_copies.push_back(std::move(data));
1361bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe  }
1371bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe
1381bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe  // Everything is OK, release the data.
1395471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe  *count_ptr = kPropertiesSize + 2;
1405471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe  *property_ptr = array_data_ptr.release();
1411bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe  for (auto& uptr : property_copies) {
1421bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    uptr.release();
1431bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe  }
1441bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe
1451bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe  return ERR(NONE);
1461bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe}
1471bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe
1485471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampestatic jvmtiError Copy(jvmtiEnv* env, const char* in, char** out) {
1495471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe  jvmtiError result;
1505471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe  JvmtiUniquePtr<char[]> data = CopyString(env, in, &result);
1515471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe  *out = data.release();
1525471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe  return result;
1535471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe}
1545471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe
1558018810a3fa49708fb7aeda01a675ad9e0d0b8c0Andreas Gampe// See dalvik_system_VMRuntime.cpp.
1568018810a3fa49708fb7aeda01a675ad9e0d0b8c0Andreas Gampestatic const char* DefaultToDot(const std::string& class_path) {
1578018810a3fa49708fb7aeda01a675ad9e0d0b8c0Andreas Gampe  return class_path.empty() ? "." : class_path.c_str();
1588018810a3fa49708fb7aeda01a675ad9e0d0b8c0Andreas Gampe}
1598018810a3fa49708fb7aeda01a675ad9e0d0b8c0Andreas Gampe
1609e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe// Handle kPropertyLibraryPath.
1619e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampestatic jvmtiError GetLibraryPath(jvmtiEnv* env, char** value_ptr) {
1629e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe  const std::vector<std::string>& runtime_props = art::Runtime::Current()->GetProperties();
1639e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe  for (const std::string& prop_assignment : runtime_props) {
1649e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe    size_t assign_pos = prop_assignment.find('=');
1659e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe    if (assign_pos != std::string::npos && assign_pos > 0) {
1669e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe      if (prop_assignment.substr(0, assign_pos) == kPropertyLibraryPath) {
1679e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe        return Copy(env, prop_assignment.substr(assign_pos + 1).c_str(), value_ptr);
1689e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe      }
1699e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe    }
1709e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe  }
1719e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe  if (!PhaseUtil::IsLivePhase()) {
1729e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe    return ERR(NOT_AVAILABLE);
1739e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe  }
1749e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe  // We expect this call to be rare. So don't optimize.
1759e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe  DCHECK(art::Thread::Current() != nullptr);
1769e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe  JNIEnv* jni_env = art::Thread::Current()->GetJniEnv();
1779e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe  jmethodID get_prop = jni_env->GetStaticMethodID(art::WellKnownClasses::java_lang_System,
1789e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe                                                  "getProperty",
1799e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe                                                  "(Ljava/lang/String;)Ljava/lang/String;");
1809e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe  CHECK(get_prop != nullptr);
1819e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe
1829e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe  ScopedLocalRef<jobject> input_str(jni_env, jni_env->NewStringUTF(kPropertyLibraryPath));
1839e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe  if (input_str.get() == nullptr) {
1849e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe    jni_env->ExceptionClear();
1859e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe    return ERR(OUT_OF_MEMORY);
1869e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe  }
1879e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe
1889e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe  ScopedLocalRef<jobject> prop_res(
1899e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe      jni_env, jni_env->CallStaticObjectMethod(art::WellKnownClasses::java_lang_System,
1909e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe                                               get_prop,
1919e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe                                               input_str.get()));
1929e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe  if (jni_env->ExceptionCheck() == JNI_TRUE) {
1939e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe    jni_env->ExceptionClear();
1949e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe    return ERR(INTERNAL);
1959e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe  }
1969e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe  if (prop_res.get() == nullptr) {
1979e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe    *value_ptr = nullptr;
1989e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe    return ERR(NONE);
1999e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe  }
2009e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe
2019e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe  ScopedUtfChars chars(jni_env, reinterpret_cast<jstring>(prop_res.get()));
2029e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe  return Copy(env, chars.c_str(), value_ptr);
2039e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe}
2049e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe
2051bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas GampejvmtiError PropertiesUtil::GetSystemProperty(jvmtiEnv* env,
2061bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe                                             const char* property,
2071bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe                                             char** value_ptr) {
2081bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe  if (property == nullptr || value_ptr == nullptr) {
2091bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    return ERR(NULL_POINTER);
2101bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe  }
2111bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe
2121bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe  if (strcmp(property, kPropertyLibraryPath) == 0) {
2139e2c81b67caf4d3b44f8c577b48d632c9b02b220Andreas Gampe    return GetLibraryPath(env, value_ptr);
2141bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe  }
2151bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe
2161bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe  if (strcmp(property, kPropertyClassPath) == 0) {
2178018810a3fa49708fb7aeda01a675ad9e0d0b8c0Andreas Gampe    return Copy(env, DefaultToDot(art::Runtime::Current()->GetClassPathString()), value_ptr);
2181bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe  }
2191bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe
2201bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe  for (size_t i = 0; i != kPropertiesSize; ++i) {
2211bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    if (strcmp(property, kProperties[i][0]) == 0) {
2221bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe      return Copy(env, kProperties[i][1], value_ptr);
2231bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe    }
2241bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe  }
2251bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe
2261bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe  return ERR(NOT_AVAILABLE);
2271bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe}
2281bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe
2291bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas GampejvmtiError PropertiesUtil::SetSystemProperty(jvmtiEnv* env ATTRIBUTE_UNUSED,
2301bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe                                             const char* property ATTRIBUTE_UNUSED,
2311bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe                                             const char* value ATTRIBUTE_UNUSED) {
2321bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe  // We do not allow manipulation of any property here.
2331bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe  return ERR(NOT_AVAILABLE);
2341bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe}
2351bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe
2361bdaf733b472bc79a8e385f0563ffed603a2c93eAndreas Gampe}  // namespace openjdkjvmti
237