diff options
7 files changed, 55 insertions, 9 deletions
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java index c1a1809d4962..5f6c4f009b41 100644 --- a/core/java/android/os/ParcelFileDescriptor.java +++ b/core/java/android/os/ParcelFileDescriptor.java @@ -230,7 +230,11 @@ public class ParcelFileDescriptor implements Parcelable { @Override public void close() throws IOException { - mFd.close(); + try { + mFd.close(); + } finally { + super.close(); + } } } @@ -249,7 +253,11 @@ public class ParcelFileDescriptor implements Parcelable { @Override public void close() throws IOException { - mFd.close(); + try { + mFd.close(); + } finally { + super.close(); + } } } diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java index 34d3b85157c3..ab5173e9524b 100644 --- a/core/java/android/os/StrictMode.java +++ b/core/java/android/os/StrictMode.java @@ -26,6 +26,7 @@ import android.util.Printer; import com.android.internal.os.RuntimeInit; import dalvik.system.BlockGuard; +import dalvik.system.CloseGuard; import java.io.PrintWriter; import java.io.StringWriter; @@ -70,6 +71,7 @@ import java.util.HashMap; * .build()); * StrictMode.setVmPolicy(new {@link VmPolicy.Builder StrictMode.VmPolicy.Builder}() * .detectLeakedSqlLiteObjects() + * .detectLeakedClosableObjects() * .penaltyLog() * .penaltyDeath() * .build()); @@ -140,6 +142,12 @@ public final class StrictMode { public static final int DETECT_VM_CURSOR_LEAKS = 0x200; // for ProcessPolicy /** + * Note, a "VM_" bit, not thread. + * @hide + */ + public static final int DETECT_VM_CLOSABLE_LEAKS = 0x400; // for ProcessPolicy + + /** * @hide */ public static final int PENALTY_LOG = 0x10; // normal android.util.Log @@ -450,12 +458,12 @@ public final class StrictMode { /** * Detect everything that's potentially suspect. * - * <p>As of the Gingerbread release this only includes - * SQLite cursor leaks but will likely expand in future - * releases. + * <p>In the Honeycomb release this includes leaks of + * SQLite cursors and other closable objects but will + * likely expand in future releases. */ public Builder detectAll() { - return enable(DETECT_VM_CURSOR_LEAKS); + return enable(DETECT_VM_CURSOR_LEAKS | DETECT_VM_CLOSABLE_LEAKS); } /** @@ -472,6 +480,18 @@ public final class StrictMode { } /** + * Detect when an {@link java.io.Closeable} or other + * object with a explict termination method is finalized + * without having been closed. + * + * <p>You always want to explicitly close such objects to + * avoid unnecessary resources leaks. + */ + public Builder detectLeakedClosableObjects() { + return enable(DETECT_VM_CLOSABLE_LEAKS); + } + + /** * Crashes the whole process on violation. This penalty runs at * the end of all enabled penalties so yo you'll still get * your logging or other violations before the process dies. @@ -671,6 +691,7 @@ public final class StrictMode { StrictMode.DETECT_NETWORK | StrictMode.PENALTY_DROPBOX); sVmPolicyMask = StrictMode.DETECT_VM_CURSOR_LEAKS | + StrictMode.DETECT_VM_CLOSABLE_LEAKS | StrictMode.PENALTY_DROPBOX | StrictMode.PENALTY_LOG; return true; @@ -1030,6 +1051,7 @@ public final class StrictMode { */ public static void setVmPolicy(final VmPolicy policy) { sVmPolicyMask = policy.mask; + CloseGuard.setEnabled(vmClosableObjectLeaksEnabled()); } /** @@ -1043,8 +1065,9 @@ public final class StrictMode { * Enable the recommended StrictMode defaults, with violations just being logged. * * <p>This catches disk and network access on the main thread, as - * well as leaked SQLite cursors. This is simply a wrapper around - * {@link #setVmPolicy} and {@link #setThreadPolicy}. + * well as leaked SQLite cursors and unclosed resources. This is + * simply a wrapper around {@link #setVmPolicy} and {@link + * #setThreadPolicy}. */ public static void enableDefaults() { StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() @@ -1053,6 +1076,7 @@ public final class StrictMode { .build()); StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() .detectLeakedSqlLiteObjects() + .detectLeakedClosableObjects() .penaltyLog() .build()); } @@ -1067,6 +1091,13 @@ public final class StrictMode { /** * @hide */ + public static boolean vmClosableObjectLeaksEnabled() { + return (sVmPolicyMask & DETECT_VM_CLOSABLE_LEAKS) != 0; + } + + /** + * @hide + */ public static void onSqliteObjectLeaked(String message, Throwable originStack) { if ((sVmPolicyMask & PENALTY_LOG) != 0) { Log.e(TAG, message, originStack); diff --git a/core/java/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java index 00c4dbebcd23..4ae55fc4e3ee 100644 --- a/core/java/com/android/internal/content/NativeLibraryHelper.java +++ b/core/java/com/android/internal/content/NativeLibraryHelper.java @@ -259,6 +259,7 @@ public class NativeLibraryHelper { File destFile = new File(sharedLibraryDir, entry.second); copyNativeBinaryLI(zipFile, entry.first, sharedLibraryDir, destFile); } + zipFile.close(); } catch (ZipException e) { Slog.w(TAG, "Failed to extract data from package file", e); return PackageManager.INSTALL_FAILED_INVALID_APK; diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java index f9930932fe4e..dea900786874 100644 --- a/services/java/com/android/server/DockObserver.java +++ b/services/java/com/android/server/DockObserver.java @@ -102,6 +102,7 @@ class DockObserver extends UEventObserver { try { FileReader file = new FileReader(DOCK_STATE_PATH); int len = file.read(buffer, 0, 1024); + file.close(); mPreviousDockState = mDockState = Integer.valueOf((new String(buffer, 0, len)).trim()); } catch (FileNotFoundException e) { Slog.w(TAG, "This kernel does not have dock station support"); diff --git a/services/java/com/android/server/InputManager.java b/services/java/com/android/server/InputManager.java index e7eb1293d0e0..13be984590d4 100644 --- a/services/java/com/android/server/InputManager.java +++ b/services/java/com/android/server/InputManager.java @@ -493,7 +493,9 @@ public class InputManager { CALIBRATION_DIR_PATH + deviceName + ".idc"); if (calibrationFile.exists()) { try { - properties.load(new FileInputStream(calibrationFile)); + FileInputStream fis = new FileInputStream(calibrationFile); + properties.load(fis); + fis.close(); } catch (IOException ex) { Slog.w(TAG, "Error reading input device calibration properties for device " + deviceName + " from " + calibrationFile + ".", ex); diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java index 7c758a25c593..7ad95da94b60 100644 --- a/services/java/com/android/server/PackageManagerService.java +++ b/services/java/com/android/server/PackageManagerService.java @@ -1225,6 +1225,7 @@ class PackageManagerService extends IPackageManager.Stub { } } + permReader.close(); } catch (XmlPullParserException e) { Slog.w(TAG, "Got execption parsing permissions.", e); } catch (IOException e) { diff --git a/services/java/com/android/server/UsbObserver.java b/services/java/com/android/server/UsbObserver.java index 546e5f8d0242..cfa83be586d7 100644 --- a/services/java/com/android/server/UsbObserver.java +++ b/services/java/com/android/server/UsbObserver.java @@ -119,6 +119,7 @@ class UsbObserver extends UEventObserver { try { FileReader file = new FileReader(USB_CONFIGURATION_PATH); int len = file.read(buffer, 0, 1024); + file.close(); mPreviousUsbConfig = mUsbConfig = Integer.valueOf((new String(buffer, 0, len)).trim()); } catch (FileNotFoundException e) { @@ -133,6 +134,7 @@ class UsbObserver extends UEventObserver { File file = new File(files[i], "enable"); FileReader reader = new FileReader(file); int len = reader.read(buffer, 0, 1024); + reader.close(); int value = Integer.valueOf((new String(buffer, 0, len)).trim()); String functionName = files[i].getName(); if (value == 1) { |