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

Commit cc6418fe authored by Sudheer Shanka's avatar Sudheer Shanka
Browse files

Move ApplicationThread to aidl.

Bug: 30977067
Test: Existing tests are passing, dump commands still working.
Change-Id: Iecb382e8720dfb1b6b707272497e3793e6995edb
parent e60cb323
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ LOCAL_SRC_FILES += \
	core/java/android/app/IAlarmListener.aidl \
	core/java/android/app/IAlarmManager.aidl \
	core/java/android/app/IAppTask.aidl \
	core/java/android/app/IApplicationThread.aidl \
	core/java/android/app/ITaskStackListener.aidl \
	core/java/android/app/IBackupAgent.aidl \
	core/java/android/app/IEphemeralResolver.aidl \
@@ -597,6 +598,7 @@ aidl_files := \
	frameworks/base/core/java/android/os/WorkSource.aidl \
	frameworks/base/core/java/android/os/DropBoxManager.aidl \
	frameworks/base/core/java/android/os/Bundle.aidl \
	frameworks/base/core/java/android/os/Debug.aidl \
	frameworks/base/core/java/android/accessibilityservice/AccessibilityServiceInfo.aidl \
	frameworks/base/core/java/android/net/Network.aidl \
	frameworks/base/core/java/android/net/RouteInfo.aidl \
