summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/provider/Settings.java14
-rw-r--r--core/java/com/android/internal/content/F2fsUtils.java296
-rw-r--r--core/java/com/android/internal/content/OWNERS5
-rw-r--r--core/jni/Android.bp1
-rw-r--r--core/jni/AndroidRuntime.cpp2
-rw-r--r--core/jni/com_android_internal_content_F2fsUtils.cpp84
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java44
7 files changed, 2 insertions, 444 deletions
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 3116b2612c67..5cfb665745a8 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6624,20 +6624,6 @@ public final class Settings {
public static final String COMPLETED_CATEGORY_PREFIX = "suggested.completed_category.";
/**
- * Whether or not compress blocks should be released on install.
- * <p>The setting only determines if the platform will attempt to release
- * compress blocks; it does not guarantee that the files will have their
- * compress blocks released. Compression is currently only supported on
- * some f2fs filesystems.
- * <p>
- * Type: int (0 for false, 1 for true)
- *
- * @hide
- */
- public static final String RELEASE_COMPRESS_BLOCKS_ON_INSTALL =
- "release_compress_blocks_on_install";
-
- /**
* List of input methods that are currently enabled. This is a string
* containing the IDs of all enabled input methods, each ID separated
* by ':'.
diff --git a/core/java/com/android/internal/content/F2fsUtils.java b/core/java/com/android/internal/content/F2fsUtils.java
deleted file mode 100644
index 27f1b308ed9c..000000000000
--- a/core/java/com/android/internal/content/F2fsUtils.java
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.content;
-
-import android.annotation.NonNull;
-import android.content.ContentResolver;
-import android.os.Environment;
-import android.os.incremental.IncrementalManager;
-import android.provider.Settings.Secure;
-import android.text.TextUtils;
-import android.util.Slog;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Utility methods to work with the f2fs file system.
- */
-public final class F2fsUtils {
- private static final String TAG = "F2fsUtils";
- private static final boolean DEBUG_F2FS = false;
-
- /** Directory containing kernel features */
- private static final File sKernelFeatures =
- new File("/sys/fs/f2fs/features");
- /** File containing features enabled on "/data" */
- private static final File sUserDataFeatures =
- new File("/dev/sys/fs/by-name/userdata/features");
- private static final File sDataDirectory = Environment.getDataDirectory();
- /** Name of the compression feature */
- private static final String COMPRESSION_FEATURE = "compression";
-
- private static final boolean sKernelCompressionAvailable;
- private static final boolean sUserDataCompressionAvailable;
-
- static {
- sKernelCompressionAvailable = isCompressionEnabledInKernel();
- if (!sKernelCompressionAvailable) {
- if (DEBUG_F2FS) {
- Slog.d(TAG, "f2fs compression DISABLED; feature not part of the kernel");
- }
- }
- sUserDataCompressionAvailable = isCompressionEnabledOnUserData();
- if (!sUserDataCompressionAvailable) {
- if (DEBUG_F2FS) {
- Slog.d(TAG, "f2fs compression DISABLED; feature not enabled on filesystem");
- }
- }
- }
-
- /**
- * Releases compressed blocks from eligible installation artifacts.
- * <p>
- * Modern f2fs implementations starting in {@code S} support compression
- * natively within the file system. The data blocks of specific installation
- * artifacts [eg. .apk, .so, ...] can be compressed at the file system level,
- * making them look and act like any other uncompressed file, but consuming
- * a fraction of the space.
- * <p>
- * However, the unused space is not free'd automatically. Instead, we must
- * manually tell the file system to release the extra blocks [the delta between
- * the compressed and uncompressed block counts] back to the free pool.
- * <p>
- * Because of how compression works within the file system, once the blocks
- * have been released, the file becomes read-only and cannot be modified until
- * the free'd blocks have again been reserved from the free pool.
- */
- public static void releaseCompressedBlocks(ContentResolver resolver, File file) {
- if (!sKernelCompressionAvailable || !sUserDataCompressionAvailable) {
- return;
- }
-
- // NOTE: Retrieving this setting means we need to delay releasing cblocks
- // of any APKs installed during the PackageManagerService constructor. Instead
- // of being able to release them in the constructor, they can only be released
- // immediately prior to the system being available. When we no longer need to
- // read this setting, move cblock release back to the package manager constructor.
- final boolean releaseCompressBlocks =
- Secure.getInt(resolver, Secure.RELEASE_COMPRESS_BLOCKS_ON_INSTALL, 1) != 0;
- if (!releaseCompressBlocks) {
- if (DEBUG_F2FS) {
- Slog.d(TAG, "SKIP; release compress blocks not enabled");
- }
- return;
- }
- if (!isCompressionAllowed(file)) {
- if (DEBUG_F2FS) {
- Slog.d(TAG, "SKIP; compression not allowed");
- }
- return;
- }
- final File[] files = getFilesToRelease(file);
- if (files == null || files.length == 0) {
- if (DEBUG_F2FS) {
- Slog.d(TAG, "SKIP; no files to compress");
- }
- return;
- }
- for (int i = files.length - 1; i >= 0; --i) {
- final long releasedBlocks = nativeReleaseCompressedBlocks(files[i].getAbsolutePath());
- if (DEBUG_F2FS) {
- Slog.d(TAG, "RELEASED " + releasedBlocks + " blocks"
- + " from \"" + files[i] + "\"");
- }
- }
- }
-
- /**
- * Returns {@code true} if compression is allowed on the file system containing
- * the given file.
- * <p>
- * NOTE: The return value does not mean if the given file, or any other file
- * on the same file system, is actually compressed. It merely determines whether
- * not files <em>may</em> be compressed.
- */
- private static boolean isCompressionAllowed(@NonNull File file) {
- final String filePath;
- try {
- filePath = file.getCanonicalPath();
- } catch (IOException e) {
- if (DEBUG_F2FS) {
- Slog.d(TAG, "f2fs compression DISABLED; could not determine path");
- }
- return false;
- }
- if (IncrementalManager.isIncrementalPath(filePath)) {
- if (DEBUG_F2FS) {
- Slog.d(TAG, "f2fs compression DISABLED; file on incremental fs");
- }
- return false;
- }
- if (!isChild(sDataDirectory, filePath)) {
- if (DEBUG_F2FS) {
- Slog.d(TAG, "f2fs compression DISABLED; file not on /data");
- }
- return false;
- }
- if (DEBUG_F2FS) {
- Slog.d(TAG, "f2fs compression ENABLED");
- }
- return true;
- }
-
- /**
- * Returns {@code true} if the given child is a descendant of the base.
- */
- private static boolean isChild(@NonNull File base, @NonNull String childPath) {
- try {
- base = base.getCanonicalFile();
-
- File parentFile = new File(childPath).getCanonicalFile();
- while (parentFile != null) {
- if (base.equals(parentFile)) {
- return true;
- }
- parentFile = parentFile.getParentFile();
- }
- return false;
- } catch (IOException ignore) {
- return false;
- }
- }
-
- /**
- * Returns whether or not the compression feature is enabled in the kernel.
- * <p>
- * NOTE: This doesn't mean compression is enabled on a particular file system
- * or any files have been compressed. Only that the functionality is enabled
- * on the device.
- */
- private static boolean isCompressionEnabledInKernel() {
- final File[] features = sKernelFeatures.listFiles();
- if (features == null || features.length == 0) {
- if (DEBUG_F2FS) {
- Slog.d(TAG, "ERROR; no kernel features");
- }
- return false;
- }
- for (int i = features.length - 1; i >= 0; --i) {
- final File feature = features[i];
- if (COMPRESSION_FEATURE.equals(features[i].getName())) {
- if (DEBUG_F2FS) {
- Slog.d(TAG, "FOUND kernel compression feature");
- }
- return true;
- }
- }
- if (DEBUG_F2FS) {
- Slog.d(TAG, "ERROR; kernel compression feature not found");
- }
- return false;
- }
-
- /**
- * Returns whether or not the compression feature is enabled on user data [ie. "/data"].
- * <p>
- * NOTE: This doesn't mean any files have been compressed. Only that the functionality
- * is enabled on the file system.
- */
- private static boolean isCompressionEnabledOnUserData() {
- if (!sUserDataFeatures.exists()
- || !sUserDataFeatures.isFile()
- || !sUserDataFeatures.canRead()) {
- if (DEBUG_F2FS) {
- Slog.d(TAG, "ERROR; filesystem features not available");
- }
- return false;
- }
- final List<String> configLines;
- try {
- configLines = Files.readAllLines(sUserDataFeatures.toPath());
- } catch (IOException ignore) {
- if (DEBUG_F2FS) {
- Slog.d(TAG, "ERROR; couldn't read filesystem features");
- }
- return false;
- }
- if (configLines == null
- || configLines.size() > 1
- || TextUtils.isEmpty(configLines.get(0))) {
- if (DEBUG_F2FS) {
- Slog.d(TAG, "ERROR; no filesystem features");
- }
- return false;
- }
- final String[] features = configLines.get(0).split(",");
- for (int i = features.length - 1; i >= 0; --i) {
- if (COMPRESSION_FEATURE.equals(features[i].trim())) {
- if (DEBUG_F2FS) {
- Slog.d(TAG, "FOUND filesystem compression feature");
- }
- return true;
- }
- }
- if (DEBUG_F2FS) {
- Slog.d(TAG, "ERROR; filesystem compression feature not found");
- }
- return false;
- }
-
- /**
- * Returns all files contained within the directory at any depth from the given path.
- */
- private static List<File> getFilesRecursive(@NonNull File path) {
- final File[] allFiles = path.listFiles();
- if (allFiles == null) {
- return null;
- }
- final ArrayList<File> files = new ArrayList<>();
- for (File f : allFiles) {
- if (f.isDirectory()) {
- files.addAll(getFilesRecursive(f));
- } else if (f.isFile()) {
- files.add(f);
- }
- }
- return files;
- }
-
- /**
- * Returns all files contained within the directory at any depth from the given path.
- */
- private static File[] getFilesToRelease(@NonNull File codePath) {
- final List<File> files = getFilesRecursive(codePath);
- if (files == null) {
- if (codePath.isFile()) {
- return new File[] { codePath };
- }
- return null;
- }
- if (files.size() == 0) {
- return null;
- }
- return files.toArray(new File[files.size()]);
- }
-
- private static native long nativeReleaseCompressedBlocks(String path);
-
-}
diff --git a/core/java/com/android/internal/content/OWNERS b/core/java/com/android/internal/content/OWNERS
deleted file mode 100644
index c42bee69410d..000000000000
--- a/core/java/com/android/internal/content/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-# Bug component: 36137
-include /core/java/android/content/pm/OWNERS
-
-per-file ReferrerIntent.aidl = file:/services/core/java/com/android/server/am/OWNERS
-per-file ReferrerIntent.java = file:/services/core/java/com/android/server/am/OWNERS
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 4502a33fbb63..146863342f47 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -84,7 +84,6 @@ cc_library_shared {
android: {
srcs: [
"AndroidRuntime.cpp",
- "com_android_internal_content_F2fsUtils.cpp",
"com_android_internal_content_NativeLibraryHelper.cpp",
"com_google_android_gles_jni_EGLImpl.cpp",
"com_google_android_gles_jni_GLImpl.cpp", // TODO: .arm
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index dca5d969257b..7e8fc7e6ba4f 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -190,7 +190,6 @@ extern int register_android_content_res_ObbScanner(JNIEnv* env);
extern int register_android_content_res_Configuration(JNIEnv* env);
extern int register_android_animation_PropertyValuesHolder(JNIEnv *env);
extern int register_android_security_Scrypt(JNIEnv *env);
-extern int register_com_android_internal_content_F2fsUtils(JNIEnv* env);
extern int register_com_android_internal_content_NativeLibraryHelper(JNIEnv *env);
extern int register_com_android_internal_content_om_OverlayConfig(JNIEnv *env);
extern int register_com_android_internal_net_NetworkUtilsInternal(JNIEnv* env);
@@ -1622,7 +1621,6 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_animation_PropertyValuesHolder),
REG_JNI(register_android_security_Scrypt),
- REG_JNI(register_com_android_internal_content_F2fsUtils),
REG_JNI(register_com_android_internal_content_NativeLibraryHelper),
REG_JNI(register_com_android_internal_os_DmabufInfoReader),
REG_JNI(register_com_android_internal_os_FuseAppLoop),
diff --git a/core/jni/com_android_internal_content_F2fsUtils.cpp b/core/jni/com_android_internal_content_F2fsUtils.cpp
deleted file mode 100644
index 8b9d59c416a0..000000000000
--- a/core/jni/com_android_internal_content_F2fsUtils.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "F2fsUtils"
-
-#include "core_jni_helpers.h"
-
-#include <nativehelper/ScopedUtfChars.h>
-#include <nativehelper/jni_macros.h>
-
-#include <sys/ioctl.h>
-#include <sys/types.h>
-
-#include <linux/f2fs.h>
-#include <linux/fs.h>
-
-#include <android-base/unique_fd.h>
-
-#include <utils/Log.h>
-
-#include <errno.h>
-#include <fcntl.h>
-
-#include <array>
-
-using namespace std::literals;
-
-namespace android {
-
-static jlong com_android_internal_content_F2fsUtils_nativeReleaseCompressedBlocks(JNIEnv *env,
- jclass clazz,
- jstring path) {
- unsigned long long blkcnt;
- int ret;
- ScopedUtfChars filePath(env, path);
-
- android::base::unique_fd fd(open(filePath.c_str(), O_RDONLY | O_CLOEXEC, 0));
- if (fd < 0) {
- ALOGW("Failed to open file: %s (%d)\n", filePath.c_str(), errno);
- return 0;
- }
-
- long flags = 0;
- ret = ioctl(fd, FS_IOC_GETFLAGS, &flags);
- if (ret < 0) {
- ALOGW("Failed to get flags for file: %s (%d)\n", filePath.c_str(), errno);
- return 0;
- }
- if ((flags & FS_COMPR_FL) == 0) {
- return 0;
- }
-
- ret = ioctl(fd, F2FS_IOC_RELEASE_COMPRESS_BLOCKS, &blkcnt);
- if (ret < 0) {
- return -errno;
- }
- return blkcnt;
-}
-
-static const std::array gMethods = {
- MAKE_JNI_NATIVE_METHOD(
- "nativeReleaseCompressedBlocks", "(Ljava/lang/String;)J",
- com_android_internal_content_F2fsUtils_nativeReleaseCompressedBlocks),
-};
-
-int register_com_android_internal_content_F2fsUtils(JNIEnv *env) {
- return RegisterMethodsOrDie(env, "com/android/internal/content/F2fsUtils", gMethods.data(),
- gMethods.size());
-}
-
-}; // namespace android
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 7b1b2e5a9e4c..14861c2ddf4c 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -341,7 +341,6 @@ import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.ResolverActivity;
-import com.android.internal.content.F2fsUtils;
import com.android.internal.content.NativeLibraryHelper;
import com.android.internal.content.PackageHelper;
import com.android.internal.content.om.OverlayConfig;
@@ -897,20 +896,6 @@ public class PackageManagerService extends IPackageManager.Stub
* Only non-null during an OTA, and even then it is nulled again once systemReady().
*/
private @Nullable ArraySet<String> mExistingPackages = null;
-
- /**
- * List of code paths that need to be released when the system becomes ready.
- * <p>
- * NOTE: We have to delay releasing cblocks for no other reason than we cannot
- * retrieve the setting {@link Secure#RELEASE_COMPRESS_BLOCKS_ON_INSTALL}. When
- * we no longer need to read that setting, cblock release can occur in the
- * constructor.
- *
- * @see Secure#RELEASE_COMPRESS_BLOCKS_ON_INSTALL
- * @see #systemReady()
- */
- private @Nullable List<File> mReleaseOnSystemReady;
-
/**
* Whether or not system app permissions should be promoted from install to runtime.
*/
@@ -7316,21 +7301,6 @@ public class PackageManagerService extends IPackageManager.Stub
IoUtils.closeQuietly(handle);
}
}
- if (ret == PackageManager.INSTALL_SUCCEEDED) {
- // NOTE: During boot, we have to delay releasing cblocks for no other reason than
- // we cannot retrieve the setting {@link Secure#RELEASE_COMPRESS_BLOCKS_ON_INSTALL}.
- // When we no longer need to read that setting, cblock release can occur always
- // occur here directly
- if (!mSystemReady) {
- if (mReleaseOnSystemReady == null) {
- mReleaseOnSystemReady = new ArrayList<>();
- }
- mReleaseOnSystemReady.add(dstCodePath);
- } else {
- final ContentResolver resolver = mContext.getContentResolver();
- F2fsUtils.releaseCompressedBlocks(resolver, dstCodePath);
- }
- }
if (ret != PackageManager.INSTALL_SUCCEEDED) {
if (!dstCodePath.exists()) {
return null;
@@ -17202,10 +17172,6 @@ public class PackageManagerService extends IPackageManager.Stub
if (mRet == PackageManager.INSTALL_SUCCEEDED) {
mRet = args.copyApk();
}
- if (mRet == PackageManager.INSTALL_SUCCEEDED) {
- F2fsUtils.releaseCompressedBlocks(
- mContext.getContentResolver(), new File(args.getCodePath()));
- }
if (mParentInstallParams != null) {
mParentInstallParams.tryProcessInstallRequest(args, mRet);
} else {
@@ -17213,6 +17179,7 @@ public class PackageManagerService extends IPackageManager.Stub
processInstallRequestsAsync(
res.returnCode == PackageManager.INSTALL_SUCCEEDED,
Collections.singletonList(new InstallRequest(args, res)));
+
}
}
}
@@ -23547,15 +23514,8 @@ public class PackageManagerService extends IPackageManager.Stub
public void systemReady() {
enforceSystemOrRoot("Only the system can claim the system is ready");
- final ContentResolver resolver = mContext.getContentResolver();
- if (mReleaseOnSystemReady != null) {
- for (int i = mReleaseOnSystemReady.size() - 1; i >= 0; --i) {
- final File dstCodePath = mReleaseOnSystemReady.get(i);
- F2fsUtils.releaseCompressedBlocks(resolver, dstCodePath);
- }
- mReleaseOnSystemReady = null;
- }
mSystemReady = true;
+ final ContentResolver resolver = mContext.getContentResolver();
ContentObserver co = new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange) {