Fix logfile path if not absolute

If 'logfile' parameter is not absolute, no log file is written because
an app default cwd is '/'. When we can, we fix it by using directory
/data/data/packageName.

Manual testing:
adb root
adb shell stop
adb shell setprop dalvik.vm.extra-opts "-verbose:jdwp,startup -XjdwpOptions:logfile=fab.log,logflags=0xfff,directlog=y"
adb shell start

Test: Manual
Bug: 286291596
Reland: asop/2618135

I am not convinced asop/2618135 was the real cause of the breakages in
Chromium for three reasons:

1/ The error seems unrelated to ART (module "aconfig.test.java)
2/ The previous CL (asop/2619790) had the same errors (See
https://ci.chromium.org/ui/p/art/builders/ci/angler-armv8-debug/3558/overview). It was
not reverted but the build still came back green.
3/ Even after the rever, I still see the same kind of errors across Chromium tree (https://ci.chromium.org/ui/p/art/builders/ci/angler-armv8-debug/3559/overview).

Change-Id: I0968c502a012a8f66f3636a7c8f7f64f107946e7
diff --git a/adbconnection/adbconnection.cc b/adbconnection/adbconnection.cc
index 3ca9166..4759bed 100644
--- a/adbconnection/adbconnection.cc
+++ b/adbconnection/adbconnection.cc
@@ -859,6 +859,36 @@
   return res;
 }
 
+#if defined(__ANDROID__)
+void FixLogfile(JdwpArgs& parameters) {
+  const std::string kLogfile = "logfile";
+  // On Android, an app will not have write access to the cwd (which is "/").
+  // If a relative path was provided, we need to patch it with a writable
+  // location. For now, we use /data/data/<PKG_NAME>.
+  // Note that /data/local/tmp/ was also considered but it not a good candidate since apps don't
+  // have write access to it.
+
+  if (!parameters.contains(kLogfile)) {
+    return;
+  }
+
+  std::string& logfile = parameters.get(kLogfile);
+  if (logfile.front() == '/') {
+    // We only fix logfile if it is not using an absolute path
+    return;
+  }
+
+  std::string packageName = art::Runtime::Current()->GetProcessPackageName();
+  if (packageName.empty()) {
+    VLOG(jdwp) << "Unable to fix relative path logfile='" + logfile + "' without package name.";
+    return;
+  }
+  parameters.put(kLogfile, "/data/data/" + packageName + "/" + logfile);
+}
+#else
+void FixLogfile(JdwpArgs&) {}
+#endif
+
 std::string AdbConnectionState::MakeAgentArg() {
   const std::string& opts = art::Runtime::Current()->GetJdwpOptions();
   DCHECK(ValidateJdwpOptions(opts));
@@ -883,6 +913,9 @@
   parameters.put("transport", "dt_fd_forward");
   parameters.put("address", std::to_string(remote_agent_control_sock_));
 
+  // If logfile is relative, we need to fix it.
+  FixLogfile(parameters);
+
   // TODO Get agent_name_ from something user settable?
   return agent_name_ + "=" + parameters.join();
 }
diff --git a/adbconnection/jdwpargs.h b/adbconnection/jdwpargs.h
index f3ade44..c1c69e2 100644
--- a/adbconnection/jdwpargs.h
+++ b/adbconnection/jdwpargs.h
@@ -37,6 +37,10 @@
   // Add a key / value
   void put(const std::string& key, const std::string& value);
 
+  bool contains(const std::string& key) { return store.find(key) != store.end(); }
+
+  std::string& get(const std::string& key) { return store[key]; }
+
   // Concatenate all key/value into a command separated list of "key=value" entries.
   std::string join();