+21 −21
Original line number Diff line number Diff line
@@ -150,7 +150,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
        {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
            String callingPackage = data.readString();
            Intent intent = Intent.CREATOR.createFromParcel(data);
            String resolvedType = data.readString();
@@ -173,7 +173,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
        {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
            String callingPackage = data.readString();
            Intent intent = Intent.CREATOR.createFromParcel(data);
            String resolvedType = data.readString();
@@ -197,7 +197,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
        {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
            String callingPackage = data.readString();
            Intent intent = Intent.CREATOR.createFromParcel(data);
            String resolvedType = data.readString();
@@ -223,7 +223,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
        {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
            String callingPackage = data.readString();
            Intent intent = Intent.CREATOR.createFromParcel(data);
            String resolvedType = data.readString();
@@ -247,7 +247,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
        {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
            String callingPackage = data.readString();
            Intent intent = Intent.CREATOR.createFromParcel(data);
            String resolvedType = data.readString();
@@ -270,7 +270,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
        {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
            IntentSender intent = IntentSender.CREATOR.createFromParcel(data);
            Intent fillInIntent = null;
            if (data.readInt() != 0) {
@@ -432,7 +432,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM

        case RELEASE_SOME_ACTIVITIES_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IApplicationThread app = ApplicationThreadNative.asInterface(data.readStrongBinder());
            IApplicationThread app = IApplicationThread.Stub.asInterface(data.readStrongBinder());
            releaseSomeActivities(app);
            reply.writeNoException();
            return true;
@@ -452,7 +452,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app =
                b != null ? ApplicationThreadNative.asInterface(b) : null;
                b != null ? IApplicationThread.Stub.asInterface(b) : null;
            String packageName = data.readString();
            b = data.readStrongBinder();
            IIntentReceiver rec
@@ -489,7 +489,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app =
                b != null ? ApplicationThreadNative.asInterface(b) : null;
                b != null ? IApplicationThread.Stub.asInterface(b) : null;
            Intent intent = Intent.CREATOR.createFromParcel(data);
            String resolvedType = data.readString();
            b = data.readStrongBinder();
@@ -516,7 +516,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
        {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = b != null ? ApplicationThreadNative.asInterface(b) : null;
            IApplicationThread app = b != null ? IApplicationThread.Stub.asInterface(b) : null;
            Intent intent = Intent.CREATOR.createFromParcel(data);
            int userId = data.readInt();
            unbroadcastIntent(app, intent, userId);
@@ -541,7 +541,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM

        case ATTACH_APPLICATION_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IApplicationThread app = ApplicationThreadNative.asInterface(
            IApplicationThread app = IApplicationThread.Stub.asInterface(
                    data.readStrongBinder());
            if (app != null) {
                attachApplication(app);
@@ -978,7 +978,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
        case GET_CONTENT_PROVIDER_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
            String name = data.readString();
            int userId = data.readInt();
            boolean stable = data.readInt() != 0;
@@ -1012,7 +1012,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
        case PUBLISH_CONTENT_PROVIDERS_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
            ArrayList<ContentProviderHolder> providers =
                data.createTypedArrayList(ContentProviderHolder.CREATOR);
            publishContentProviders(app, providers);
@@ -1077,7 +1077,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
        case START_SERVICE_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
            Intent service = Intent.CREATOR.createFromParcel(data);
            String resolvedType = data.readString();
            String callingPackage = data.readString();
@@ -1091,7 +1091,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
        case STOP_SERVICE_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
            Intent service = Intent.CREATOR.createFromParcel(data);
            String resolvedType = data.readString();
            int userId = data.readInt();
@@ -1130,7 +1130,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
        case BIND_SERVICE_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
            IBinder token = data.readStrongBinder();
            Intent service = Intent.CREATOR.createFromParcel(data);
            String resolvedType = data.readString();
@@ -1210,7 +1210,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
        case FINISH_INSTRUMENTATION_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
            int resultCode = data.readInt();
            Bundle results = data.readBundle();
            finishInstrumentation(app, resultCode, results);
@@ -1421,7 +1421,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
        case GRANT_URI_PERMISSION_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
            String targetPkg = data.readString();
            Uri uri = Uri.CREATOR.createFromParcel(data);
            int mode = data.readInt();
@@ -1434,7 +1434,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
        case REVOKE_URI_PERMISSION_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
            Uri uri = Uri.CREATOR.createFromParcel(data);
            int mode = data.readInt();
            int userId = data.readInt();
@@ -1497,7 +1497,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
        case SHOW_WAITING_FOR_DEBUGGER_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
            boolean waiting = data.readInt() != 0;
            showWaitingForDebugger(app, waiting);
            reply.writeNoException();
@@ -2061,7 +2061,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
        {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
            String callingPackage = data.readString();
            Intent[] intents = data.createTypedArray(Intent.CREATOR);
            String[] resolvedTypes = data.createStringArray();
+49 −34
Original line number Diff line number Diff line
@@ -647,7 +647,7 @@ public final class ActivityThread {

    private native void dumpGraphicsInfo(FileDescriptor fd);

    private class ApplicationThread extends ApplicationThreadNative {
    private class ApplicationThread extends IApplicationThread.Stub {
        private static final String DB_INFO_FORMAT = "  %8s %8s %14s %14s  %s";

        private int mLastProcessState = -1;
@@ -859,7 +859,7 @@ public final class ActivityThread {
                IUiAutomationConnection instrumentationUiConnection, int debugMode,
                boolean enableBinderTracking, boolean trackAllocation,
                boolean isRestrictedBackupMode, boolean persistent, Configuration config,
                CompatibilityInfo compatInfo, Map<String, IBinder> services, Bundle coreSettings,
                CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
                String buildSerial) {

            if (services != null) {
@@ -929,15 +929,17 @@ public final class ActivityThread {
            mH.sendMessage(mH.obtainMessage(H.GC_WHEN_IDLE));
        }

        public void dumpService(FileDescriptor fd, IBinder servicetoken, String[] args) {
        public void dumpService(ParcelFileDescriptor pfd, IBinder servicetoken, String[] args) {
            DumpComponentInfo data = new DumpComponentInfo();
            try {
                data.fd = ParcelFileDescriptor.dup(fd);
                data.fd = pfd.dup();
                data.token = servicetoken;
                data.args = args;
                sendMessage(H.DUMP_SERVICE, data, 0, 0, true /*async*/);
            } catch (IOException e) {
                Slog.w(TAG, "dumpService failed", e);
            } finally {
                IoUtils.closeQuietly(pfd);
            }
        }

@@ -996,43 +998,48 @@ public final class ActivityThread {
            sendMessage(H.SCHEDULE_CRASH, msg);
        }

        public void dumpActivity(FileDescriptor fd, IBinder activitytoken,
        public void dumpActivity(ParcelFileDescriptor pfd, IBinder activitytoken,
                String prefix, String[] args) {
            DumpComponentInfo data = new DumpComponentInfo();
            try {
                data.fd = ParcelFileDescriptor.dup(fd);
                data.fd = pfd.dup();
                data.token = activitytoken;
                data.prefix = prefix;
                data.args = args;
                sendMessage(H.DUMP_ACTIVITY, data, 0, 0, true /*async*/);
            } catch (IOException e) {
                Slog.w(TAG, "dumpActivity failed", e);
            } finally {
                IoUtils.closeQuietly(pfd);
            }
        }

        public void dumpProvider(FileDescriptor fd, IBinder providertoken,
        public void dumpProvider(ParcelFileDescriptor pfd, IBinder providertoken,
                String[] args) {
            DumpComponentInfo data = new DumpComponentInfo();
            try {
                data.fd = ParcelFileDescriptor.dup(fd);
                data.fd = pfd.dup();
                data.token = providertoken;
                data.args = args;
                sendMessage(H.DUMP_PROVIDER, data, 0, 0, true /*async*/);
            } catch (IOException e) {
                Slog.w(TAG, "dumpProvider failed", e);
            } finally {
                IoUtils.closeQuietly(pfd);
            }
        }

        @Override
        public void dumpMemInfo(FileDescriptor fd, Debug.MemoryInfo mem, boolean checkin,
        public void dumpMemInfo(ParcelFileDescriptor pfd, Debug.MemoryInfo mem, boolean checkin,
                boolean dumpFullInfo, boolean dumpDalvik, boolean dumpSummaryOnly,
                boolean dumpUnreachable, String[] args) {
            FileOutputStream fout = new FileOutputStream(fd);
            FileOutputStream fout = new FileOutputStream(pfd.getFileDescriptor());
            PrintWriter pw = new FastPrintWriter(fout);
            try {
                dumpMemInfo(pw, mem, checkin, dumpFullInfo, dumpDalvik, dumpSummaryOnly, dumpUnreachable);
            } finally {
                pw.flush();
                IoUtils.closeQuietly(pfd);
            }
        }

@@ -1175,44 +1182,49 @@ public final class ActivityThread {
        }

        @Override
        public void dumpGfxInfo(FileDescriptor fd, String[] args) {
            dumpGraphicsInfo(fd);
            WindowManagerGlobal.getInstance().dumpGfxInfo(fd, args);
        public void dumpGfxInfo(ParcelFileDescriptor pfd, String[] args) {
            dumpGraphicsInfo(pfd.getFileDescriptor());
            WindowManagerGlobal.getInstance().dumpGfxInfo(pfd.getFileDescriptor(), args);
            IoUtils.closeQuietly(pfd);
        }

        private void dumpDatabaseInfo(FileDescriptor fd, String[] args) {
            PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd));
        private void dumpDatabaseInfo(ParcelFileDescriptor pfd, String[] args) {
            PrintWriter pw = new FastPrintWriter(
                    new FileOutputStream(pfd.getFileDescriptor()));
            PrintWriterPrinter printer = new PrintWriterPrinter(pw);
            SQLiteDebug.dump(printer, args);
            pw.flush();
        }

        @Override
        public void dumpDbInfo(final FileDescriptor fd, final String[] args) {
        public void dumpDbInfo(final ParcelFileDescriptor pfd, final String[] args) {
            if (mSystemThread) {
                // Ensure this invocation is asynchronous to prevent writer waiting if buffer cannot
                // be consumed. But it must duplicate the file descriptor first, since caller might
                // be closing it.
                final ParcelFileDescriptor dup;
                try {
                    dup = ParcelFileDescriptor.dup(fd);
                    dup = pfd.dup();
                } catch (IOException e) {
                    Log.w(TAG, "Could not dup FD " + fd.getInt$());
                    Log.w(TAG, "Could not dup FD " + pfd.getFileDescriptor().getInt$());
                    return;
                } finally {
                    IoUtils.closeQuietly(pfd);
                }

                AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            dumpDatabaseInfo(dup.getFileDescriptor(), args);
                            dumpDatabaseInfo(dup, args);
                        } finally {
                            IoUtils.closeQuietly(dup);
                        }
                    }
                });
            } else {
                dumpDatabaseInfo(fd, args);
                dumpDatabaseInfo(pfd, args);
                IoUtils.closeQuietly(pfd);
            }
        }

@@ -1251,9 +1263,9 @@ public final class ActivityThread {
            sendMessage(H.TRANSLUCENT_CONVERSION_COMPLETE, token, drawComplete ? 1 : 0);
        }

        public void scheduleOnNewActivityOptions(IBinder token, ActivityOptions options) {
        public void scheduleOnNewActivityOptions(IBinder token, Bundle options) {
            sendMessage(H.ON_NEW_ACTIVITY_OPTIONS,
                    new Pair<IBinder, ActivityOptions>(token, options));
                    new Pair<IBinder, ActivityOptions>(token, ActivityOptions.fromBundle(options)));
        }

        public void setProcessState(int state) {
@@ -1319,10 +1331,12 @@ public final class ActivityThread {
        }

        @Override
        public void stopBinderTrackingAndDump(FileDescriptor fd) {
        public void stopBinderTrackingAndDump(ParcelFileDescriptor pfd) {
            try {
                sendMessage(H.STOP_BINDER_TRACKING_AND_DUMP, ParcelFileDescriptor.dup(fd));
                sendMessage(H.STOP_BINDER_TRACKING_AND_DUMP, pfd.dup());
            } catch (IOException e) {
            } finally {
                IoUtils.closeQuietly(pfd);
            }
        }

@@ -3097,8 +3111,8 @@ public final class ActivityThread {

        String classname = data.appInfo.backupAgentName;
        // full backup operation but no app-supplied agent?  use the default implementation
        if (classname == null && (data.backupMode == IApplicationThread.BACKUP_MODE_FULL
                || data.backupMode == IApplicationThread.BACKUP_MODE_RESTORE_FULL)) {
        if (classname == null && (data.backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL
                || data.backupMode == ApplicationThreadConstants.BACKUP_MODE_RESTORE_FULL)) {
            classname = "android.app.backup.FullBackupAgent";
        }

@@ -3130,8 +3144,9 @@ public final class ActivityThread {
                    // If this is during restore, fail silently; otherwise go
                    // ahead and let the user see the crash.
                    Slog.e(TAG, "Agent threw during creation: " + e);
                    if (data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE
                            && data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE_FULL) {
                    if (data.backupMode != ApplicationThreadConstants.BACKUP_MODE_RESTORE
                            && data.backupMode !=
                                    ApplicationThreadConstants.BACKUP_MODE_RESTORE_FULL) {
                        throw e;
                    }
                    // falling through with 'binder' still null
@@ -4904,10 +4919,10 @@ public final class ActivityThread {
    final void handleDispatchPackageBroadcast(int cmd, String[] packages) {
        boolean hasPkgInfo = false;
        switch (cmd) {
            case IApplicationThread.PACKAGE_REMOVED:
            case IApplicationThread.PACKAGE_REMOVED_DONT_KILL:
            case ApplicationThreadConstants.PACKAGE_REMOVED:
            case ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL:
            {
                final boolean killApp = cmd == IApplicationThread.PACKAGE_REMOVED;
                final boolean killApp = cmd == ApplicationThreadConstants.PACKAGE_REMOVED;
                if (packages == null) {
                    break;
                }
@@ -4932,7 +4947,7 @@ public final class ActivityThread {
                }
                break;
            }
            case IApplicationThread.PACKAGE_REPLACED:
            case ApplicationThreadConstants.PACKAGE_REPLACED:
            {
                if (packages == null) {
                    break;
@@ -5232,10 +5247,10 @@ public final class ActivityThread {
            /* ignore */
        }

        if (data.debugMode != IApplicationThread.DEBUG_OFF) {
        if (data.debugMode != ApplicationThreadConstants.DEBUG_OFF) {
            // XXX should have option to change the port.
            Debug.changeDebugPort(8100);
            if (data.debugMode == IApplicationThread.DEBUG_WAIT) {
            if (data.debugMode == ApplicationThreadConstants.DEBUG_WAIT) {
                Slog.w(TAG, "Application " + data.info.getPackageName()
                      + " is waiting for the debugger on port 8100...");

+1 −1
Original line number Diff line number Diff line
@@ -1381,7 +1381,7 @@ public class ApplicationPackageManager extends PackageManager {

    static void handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo) {
        boolean immediateGc = false;
        if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
        if (cmd == ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE) {
            immediateGc = true;
        }
        if (pkgList != null && (pkgList.length > 0)) {
+39 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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 android.app;

/**
 * @hide
 */
public final class ApplicationThreadConstants {
    public static final int BACKUP_MODE_INCREMENTAL = 0;
    public static final int BACKUP_MODE_FULL = 1;
    public static final int BACKUP_MODE_RESTORE = 2;
    public static final int BACKUP_MODE_RESTORE_FULL = 3;

    public static final int DEBUG_OFF = 0;
    public static final int DEBUG_ON = 1;
    public static final int DEBUG_WAIT = 2;

    // the package has been removed, clean up internal references
    public static final int PACKAGE_REMOVED = 0;
    public static final int EXTERNAL_STORAGE_UNAVAILABLE = 1;
    // the package is being modified in-place, don't kill it and retain references to it
    public static final int PACKAGE_REMOVED_DONT_KILL = 2;
    // a previously removed package was replaced with a new version [eg. upgrade, split added, ...]
    public static final int PACKAGE_REPLACED = 3;
}
 No newline at end of file
Loading