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

Commit ee81ebfd authored by Sumedh Sen's avatar Sumedh Sen
Browse files

Add more logs to Pia V2

These logs will help understand how an installation or uninstallation
proceeds through different stages, which would be helpful to debug test
failures

Bug: 331474068
Test: N/A
Change-Id: Ic287b9cfbca3babae27153c08fc23cd0830286ec
parent 79c910f8
Loading
Loading
Loading
Loading
+41 −16
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ import com.android.packageinstaller.v2.model.PackageUtil.getPackageNameForUid
import com.android.packageinstaller.v2.model.PackageUtil.isCallerSessionOwner
import com.android.packageinstaller.v2.model.PackageUtil.isInstallPermissionGrantedOrRequested
import com.android.packageinstaller.v2.model.PackageUtil.isPermissionGranted
import com.android.packageinstaller.v2.model.PackageUtil.localLogv
import java.io.File
import java.io.IOException
import kotlinx.coroutines.DelicateCoroutinesApi
@@ -75,7 +76,6 @@ class InstallRepository(private val context: Context) {
    private val devicePolicyManager: DevicePolicyManager? =
        context.getSystemService(DevicePolicyManager::class.java)
    private val appOpsManager: AppOpsManager? = context.getSystemService(AppOpsManager::class.java)
    private val localLOGV = false
    private var isSessionInstall = false
    private var isTrustedSource = false
    private val _stagingResult = MutableLiveData<InstallStage>()
@@ -155,8 +155,18 @@ class InstallRepository(private val context: Context) {
            originatingUid, callingAttributionTag
        )

        if(localLogv) {
            Log.i(LOG_TAG, "Intent: $intent\n" +
                "sessionId: $sessionId\n" +
                "staged sessionId: $stagedSessionId\n" +
                "calling package: $callingPackage\n" +
                "callingUid: $callingUid\n" +
                "originatingUid: $originatingUid")
        }

        if (callingUid == Process.INVALID_UID && sourceInfo == null) {
            // Caller's identity could not be determined. Abort the install
            Log.e(LOG_TAG, "Cannot determine caller since UID is invalid and sourceInfo is null")
            return InstallAborted(ABORT_REASON_INTERNAL_ERROR)
        }

@@ -165,6 +175,9 @@ class InstallRepository(private val context: Context) {
            || (stagedSessionId != SessionInfo.INVALID_ID
                && !isCallerSessionOwner(packageInstaller, Process.myUid(), stagedSessionId))
        ) {
            Log.e(LOG_TAG, "UID is not the owner of the session:\n" +
                "CallingUid: $originatingUid | SessionId: $sessionId\n" +
                "My UID: ${Process.myUid()} | StagedSessionId: $stagedSessionId")
            return InstallAborted(ABORT_REASON_INTERNAL_ERROR)
        }

@@ -173,6 +186,9 @@ class InstallRepository(private val context: Context) {
                context, callingUid, originatingUid, isTrustedSource
            )
        ) {
            Log.e(LOG_TAG, "UID $originatingUid needs to declare " +
                Manifest.permission.REQUEST_INSTALL_PACKAGES
            )
            return InstallAborted(ABORT_REASON_INTERNAL_ERROR)
        }

