Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 426cbefd authored by Netta P's avatar Netta P
Browse files

Protobufferize PackageManager dumpsys

Bug: 34230809
Test: cts-tradefed run cts-dev -m CtsIncidentHostTestCase -t com.android.server.cts.PackageIncidentTest
Change-Id: I6dc455db47a8a636267cf7abe993e135e9044b33
parent 189796da
Loading
Loading
Loading
Loading
+120 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.
 */

syntax = "proto3";

package android.service.pm;

option java_multiple_files = true;
option java_outer_classname = "PackageServiceProto";

message PackageServiceDumpProto {
    message PackageShortProto {
        // Name of package. e.g. "com.android.providers.telephony".
        string name = 1;
        // UID for this package as assigned by Android OS.
        int32 uid = 2;
    }
    message SharedLibraryProto {
        string name = 1;
        // True if library path is not null (jar), false otherwise (apk)
        bool is_jar = 2;
        // Should be filled if is_jar is true
        string path = 3;
        // Should be filled if is_jar is false
        string apk = 4;
    }
    message FeatureProto {
        string name = 1;
        int32 version = 2;
    }
    message SharedUserProto {
        int32 user_id = 1;
        string name = 2;
    }

    // Installed packages.
    PackageShortProto required_verifier_package = 1;
    PackageShortProto verifier_package = 2;
    repeated SharedLibraryProto shared_libraries = 3;
    repeated FeatureProto features = 4;
    repeated PackageProto packages = 5;
    repeated SharedUserProto shared_users = 6;
    // Messages from the settings problem file
    repeated string messages = 7;
}

message PackageProto {
    message SplitProto {
        string name = 1;
        int32 revision_code = 2;
    }
    message UserInfoProto {
        enum InstallType {
            NOT_INSTALLED_FOR_USER = 0;
            FULL_APP_INSTALL = 1;
            INSTANT_APP_INSTALL = 2;
        }
        // Enum values gotten from PackageManger.java
        enum EnabledState {
            // This component or application is in its default enabled state
            // (as specified in its manifest).
            COMPONENT_ENABLED_STATE_DEFAULT = 0;
            // This component or application has been explictily enabled, regardless
            // of what it has specified in its manifest.
            COMPONENT_ENABLED_STATE_ENABLED = 1;
            // This component or application has been explicitly disabled, regardless of
            // what it has specified in its manifest.
            COMPONENT_ENABLED_STATE_DISABLED = 2;
            // The user has explicitly disabled the application, regardless of what it has
            // specified in its manifest.
            COMPONENT_ENABLED_STATE_DISABLED_USER = 3;
            // This application should be considered, until the point where the user actually
            // wants to use it.
            COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED = 4;
        }

        int32 id = 1;
        InstallType install_type = 2;
        // Is the app restricted by owner / admin
        bool is_hidden = 3;
        bool is_suspended = 4;
        bool is_stopped = 5;
        bool is_launched = 6;
        EnabledState enabled_state = 7;
        string last_disabled_app_caller = 8;
    }

    // Name of package. e.g. "com.android.providers.telephony".
    string name = 1;
    // UID for this package as assigned by Android OS.
    int32 uid = 2;
    // Package's reported version.
    int32 version_code = 3;
    // Package's reported version string (what's displayed to the user).
    string version_string = 4;
    // UTC timestamp of install
    int64 install_time_ms = 5;
    // Millisecond UTC timestamp of latest update adjusted to Google's server clock.
    int64 update_time_ms = 6;
    // From "dumpsys package" - name of package which installed this one.
    // Typically "" if system app or "com.android.vending" if Play Store.
    string installer_name = 7;
    // Split APKs.
    repeated SplitProto splits = 8;
    // Per-user package info.
    repeated UserInfoProto users = 9;
}
+100 −3
Original line number Diff line number Diff line
@@ -128,7 +128,6 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.AppsQueryHelper;
import android.content.pm.ChangedPackages;
import android.content.pm.ComponentInfo;
import android.content.pm.InstantAppInfo;
import android.content.pm.EphemeralRequest;
import android.content.pm.EphemeralResolveInfo;
import android.content.pm.EphemeralResponse;
@@ -143,6 +142,7 @@ import android.content.pm.IPackageInstaller;
import android.content.pm.IPackageManager;
import android.content.pm.IPackageMoveObserver;
import android.content.pm.IPackageStatsObserver;
import android.content.pm.InstantAppInfo;
import android.content.pm.InstrumentationInfo;
import android.content.pm.IntentFilterVerificationInfo;
import android.content.pm.KeySet;
@@ -204,15 +204,16 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManagerInternal;
import android.os.storage.IStorageManager;
import android.os.storage.StorageManagerInternal;
import android.os.storage.StorageEventListener;
import android.os.storage.StorageManager;
import android.os.storage.StorageManagerInternal;
import android.os.storage.VolumeInfo;
import android.os.storage.VolumeRecord;
import android.provider.Settings.Global;
import android.provider.Settings.Secure;
import android.security.KeyStore;
import android.security.SystemKeyStore;
import android.service.pm.PackageServiceDumpProto;
import android.system.ErrnoException;
import android.system.Os;
import android.text.TextUtils;
@@ -235,6 +236,7 @@ import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import android.util.Xml;
import android.util.jar.StrictJarFile;
import android.util.proto.ProtoOutputStream;
import android.view.Display;
import com.android.internal.R;
@@ -316,8 +318,8 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -20284,6 +20286,9 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
                checkin = true;
            } else if ("-f".equals(opt)) {
                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
            } else if ("--proto".equals(opt)) {
                dumpProto(fd);
                return;
            } else {
                pw.println("Unknown argument: " + opt + "; use -h for help");
            }
