Snap for 7618979 from 157c361197f1902b4432533e9f9f63c497f28cee to sc-v2-release

Change-Id: Iac6f71d37fec33b9cb7d79791e75730c957bb9a6
diff --git a/derive_classpath/derive_classpath.cpp b/derive_classpath/derive_classpath.cpp
index b22e832..d379a40 100644
--- a/derive_classpath/derive_classpath.cpp
+++ b/derive_classpath/derive_classpath.cpp
@@ -109,7 +109,16 @@
   LOG(INFO) << "WriteClasspathExports content\n" << content;
 
   const std::string path_str(output_path);
-  return android::base::WriteStringToFile(content, path_str, /*follow_symlinks=*/true);
+  if (android::base::StartsWith(path_str, "/data/")) {
+    // When writing to /data, write to a temp file first to make sure the partition is not full.
+    const std::string temp_str(path_str + ".tmp");
+    if (!android::base::WriteStringToFile(content, temp_str, /*follow_symlinks=*/true)) {
+      return false;
+    }
+    return rename(temp_str.c_str(), path_str.c_str()) == 0;
+  } else {
+    return android::base::WriteStringToFile(content, path_str, /*follow_symlinks=*/true);
+  }
 }
 
 bool ReadClasspathFragment(ExportedClasspathsJars* fragment, const std::string& filepath) {
diff --git a/derive_classpath/derive_classpath_test.cpp b/derive_classpath/derive_classpath_test.cpp
index 7e7be4e..97e2581 100644
--- a/derive_classpath/derive_classpath_test.cpp
+++ b/derive_classpath/derive_classpath_test.cpp
@@ -138,7 +138,7 @@
   AddJarToClasspath("/apex/com.android.baz", "/apex/com.android.baz/javalib/baz",
                     SYSTEMSERVERCLASSPATH);
 
-  GenerateClasspathExports(working_dir());
+  ASSERT_TRUE(GenerateClasspathExports(working_dir()));
 
   const std::vector<std::string> exportLines = ParseExportsFile();
 
@@ -160,7 +160,7 @@
   AddJarToClasspath("/apex/com.android.bar", "/apex/com.android.bar/javalib/bar", BOOTCLASSPATH);
   AddJarToClasspath("/apex/com.android.baz", "/apex/com.android.baz/javalib/baz", BOOTCLASSPATH);
 
-  GenerateClasspathExports(working_dir());
+  ASSERT_TRUE(GenerateClasspathExports(working_dir()));
 
   const std::vector<std::string> exportLines = ParseExportsFile();
   const std::vector<std::string> splitExportLine = SplitClasspathExportLine(exportLines[0]);
@@ -187,7 +187,7 @@
   android::base::unique_fd fd(memfd_create("temp_file", MFD_CLOEXEC));
   ASSERT_TRUE(fd.ok()) << "Unable to open temp-file";
   const std::string file_name = android::base::StringPrintf("/proc/self/fd/%d", fd.get());
-  GenerateClasspathExports(working_dir(), file_name);
+  ASSERT_TRUE(GenerateClasspathExports(working_dir(), file_name));
 
   const std::vector<std::string> exportLines = ParseExportsFile(file_name.c_str());
   const std::vector<std::string> splitExportLine = SplitClasspathExportLine(exportLines[0]);
@@ -203,6 +203,14 @@
   EXPECT_EQ(expectedJars, exportValue);
 }
 
+// Test output location that can't be written to.
+TEST_F(DeriveClasspathTest, NonWriteableOutputLocation) {
+  AddJarToClasspath("/apex/com.android.art", "/apex/com.android.art/javalib/art", BOOTCLASSPATH);
+  AddJarToClasspath("/system", "/system/framework/jar", BOOTCLASSPATH);
+
+  ASSERT_FALSE(GenerateClasspathExports(working_dir(), "/system/non_writable_path"));
+}
+
 // Test apexes only export their own jars.
 TEST_F(DeriveClasspathDeathTest, ApexJarsBelongToApex) {
   // EXPECT_DEATH expects error messages in stderr, log there
diff --git a/manifest.json b/manifest.json
index 7c089da..01062af 100644
--- a/manifest.json
+++ b/manifest.json
@@ -1,4 +1,4 @@
 {
   "name": "com.android.sdkext",
-  "version": 309999900
+  "version": 319999900
 }