Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2756)

Unified Diff: build/android/pylib/android_commands.py

Issue 276813002: Make it harder to leak temp files on devices (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | build/android/pylib/android_commands_unittest.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: build/android/pylib/android_commands.py
diff --git a/build/android/pylib/android_commands.py b/build/android/pylib/android_commands.py
index f43fc4921795b4952ef64f0867c7bdd24d0a0d69..816b002479afe0dcc8913894189f4e5f823ef077 100644
--- a/build/android/pylib/android_commands.py
+++ b/build/android/pylib/android_commands.py
@@ -13,6 +13,7 @@ import datetime
import inspect
import logging
import os
+import random
import re
import shlex
import signal
@@ -78,6 +79,34 @@ CONTROL_USB_CHARGING_COMMANDS = [
},
]
+class DeviceTempFile(object):
+ def __init__(self, android_commands, prefix='temp_file', suffix=''):
+ """Find an unused temporary file path in the devices external directory.
+
+ When this object is closed, the file will be deleted on the device.
+ """
+ self.android_commands = android_commands
+ while True:
+ # TODO(cjhopman): This could actually return the same file in multiple
+ # calls if the caller doesn't write to the files immediately. This is
+ # expected to never happen.
+ i = random.randint(0, 1000000)
+ self.name = '%s/%s-%d-%010d%s' % (
+ android_commands.GetExternalStorage(),
+ prefix, int(time.time()), i, suffix)
+ if not android_commands.FileExistsOnDevice(self.name):
+ break
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, type, value, traceback):
+ self.close()
+
+ def close(self):
+ self.android_commands.RunShellCommand('rm ' + self.name)
+
+
def GetAVDs():
"""Returns a list of AVDs."""
re_avd = re.compile('^[ ]+Name: ([a-zA-Z0-9_:.-]+)', re.MULTILINE)
@@ -1125,16 +1154,6 @@ class AndroidCommands(object):
f.flush()
self._adb.Push(f.name, filename)
- _TEMP_FILE_BASE_FMT = 'temp_file_%d'
- _TEMP_SCRIPT_FILE_BASE_FMT = 'temp_script_file_%d.sh'
-
- def _GetDeviceTempFileName(self, base_name):
- i = 0
- while self.FileExistsOnDevice(
- self.GetExternalStorage() + '/' + base_name % i):
- i += 1
- return self.GetExternalStorage() + '/' + base_name % i
-
def RunShellCommandWithSU(self, command, timeout_time=20, log_result=False):
return self.RunShellCommand('su -c %s' % command, timeout_time, log_result)
@@ -1192,27 +1211,22 @@ class AndroidCommands(object):
This is less efficient than SetFileContents.
"""
- temp_file = self._GetDeviceTempFileName(AndroidCommands._TEMP_FILE_BASE_FMT)
- temp_script = self._GetDeviceTempFileName(
- AndroidCommands._TEMP_SCRIPT_FILE_BASE_FMT)
+ with DeviceTempFile(self) as temp_file:
+ with DeviceTempFile(self, suffix=".sh") as temp_script:
+ # Put the contents in a temporary file
+ self.SetFileContents(temp_file.name, contents)
+ # Create a script to copy the file contents to its final destination
+ self.SetFileContents(temp_script.name,
+ 'cat %s > %s' % (temp_file.name, filename))
+
+ command = 'sh %s' % temp_script.name
+ command_runner = self._GetProtectedFileCommandRunner()
+ if command_runner:
+ return command_runner(command)
+ else:
+ logging.warning(
+ 'Could not set contents of protected file: %s' % filename)
- try:
- # Put the contents in a temporary file
- self.SetFileContents(temp_file, contents)
- # Create a script to copy the file contents to its final destination
- self.SetFileContents(temp_script, 'cat %s > %s' % (temp_file, filename))
-
- command = 'sh %s' % temp_script
- command_runner = self._GetProtectedFileCommandRunner()
- if command_runner:
- return command_runner(command)
- else:
- logging.warning(
- 'Could not set contents of protected file: %s' % filename)
- finally:
- # And remove the temporary files
- self.RunShellCommand('rm ' + temp_file)
- self.RunShellCommand('rm ' + temp_script)
def RemovePushedFiles(self):
"""Removes all files pushed with PushIfNeeded() from the device."""
@@ -1877,28 +1891,23 @@ class AndroidCommands(object):
dest: absolute path of destination directory
"""
logging.info('In EfficientDeviceDirectoryCopy %s %s', source, dest)
- temp_script_file = self._GetDeviceTempFileName(
- AndroidCommands._TEMP_SCRIPT_FILE_BASE_FMT)
- host_script_path = os.path.join(constants.DIR_SOURCE_ROOT,
- 'build',
- 'android',
- 'pylib',
- 'efficient_android_directory_copy.sh')
- try:
- self._adb.Push(host_script_path, temp_script_file)
- self.EnableAdbRoot()
- out = self.RunShellCommand('sh %s %s %s' % (temp_script_file,
- source,
- dest),
- timeout_time=120)
+ with DeviceTempFile(self, suffix=".sh") as temp_script_file:
+ host_script_path = os.path.join(constants.DIR_SOURCE_ROOT,
+ 'build',
+ 'android',
+ 'pylib',
+ 'efficient_android_directory_copy.sh')
+ self._adb.Push(host_script_path, temp_script_file.name)
+ self.EnableAdbRoot
+ out = self.RunShellCommand(
+ 'sh %s %s %s' % (temp_script_file.name, source, dest),
+ timeout_time=120)
if self._device:
device_repr = self._device[-4:]
else:
device_repr = '????'
for line in out:
logging.info('[%s]> %s', device_repr, line)
- finally:
- self.RunShellCommand('rm %s' % temp_script_file)
def _GetControlUsbChargingCommand(self):
if self._control_usb_charging_command['cached']:
« no previous file with comments | « no previous file | build/android/pylib/android_commands_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698