@@ -20814,6 +20819,98 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
        }
    }
    private void dumpProto(FileDescriptor fd) {
        final ProtoOutputStream proto = new ProtoOutputStream(fd);
        synchronized (mPackages) {
            final long requiredVerifierPackageToken =
                    proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
            proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
            proto.write(
                    PackageServiceDumpProto.PackageShortProto.UID,
                    getPackageUid(
                            mRequiredVerifierPackage,
                            MATCH_DEBUG_TRIAGED_MISSING,
                            UserHandle.USER_SYSTEM));
            proto.end(requiredVerifierPackageToken);
            if (mIntentFilterVerifierComponent != null) {
                String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
                final long verifierPackageToken =
                        proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
                proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
                proto.write(
                        PackageServiceDumpProto.PackageShortProto.UID,
                        getPackageUid(
                                verifierPackageName,
                                MATCH_DEBUG_TRIAGED_MISSING,
                                UserHandle.USER_SYSTEM));
                proto.end(verifierPackageToken);
            }
            dumpSharedLibrariesProto(proto);
            dumpFeaturesProto(proto);
            mSettings.dumpPackagesProto(proto);
            mSettings.dumpSharedUsersProto(proto);
            dumpMessagesProto(proto);
        }
        proto.flush();
    }
    private void dumpMessagesProto(ProtoOutputStream proto) {
        BufferedReader in = null;
        String line = null;
        try {
            in = new BufferedReader(new FileReader(getSettingsProblemFile()));
            while ((line = in.readLine()) != null) {
                if (line.contains("ignored: updated version")) continue;
                proto.write(PackageServiceDumpProto.MESSAGES, line);
            }
        } catch (IOException ignored) {
        } finally {
            IoUtils.closeQuietly(in);
        }
    }
    private void dumpFeaturesProto(ProtoOutputStream proto) {
        synchronized (mAvailableFeatures) {
            final int count = mAvailableFeatures.size();
            for (int i = 0; i < count; i++) {
                final FeatureInfo feat = mAvailableFeatures.valueAt(i);
                final long featureToken = proto.start(PackageServiceDumpProto.FEATURES);
                proto.write(PackageServiceDumpProto.FeatureProto.NAME, feat.name);
                proto.write(PackageServiceDumpProto.FeatureProto.VERSION, feat.version);
                proto.end(featureToken);
            }
        }
    }
    private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
        final int count = mSharedLibraries.size();
        for (int i = 0; i < count; i++) {
            final String libName = mSharedLibraries.keyAt(i);
            SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
            if (versionedLib == null) {
                continue;
            }
            final int versionCount = versionedLib.size();
            for (int j = 0; j < versionCount; j++) {
                final SharedLibraryEntry libEntry = versionedLib.valueAt(j);
                final long sharedLibraryToken =
                        proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
                proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName());
                final boolean isJar = (libEntry.path != null);
                proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
                if (isJar) {
                    proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path);
                } else {
                    proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk);
                }
                proto.end(sharedLibraryToken);
            }
        }
    }
    private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
        ipw.println();
