| /* |
| * Copyright (C) 2011 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.server.pm; |
| |
| import android.content.pm.ApplicationInfo; |
| import android.content.pm.PackageManager; |
| import android.content.pm.PackageParser; |
| import android.content.pm.UserInfo; |
| import android.service.pm.PackageProto; |
| import android.util.proto.ProtoOutputStream; |
| |
| import java.io.File; |
| import java.util.List; |
| |
| /** |
| * Settings data for a particular package we know about. |
| */ |
| final class PackageSetting extends PackageSettingBase { |
| int appId; |
| PackageParser.Package pkg; |
| /** |
| * WARNING. The object reference is important. We perform integer equality and NOT |
| * object equality to check whether shared user settings are the same. |
| */ |
| SharedUserSetting sharedUser; |
| /** |
| * Temporary holding space for the shared user ID. While parsing package settings, the |
| * shared users tag may come after the packages. In this case, we must delay linking the |
| * shared user setting with the package setting. The shared user ID lets us link the |
| * two objects. |
| */ |
| private int sharedUserId; |
| |
| PackageSetting(String name, String realName, File codePath, File resourcePath, |
| String legacyNativeLibraryPathString, String primaryCpuAbiString, |
| String secondaryCpuAbiString, String cpuAbiOverrideString, |
| int pVersionCode, int pkgFlags, int privateFlags, String parentPackageName, |
| List<String> childPackageNames, int sharedUserId, String[] usesStaticLibraries, |
| int[] usesStaticLibrariesVersions) { |
| super(name, realName, codePath, resourcePath, legacyNativeLibraryPathString, |
| primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString, |
| pVersionCode, pkgFlags, privateFlags, parentPackageName, childPackageNames, |
| usesStaticLibraries, usesStaticLibrariesVersions); |
| this.sharedUserId = sharedUserId; |
| } |
| |
| /** |
| * New instance of PackageSetting replicating the original settings. |
| * Note that it keeps the same PackageParser.Package instance. |
| */ |
| PackageSetting(PackageSetting orig) { |
| super(orig, orig.realName); |
| doCopy(orig); |
| } |
| |
| /** |
| * New instance of PackageSetting replicating the original settings, but, allows specifying |
| * a real package name. |
| * Note that it keeps the same PackageParser.Package instance. |
| */ |
| PackageSetting(PackageSetting orig, String realPkgName) { |
| super(orig, realPkgName); |
| doCopy(orig); |
| } |
| |
| public int getSharedUserId() { |
| if (sharedUser != null) { |
| return sharedUser.userId; |
| } |
| return sharedUserId; |
| } |
| |
| @Override |
| public String toString() { |
| return "PackageSetting{" |
| + Integer.toHexString(System.identityHashCode(this)) |
| + " " + name + "/" + appId + "}"; |
| } |
| |
| public void copyFrom(PackageSetting orig) { |
| super.copyFrom(orig); |
| doCopy(orig); |
| } |
| |
| private void doCopy(PackageSetting orig) { |
| appId = orig.appId; |
| pkg = orig.pkg; |
| sharedUser = orig.sharedUser; |
| sharedUserId = orig.sharedUserId; |
| } |
| |
| public PermissionsState getPermissionsState() { |
| return (sharedUser != null) |
| ? sharedUser.getPermissionsState() |
| : super.getPermissionsState(); |
| } |
| |
| public boolean isPrivileged() { |
| return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; |
| } |
| |
| public boolean isOem() { |
| return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0; |
| } |
| |
| public boolean isForwardLocked() { |
| return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK) != 0; |
| } |
| |
| public boolean isSystem() { |
| return (pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0; |
| } |
| |
| public boolean isSharedUser() { |
| return sharedUser != null; |
| } |
| |
| public boolean isMatch(int flags) { |
| if ((flags & PackageManager.MATCH_SYSTEM_ONLY) != 0) { |
| return isSystem(); |
| } |
| return true; |
| } |
| |
| public void writeToProto(ProtoOutputStream proto, long fieldId, List<UserInfo> users) { |
| final long packageToken = proto.start(fieldId); |
| proto.write(PackageProto.NAME, (realName != null ? realName : name)); |
| proto.write(PackageProto.UID, appId); |
| proto.write(PackageProto.VERSION_CODE, versionCode); |
| proto.write(PackageProto.VERSION_STRING, pkg.mVersionName); |
| proto.write(PackageProto.INSTALL_TIME_MS, firstInstallTime); |
| proto.write(PackageProto.UPDATE_TIME_MS, lastUpdateTime); |
| proto.write(PackageProto.INSTALLER_NAME, installerPackageName); |
| |
| if (pkg != null) { |
| long splitToken = proto.start(PackageProto.SPLITS); |
| proto.write(PackageProto.SplitProto.NAME, "base"); |
| proto.write(PackageProto.SplitProto.REVISION_CODE, pkg.baseRevisionCode); |
| proto.end(splitToken); |
| if (pkg.splitNames != null) { |
| for (int i = 0; i < pkg.splitNames.length; i++) { |
| splitToken = proto.start(PackageProto.SPLITS); |
| proto.write(PackageProto.SplitProto.NAME, pkg.splitNames[i]); |
| proto.write(PackageProto.SplitProto.REVISION_CODE, pkg.splitRevisionCodes[i]); |
| proto.end(splitToken); |
| } |
| } |
| } |
| writeUsersInfoToProto(proto, PackageProto.USERS); |
| proto.end(packageToken); |
| } |
| } |