前言
應(yīng)用場景和用戶需求:
- ROM定制化開發(fā): 在定制ROM時,客戶可能需要限制某些應(yīng)用安裝,以確保系統(tǒng)的安全和穩(wěn)定。通過實現(xiàn)應(yīng)用安裝白名單功能,可以滿足這種需求。
- 企業(yè)設(shè)備管理: 在企業(yè)設(shè)備中,可能需要限制員工只能安裝指定的應(yīng)用,以防止惡意軟件和不當(dāng)使用。通過白名單功能,可以有效地控制應(yīng)用安裝。
核心組件
在Android 13中,實現(xiàn)應(yīng)用安裝白名單功能主要涉及以下幾個步驟和組件:
- PackageManagerService: 在PackageManagerService中添加白名單邏輯。PackageManagerService負(fù)責(zé)管理應(yīng)用安裝,通過修改其代碼可以實現(xiàn)白名單功能。具體來說,需要在PackageManagerService.java中添加判斷邏輯,檢查待安裝應(yīng)用是否在白名單中。
- IPackageManager接口: IPackageManager接口定義了服務(wù)端和客戶端的通信方式。通過修改這個接口,可以實現(xiàn)白名單的判斷邏輯,確保只有白名單中的應(yīng)用才能被安裝。
- PackageInstallerApplication: 在PackageInstallerApplication中添加白名單邏輯。這個應(yīng)用負(fù)責(zé)處理應(yīng)用的安裝請求,通過修改其代碼可以實現(xiàn)對安裝請求的白名單檢查。
代碼實例
diff --git a/frameworks/base/services/core/java/com/android/server/pm/InstallPackageHelper.java b/frameworks/base/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 90ccc4825ec..d589367a192 100755
--- a/frameworks/base/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/frameworks/base/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -198,6 +198,8 @@ import com.android.server.pm.PackageManagerService;
import com.android.server.pm.pkg.component.ParsedUsesPermission;
import com.android.server.pm.pkg.component.ParsedUsesPermissionImpl;
// @}
+import android.text.TextUtils;
+import android.widget.Toast;
final class InstallPackageHelper {
private final PackageManagerService mPm;
@@ -1783,9 +1785,20 @@ final class InstallPackageHelper {
// we're passing the freezer back to be closed in a later phase of install
shouldCloseFreezerBeforeReturn = false;
- return new PrepareResult(replace, targetScanFlags, targetParseFlags,
- oldPackage, parsedPackage, replace /* clearCodeCache */, sysPkg,
- ps, disabledPs);
+ // Create by yeruilai 2024-10-01 19:38:46 Restricted application installation
+ // return new PrepareResult(replace, targetScanFlags, targetParseFlags,
+ // oldPackage, parsedPackage, replace /* clearCodeCache */, sysPkg,
+ // ps, disabledPs);
+ if (filterAppWhiteList(parsedPackage, sysPkg)) {
+ return new PrepareResult(replace, targetScanFlags, targetParseFlags,
+ oldPackage, parsedPackage, replace /* clearCodeCache */, sysPkg,
+ ps, disabledPs);
+ } else {
+ Toast.makeText(mPm.mContext, "安裝包非白名單應(yīng)用,無法安裝", Toast.LENGTH_LONG).show();
+ throw new PrepareFailure(INSTALL_FAILED_INVALID_APK,
+ "The application installation whitelist is being controlled, " +
+ "Package: " + parsedPackage.getPackageName() + " is not in the whitelist.");
+ }
} finally {
res.mFreezer = freezer;
if (shouldCloseFreezerBeforeReturn) {
@@ -4531,4 +4544,212 @@ final class InstallPackageHelper {
return scanFlags;
}
+
+ // Create by yeruilai 2024-10-01 19:38:46 Restricted application installation
+ private static final String TAG_WHITE_LIST = "install_white";
+ private static final boolean DEBUG_WHITE = true;
+ private static final String[] WHITE_LIST_SPLIT = new String[] {
+ "com.longzhiye.demo1",
+ "com.longzhiye.demo2",
+ "com.longzhiye.demo3",
+ };
+
+ /**
+ * Create by yeruilai 2024-10-01 19:38:46 Restricted application installation
+ */
+ private boolean filterAppWhiteList(ParsedPackage parsedPackage, boolean isSysPkg) {
+ String parsedName = parsedPackage.getPackageName();
+ List<String> whiteList = Arrays.asList(WHITE_LIST_SPLIT);
+ if (whiteList == null || whiteList.size() == 0) {
+ if (DEBUG_WHITE) android.util.Log.d(TAG_WHITE_LIST, "whiteListLabel [ whiteList ] = NULL or Empty, [ DISALLOW ]");
+ return false;
+ }
+ for (String pkg : whiteList) {
+ if (DEBUG_WHITE) android.util.Log.d(TAG_WHITE_LIST, "[ whiteList ] >>> Package : " + pkg);
+ if (TextUtils.equals(parsedName, pkg)) {
+ if (DEBUG_WHITE) android.util.Log.d(TAG_WHITE_LIST, "[ ALLOW ] *** " + parsedName);
+ return true;
+ }
+ }
+ if (DEBUG_WHITE) android.util.Log.d(TAG_WHITE_LIST, "[ DISALLOW ]");
+ return false;
+ }
+
}