+31 −0
Original line number Diff line number Diff line
@@ -19,6 +19,9 @@ 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;
@@ -128,4 +131,32 @@ final class PackageSetting extends PackageSettingBase {
        }
        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);
    }
}
+30 −0
Original line number Diff line number Diff line
@@ -25,8 +25,10 @@ import android.content.pm.IntentFilterVerificationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageUserState;
import android.os.storage.VolumeInfo;
import android.service.pm.PackageProto;
import android.util.ArraySet;
import android.util.SparseArray;
import android.util.proto.ProtoOutputStream;

import com.android.internal.annotations.VisibleForTesting;

@@ -564,4 +566,32 @@ abstract class PackageSettingBase extends SettingBase {
        modifyUserState(userId).domainVerificationStatus =
                PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
    }

    protected void writeUsersInfoToProto(ProtoOutputStream proto, long fieldId) {
        int count = userState.size();
        for (int i = 0; i < count; i++) {
            final long userToken = proto.start(fieldId);
            final int userId = userState.keyAt(i);
            final PackageUserState state = userState.valueAt(i);
            proto.write(PackageProto.UserInfoProto.ID, userId);
            final int installType;
            if (state.instantApp) {
                installType = PackageProto.UserInfoProto.INSTANT_APP_INSTALL;
            } else if (state.installed) {
                installType = PackageProto.UserInfoProto.FULL_APP_INSTALL;
            } else {
                installType = PackageProto.UserInfoProto.NOT_INSTALLED_FOR_USER;
            }
            proto.write(PackageProto.UserInfoProto.INSTALL_TYPE, installType);
            proto.write(PackageProto.UserInfoProto.IS_HIDDEN, state.hidden);
            proto.write(PackageProto.UserInfoProto.IS_SUSPENDED, state.suspended);
            proto.write(PackageProto.UserInfoProto.IS_STOPPED, state.stopped);
            proto.write(PackageProto.UserInfoProto.IS_LAUNCHED, !state.notLaunched);
            proto.write(PackageProto.UserInfoProto.ENABLED_STATE, state.enabled);
            proto.write(
                    PackageProto.UserInfoProto.LAST_DISABLED_APP_CALLER,
                    state.lastDisableAppCaller);
            proto.end(userToken);
        }
    }
}
+23 −0
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
import android.service.pm.PackageServiceDumpProto;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -77,6 +78,7 @@ import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import android.util.SparseLongArray;
import android.util.Xml;
import android.util.proto.ProtoOutputStream;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.BackgroundThread;
@@ -4876,6 +4878,16 @@ final class Settings {
        }
    }

    void dumpPackagesProto(ProtoOutputStream proto) {
        List<UserInfo> users = getAllUsers(UserManagerService.getInstance());

        final int count = mPackages.size();
        for (int i = 0; i < count; i++) {
            final PackageSetting ps = mPackages.valueAt(i);
            ps.writeToProto(proto, PackageServiceDumpProto.PACKAGES, users);
        }
    }

    void dumpPermissionsLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
            DumpState dumpState) {
        boolean printedSomething = false;
@@ -4966,6 +4978,17 @@ final class Settings {
        }
    }

    void dumpSharedUsersProto(ProtoOutputStream proto) {
        final int count = mSharedUsers.size();
        for (int i = 0; i < count; i++) {
            final SharedUserSetting su = mSharedUsers.valueAt(i);
            final long sharedUserToken = proto.start(PackageServiceDumpProto.SHARED_USERS);
            proto.write(PackageServiceDumpProto.SharedUserProto.USER_ID, su.userId);
            proto.write(PackageServiceDumpProto.SharedUserProto.NAME, su.name);
            proto.end(sharedUserToken);
        }
    }

    void dumpReadMessagesLPr(PrintWriter pw, DumpState dumpState) {
        pw.println("Settings parse messages:");
        pw.print(mReadMessages.toString());