@@ -180,6 +196,7 @@ class InstallRepository(private val context: Context) {
        if (restriction != null) {
            val adminSupportDetailsIntent =
                devicePolicyManager!!.createAdminSupportIntent(restriction)
            Log.e(LOG_TAG, "$restriction set in place. Cannot install." )
            return InstallAborted(
                ABORT_REASON_POLICY, message = restriction, resultIntent = adminSupportDetailsIntent
            )
@@ -287,7 +304,7 @@ class InstallRepository(private val context: Context) {
                        stagedSessionId = packageInstaller.createSession(params)
                    }
                } catch (e: Exception) {
                    Log.w(LOG_TAG, "Failed to create a staging session", e)
                    Log.e(LOG_TAG, "Failed to create a staging session", e)
                    _stagingResult.value = InstallAborted(
                        ABORT_REASON_INTERNAL_ERROR,
                        resultIntent = Intent().putExtra(
@@ -308,6 +325,7 @@ class InstallRepository(private val context: Context) {
                    _stagingResult.value = InstallReady()
                } else {
                    cleanupStagingSession()
                    Log.e(LOG_TAG, "Could not stage APK.")
                    _stagingResult.value = InstallAborted(
                        ABORT_REASON_INTERNAL_ERROR,
                        resultIntent = Intent().putExtra(
@@ -318,6 +336,7 @@ class InstallRepository(private val context: Context) {
                }
            }
        } else {
            Log.e(LOG_TAG, "Invalid URI: ${if (uri == null) "null" else uri.scheme}")
            _stagingResult.value = InstallAborted(
                ABORT_REASON_INTERNAL_ERROR,
                resultIntent = Intent().putExtra(
@@ -403,8 +422,8 @@ class InstallRepository(private val context: Context) {
     */
    fun requestUserConfirmation(): InstallStage {
        return if (isTrustedSource) {
            if (localLOGV) {
                Log.i(LOG_TAG, "install allowed")
            if (localLogv) {
                Log.i(LOG_TAG, "Install allowed")
            }
            // Returns InstallUserActionRequired stage if install details could be successfully
            // computed, else it returns InstallAborted.
@@ -428,7 +447,7 @@ class InstallRepository(private val context: Context) {
            val info = packageInstaller.getSessionInfo(sessionId)
            val resolvedPath = info?.resolvedBaseApkPath
            if (info == null || !info.isSealed || resolvedPath == null) {
                Log.w(LOG_TAG, "Session $sessionId in funky state; ignoring")
                Log.e(LOG_TAG, "Session $sessionId in funky state; ignoring")
                return InstallAborted(ABORT_REASON_INTERNAL_ERROR)
            }
            packageSource = Uri.fromFile(File(resolvedPath))
@@ -440,7 +459,7 @@ class InstallRepository(private val context: Context) {
        } else if (PackageInstaller.ACTION_CONFIRM_PRE_APPROVAL == intent.action) {
            val info = packageInstaller.getSessionInfo(sessionId)
            if (info == null || !info.isPreApprovalRequested) {
                Log.w(LOG_TAG, "Session $sessionId in funky state; ignoring")
                Log.e(LOG_TAG, "Session $sessionId in funky state; ignoring")
                return InstallAborted(ABORT_REASON_INTERNAL_ERROR)
            }
            packageSource = info
@@ -465,7 +484,7 @@ class InstallRepository(private val context: Context) {

        // if there's nothing to do, quietly slip into the ether
        if (packageSource == null) {
            Log.w(LOG_TAG, "Unspecified source")
            Log.e(LOG_TAG, "Unspecified source")
            return InstallAborted(
                ABORT_REASON_INTERNAL_ERROR,
                resultIntent = Intent().putExtra(
@@ -509,7 +528,7 @@ class InstallRepository(private val context: Context) {
        if (scheme == null) {
            return InstallAborted(ABORT_REASON_INTERNAL_ERROR)
        }
        if (localLOGV) {
        if (localLogv) {
            Log.i(LOG_TAG, "processPackageUri(): uri = $packageUri, scheme = $scheme")
        }
        when (scheme) {
@@ -528,7 +547,7 @@ class InstallRepository(private val context: Context) {
                    }
                }
                if (newPackageInfo == null) {
                    Log.w(
                    Log.e(
                        LOG_TAG, "Requested package " + packageUri.schemeSpecificPart
                            + " not available. Discontinuing installation"
                    )
@@ -542,7 +561,7 @@ class InstallRepository(private val context: Context) {
                    )
                }
                appSnippet = getAppSnippet(context, newPackageInfo!!)
                if (localLOGV) {
                if (localLogv) {
                    Log.i(LOG_TAG, "Created snippet for " + appSnippet.label)
                }
            }
@@ -569,7 +588,7 @@ class InstallRepository(private val context: Context) {
                        activityResultCode = Activity.RESULT_FIRST_USER
                    )
                }
                if (localLOGV) {
                if (localLogv) {
                    Log.i(LOG_TAG, "Creating snippet for local file $sourceFile")
                }
                appSnippet = getAppSnippet(context, newPackageInfo!!, sourceFile!!)
@@ -590,9 +609,7 @@ class InstallRepository(private val context: Context) {
     * Use the SessionInfo and set up the installer for pre-commit install session.
     *
     * @param sessionInfo The SessionInfo to compose
     * @return
     *  * [InstallUserActionRequired] if source could be processed
     *  * [InstallAborted] if source is invalid or there was an error is processing a source
     * @return [InstallUserActionRequired]
     */
    private fun processSessionInfo(sessionInfo: SessionInfo, userActionReason: Int): InstallStage {
        newPackageInfo = generateStubPackageInfo(sessionInfo.getAppPackageName())
@@ -718,7 +735,7 @@ class InstallRepository(private val context: Context) {
            appOpStr!!, requestInfo.originatingUid, requestInfo.callingPackage,
            requestInfo.attributionTag, "Started package installation activity"
        )
        if (localLOGV) {
        if (localLogv) {
            Log.i(LOG_TAG, "handleUnknownSources(): appMode=$appOpMode")
        }

@@ -764,6 +781,9 @@ class InstallRepository(private val context: Context) {
    fun initiateInstall() {
        if (sessionId > 0) {
            packageInstaller.setPermissionsResult(sessionId, true)
            if (localLogv) {
                Log.i(LOG_TAG, "Install permission granted for session $sessionId")
            }
            _installResult.value = InstallAborted(
                ABORT_REASON_DONE, activityResultCode = Activity.RESULT_OK
            )
@@ -824,8 +844,13 @@ class InstallRepository(private val context: Context) {
    private fun setStageBasedOnResult(
        statusCode: Int,
        legacyStatus: Int,
        message: String?
        message: String?,
    ) {
        if (localLogv) {
            Log.i(LOG_TAG, "Status code: $statusCode\n" +
                "legacy status: $legacyStatus\n" +
                "message: $message")
        }
        if (statusCode == PackageInstaller.STATUS_SUCCESS) {
            val shouldReturnResult = intent.getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)
            val resultIntent = if (shouldReturnResult) {
+8 −3
Original line number Diff line number Diff line
@@ -36,7 +36,8 @@ import java.io.File
object PackageUtil {
    private val LOG_TAG = InstallRepository::class.java.simpleName
    private const val DOWNLOADS_AUTHORITY = "downloads"
    private const val SPLIT_BASE_APK_END_WITH = "base.apk"
    private const val SPLIT_BASE_APK_SUFFIX = "base.apk"
    const val localLogv = false

    /**
     * Determines if the UID belongs to the system downloads provider and returns the
@@ -394,7 +395,7 @@ object PackageUtil {
    @JvmStatic
    fun getPackageInfo(context: Context, sourceFile: File, flags: Int): PackageInfo? {
        var filePath = sourceFile.absolutePath
        if (filePath.endsWith(SPLIT_BASE_APK_END_WITH)) {
        if (filePath.endsWith(SPLIT_BASE_APK_SUFFIX)) {
            val dir = sourceFile.parentFile
            if ((dir?.listFiles()?.size ?: 0) > 1) {
                // split apks, use file directory to get archive info
@@ -436,5 +437,9 @@ object PackageUtil {
     * The class to hold an incoming package's icon and label.
     * See [getAppSnippet]
     */
    data class AppSnippet(var label: CharSequence?, var icon: Drawable?)
    data class AppSnippet(var label: CharSequence?, var icon: Drawable?) {
        override fun toString(): String {
            return "AppSnippet[label = ${label}, hasIcon = ${icon != null}]"
        }
    }
}
+7 −4
Original line number Diff line number Diff line
@@ -226,18 +226,19 @@ class UninstallRepository(private val context: Context) {
                userName
            )
            if (userManager!!.isSameProfileGroup(myUserHandle, uninstalledUser!!)) {
                if (customUserManager!!.isManagedProfile()) {
                if (customUserManager.isManagedProfile) {
                    messageString = context.getString(
                            R.string.uninstall_application_text_current_user_work_profile, userName
                    )
                } else if (customUserManager!!.isCloneProfile()){
                } else if (customUserManager.isCloneProfile){
                    isClonedApp = true
                    messageString = context.getString(
                            R.string.uninstall_application_text_current_user_clone_profile
                    )
                } else if (Flags.allowPrivateProfile()
                        && android.multiuser.Flags.enablePrivateSpaceFeatures()
                        && customUserManager!!.isPrivateProfile()) {
                        && customUserManager.isPrivateProfile
                ) {
                    // TODO(b/324244123): Get these Strings from a User Property API.
                    messageString = context.getString(
                            R.string.uninstall_application_text_current_user_private_profile
@@ -401,6 +402,7 @@ class UninstallRepository(private val context: Context) {
        uninstallData.putBoolean(Intent.EXTRA_UNINSTALL_ALL_USERS, uninstallFromAllUsers)
        uninstallData.putCharSequence(EXTRA_APP_LABEL, targetAppLabel)
        uninstallData.putBoolean(EXTRA_IS_CLONE_APP, isClonedApp)
        uninstallData.putInt(EXTRA_TARGET_USER_ID, uninstalledUser!!.identifier)
        Log.i(LOG_TAG, "Uninstalling extras = $uninstallData")

        // Get a PendingIntent for result broadcast and issue an uninstall request
@@ -730,7 +732,7 @@ class UninstallRepository(private val context: Context) {
        }
    }

    fun cancelInstall() {
    fun cancelUninstall() {
        if (callback != null) {
            callback!!.onUninstallComplete(
                targetPackageName!!,
@@ -749,6 +751,7 @@ class UninstallRepository(private val context: Context) {
        private const val EXTRA_IS_CLONE_APP = "com.android.packageinstaller.extra.IS_CLONE_APP"
        private const val EXTRA_PACKAGE_NAME =
            "com.android.packageinstaller.extra.EXTRA_PACKAGE_NAME"
        private const val EXTRA_TARGET_USER_ID = "EXTRA_TARGET_USER_ID"
    }

    class CallerInfo(val activityName: String?, val uid: Int)
+19 −5
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import com.android.packageinstaller.v2.model.InstallRepository
import com.android.packageinstaller.v2.model.InstallStage
import com.android.packageinstaller.v2.model.InstallSuccess
import com.android.packageinstaller.v2.model.InstallUserActionRequired
import com.android.packageinstaller.v2.model.PackageUtil.localLogv
import com.android.packageinstaller.v2.ui.fragments.AnonymousSourceFragment
import com.android.packageinstaller.v2.ui.fragments.ExternalSourcesBlockedFragment
import com.android.packageinstaller.v2.ui.fragments.InstallConfirmationFragment
@@ -66,8 +67,6 @@ class InstallLaunch : FragmentActivity(), InstallActionListener {
        private const val TAG_DIALOG = "dialog"
    }

    private val localLOGV = false

    /**
     * A collection of unknown sources listeners that are actively listening for app ops mode
     * changes
@@ -199,14 +198,14 @@ class InstallLaunch : FragmentActivity(), InstallActionListener {
        // admin enforcing the restriction for the affected user. If not enforced by the admin,
        // show the system dialog.
        if (adminSupportIntent != null) {
            if (localLOGV) {
            if (localLogv) {
                Log.i(LOG_TAG, "Restriction set by admin, starting $adminSupportIntent")
            }
            startActivity(adminSupportIntent)
            // Finish the package installer app since the next dialog will not be shown by this app
            shouldFinish = true
        } else {
            if (localLOGV) {
            if (localLogv) {
                Log.i(LOG_TAG, "Restriction set by system: $restriction")
            }
            val blockedByPolicyDialog = createDevicePolicyRestrictionDialog(restriction)
@@ -225,7 +224,7 @@ class InstallLaunch : FragmentActivity(), InstallActionListener {
     * @return The dialog
     */
    private fun createDevicePolicyRestrictionDialog(restriction: String?): DialogFragment? {
        if (localLOGV) {
        if (localLogv) {
            Log.i(LOG_TAG, "createDialog($restriction)")
        }
        return when (restriction) {
@@ -259,6 +258,9 @@ class InstallLaunch : FragmentActivity(), InstallActionListener {
    }

    override fun onPositiveResponse(reasonCode: Int) {
        if (localLogv) {
            Log.d(LOG_TAG, "Positive button clicked. ReasonCode: $reasonCode")
        }
        when (reasonCode) {
            InstallUserActionRequired.USER_ACTION_REASON_ANONYMOUS_SOURCE ->
                installViewModel!!.forcedSkipSourceCheck()
@@ -269,6 +271,9 @@ class InstallLaunch : FragmentActivity(), InstallActionListener {
    }

    override fun onNegativeResponse(stageCode: Int) {
        if (localLogv) {
            Log.d(LOG_TAG, "Negative button clicked. StageCode: $stageCode")
        }
        if (stageCode == InstallStage.STAGE_USER_ACTION_REQUIRED) {
            installViewModel!!.cleanupInstall()
        }
@@ -276,10 +281,16 @@ class InstallLaunch : FragmentActivity(), InstallActionListener {
    }

    override fun onNegativeResponse(resultCode: Int, data: Intent?) {
        if (localLogv) {
            Log.d(LOG_TAG, "Negative button clicked. resultCode: $resultCode; Intent: $data")
        }
        setResult(resultCode, data, true)
    }

    override fun sendUnknownAppsIntent(sourcePackageName: String) {
        if (localLogv) {
            Log.d(LOG_TAG, "Launching unknown-apps settings intent for $sourcePackageName")
        }
        val settingsIntent = Intent()
        settingsIntent.setAction(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES)
        val packageUri = Uri.parse("package:$sourcePackageName")
@@ -299,6 +310,9 @@ class InstallLaunch : FragmentActivity(), InstallActionListener {
    }

    override fun openInstalledApp(intent: Intent?) {
        if (localLogv) {
            Log.d(LOG_TAG, "Opening $intent")
        }
        setResult(Activity.RESULT_OK, intent, true)
        if (intent != null && intent.hasCategory(Intent.CATEGORY_LAUNCHER)) {
            startActivity(intent)
+8 −1
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.ViewModelProvider
import com.android.packageinstaller.v2.model.PackageUtil.localLogv
import com.android.packageinstaller.v2.model.UninstallAborted
import com.android.packageinstaller.v2.model.UninstallFailed
import com.android.packageinstaller.v2.model.UninstallRepository
@@ -159,11 +160,17 @@ class UninstallLaunch : FragmentActivity(), UninstallActionListener {
    }

    override fun onPositiveResponse(keepData: Boolean) {
        if (localLogv) {
            Log.d(LOG_TAG, "Staring uninstall")
        }
        uninstallViewModel!!.initiateUninstall(keepData)
    }

    override fun onNegativeResponse() {
        uninstallViewModel!!.cancelInstall()
        if (localLogv) {
            Log.d(LOG_TAG, "Cancelling uninstall")
        }
        uninstallViewModel!!.cancelUninstall()
        setResult(Activity.RESULT_FIRST_USER, null, true)
    }
}
Loading