Android,Windows: support long paths in tooling

aar_resources_extractor now supports long paths
on Windows.

If the script needs to extract a file from the
AAR where the destination path is too long, the
script will:
1. create a temporary junction under a short path,
   pointing to the destination directory (which
   has a long path)
2. extract the file under the junction
3. delete the junction and the temp directory

See https://github.com/bazelbuild/bazel/issues/3659

Change-Id: Ie85665b360a6514afaac546aaec8869224fe9d06
PiperOrigin-RevId: 167545085
diff --git a/tools/android/aar_resources_extractor.py b/tools/android/aar_resources_extractor.py
index 0e259b8..eb0d432 100644
--- a/tools/android/aar_resources_extractor.py
+++ b/tools/android/aar_resources_extractor.py
@@ -26,6 +26,7 @@
 import sys
 import zipfile
 
+from tools.android import junction
 from third_party.py import gflags
 
 FLAGS = gflags.FLAGS
@@ -37,10 +38,19 @@
 
 
 def ExtractResources(aar, output_res_dir):
+  """Extract resource from an `aar` file to the `output_res_dir` directory."""
   aar_contains_no_resources = True
+  output_res_dir_abs = os.path.normpath(
+      os.path.join(os.getcwd(), output_res_dir))
   for name in aar.namelist():
     if name.startswith("res/"):
-      aar.extract(name, output_res_dir)
+      fullpath = os.path.normpath(os.path.join(output_res_dir_abs, name))
+      if os.name == "nt" and len(fullpath) >= 260:  # MAX_PATH in <windows.h>
+        with junction.TempJunction(os.path.dirname(fullpath)) as juncpath:
+          shortpath = os.path.join(juncpath, os.path.basename(fullpath))
+          aar.extract(name, shortpath)
+      else:
+        aar.extract(name, output_res_dir)
       aar_contains_no_resources = False
   if aar_contains_no_resources:
     empty_xml_filename = output_res_dir + "/res/values/empty.xml"