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

Commit edd9a262 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 6780056 from 4b867486 to rvc-qpr1-release

Change-Id: I66c9828f01960f96bd1c4621e364dec73b5e8f74
parents a09ab5e7 4b867486
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -35,6 +35,23 @@
            android:id="@+id/items_container"
            style="@style/PermissionUsageDialogItemsContainer"/>

        <TextView
            android:id="@+id/other_use_header"
            android:text="@string/other_use"
            style="@style/PermissionUsageDialogOtherUseHeader"/>

        <TextView
            android:id="@+id/other_use_content"
            style="@style/PermissionUsageDialogOtherUseContent"/>

        <View
            android:id="@+id/other_use_inside_spacer"
            style="@style/PermissionUsageDialogOtherUseInsideSpacer"/>

        <TextView
            android:id="@+id/system_use_content"
            style="@style/PermissionUsageDialogSystemUseContent"/>

    </LinearLayout>

</ScrollView>
+4 −0
Original line number Diff line number Diff line
@@ -153,6 +153,10 @@
            <item type="style" name="PermissionUsageDialogItemAppName" />
            <item type="style" name="PermissionUsageDialogItemPermissionsList" />
            <item type="style" name="PermissionUsageDialogItemIconsContainer" />
            <item type="style" name="PermissionUsageDialogOtherUseHeader" />
            <item type="style" name="PermissionUsageDialogOtherUseContent" />
            <item type="style" name="PermissionUsageDialogOtherUseInsideSpacer" />
            <item type="style" name="PermissionUsageDialogSystemUseContent" />
            <!-- END ONGOING USAGE DIALOG -->

            <!-- START REQUEST ROLE DIALOG TITLE -->
+17 −0
Original line number Diff line number Diff line
@@ -884,6 +884,23 @@
    <!-- Label for the button to set an application as the default application [CHAR LIMIT=20] -->
    <string name="request_role_set_as_default">Set as default</string>

    <!-- Message telling the user that a phone call is currently using the microphone [CHAR LIMIT=none] -->
    <string name="phone_call_uses_microphone">Microphone is used in &lt;b>phone call&lt;/b></string>
    <!-- Message telling the user that a phone call is currently using the microphone and the camera [CHAR LIMIT=none] -->
    <string name="phone_call_uses_microphone_and_camera">Camera and Microphone are used in &lt;b>video call&lt;/b></string>
    <!-- Message telling the user that a phone call is currently using the camera [CHAR LIMIT=none] -->
    <string name="phone_call_uses_camera">Camera is used in &lt;b>video call&lt;/b></string>

    <!-- Message telling the user that a system service is currently using the microphone [CHAR LIMIT=none] -->
    <string name="system_uses_microphone">Microphone is accessed using system service</string>
    <!-- Message telling the user that a system service is currently using the microphone and the camera [CHAR LIMIT=none] -->
    <string name="system_uses_microphone_and_camera">Camera and Microphone are accessed using system service</string>
    <!-- Message telling the user that a system service is currently using the camera [CHAR LIMIT=none] -->
    <string name="system_uses_camera">Camera is accessed using system service</string>

    <!-- Line above a list of other apps and system service that are currently microphone or camera [CHAR LIMIT=60] -->
    <string name="other_use">Other use:</string>

    <!-- Action for accepting the Ongoing usage dialog [CHAR LIMIT=10]-->
    <string name="ongoing_usage_dialog_ok">Got it</string>

+26 −0
Original line number Diff line number Diff line
@@ -663,6 +663,32 @@
        <item name="android:layout_gravity">end</item>
    </style>

    <style name="PermissionUsageDialogOtherUseHeader">
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:textAppearance">?android:textAppearanceListItemSecondary</item>
        <item name="android:layout_marginStart">16dp</item>
    </style>

    <style name="PermissionUsageDialogOtherUseContent">
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:textAppearance">?android:textAppearanceListItemSecondary</item>
        <item name="android:layout_marginStart">16dp</item>
    </style>

    <style name="PermissionUsageDialogOtherUseInsideSpacer">
        <item name="android:layout_width">0dp</item>
        <item name="android:layout_height">16dp</item>
    </style>

    <style name="PermissionUsageDialogSystemUseContent">
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:textAppearance">?android:textAppearanceListItemSecondary</item>
        <item name="android:layout_marginStart">16dp</item>
    </style>

    <!-- END ONGOING USAGE DIALOG -->

    <!-- START REQUEST ROLE DIALOG TITLE -->
+127 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.permissioncontroller.permission.data

import android.app.AppOpsManager
import android.app.AppOpsManager.OP_FLAGS_ALL_TRUSTED
import android.app.Application
import android.os.UserHandle
import com.android.permissioncontroller.PermissionControllerApplication
import kotlinx.coroutines.Job
import java.util.function.Consumer

/**
 * LiveData that loads the last usage of each of a list of app ops for every package.
 *
 * <p>For app-ops with duration the end of the access is considered.
 *
 * @param app The current application
 * @param opNames The names of the app ops we wish to search for
 * @param usageDurationMs how much ago can an access have happened to be considered
 */
// TODO: listen for updates
class OpUsageLiveData(
    private val app: Application,
    private val opNames: List<String>,
    private val usageDurationMs: Long
) : SmartAsyncMediatorLiveData<@JvmSuppressWildcards Map<String, List<OpAccess>>>(),
        Consumer<AppOpsManager.HistoricalOps> {
    val appOpsManager = app.getSystemService(AppOpsManager::class.java)!!

    override suspend fun loadDataAndPostValue(job: Job) {
        val now = System.currentTimeMillis()
        val opMap = mutableMapOf<String, MutableList<OpAccess>>()

        val packageOps = appOpsManager.getPackagesForOps(opNames.toTypedArray())
        for (packageOp in packageOps) {
            for (opEntry in packageOp.ops) {
                val user = UserHandle.getUserHandleForUid(packageOp.uid)
                val lastAccessTime: Long = opEntry.getLastAccessTime(OP_FLAGS_ALL_TRUSTED)

                if (lastAccessTime == -1L) {
                    // There was no access, so skip
                    continue
                }

                var lastAccessDuration = opEntry.getLastDuration(OP_FLAGS_ALL_TRUSTED)

                // Some accesses have no duration
                if (lastAccessDuration == -1L) {
                    lastAccessDuration = 0
                }

                if (opEntry.isRunning ||
                        lastAccessTime + lastAccessDuration > (now - usageDurationMs)) {
                    val accessList = opMap.getOrPut(opEntry.opStr) { mutableListOf() }
                    val accessTime = if (opEntry.isRunning) {
                        -1
                    } else {
                        lastAccessTime
                    }
                    accessList.add(OpAccess(packageOp.packageName, user, accessTime))
                }
            }
        }

        postValue(opMap)
    }

    override fun accept(historicalOps: AppOpsManager.HistoricalOps) {
        val opMap = mutableMapOf<String, MutableList<OpAccess>>()
        for (i in 0 until historicalOps.uidCount) {
            val historicalUidOps = historicalOps.getUidOpsAt(i)
            val user = UserHandle.getUserHandleForUid(historicalUidOps.uid)
            for (j in 0 until historicalUidOps.packageCount) {
                val historicalPkgOps = historicalUidOps.getPackageOpsAt(j)
                val pkgName = historicalPkgOps.packageName
                for (k in 0 until historicalPkgOps.opCount) {
                    val historicalAttributedOps = historicalPkgOps.getAttributedOpsAt(k)
                    for (l in 0 until historicalAttributedOps.opCount) {
                        val historicalOp = historicalAttributedOps.getOpAt(l)
                        val opName = historicalOp.opName

                        val accessList = opMap.getOrPut(opName) { mutableListOf() }
                        accessList.add(OpAccess(pkgName, user, -1))
                    }
                }
            }
        }
    }

    override fun onActive() {
        super.onActive()
        updateAsync()
    }

    companion object : DataRepository<Pair<List<String>, Long>, OpUsageLiveData>() {
        override fun newValue(key: Pair<List<String>, Long>): OpUsageLiveData {
            return OpUsageLiveData(PermissionControllerApplication.get(), key.first, key.second)
        }

        operator fun get(ops: List<String>, usageDurationMs: Long): OpUsageLiveData {
            return get(ops to usageDurationMs)
        }
    }
}

data class OpAccess(val packageName: String?, val user: UserHandle?, val lastAccessTime: Long) {
    companion object {
        const val IS_RUNNING = -1L
    }

    fun isRunning() = lastAccessTime == IS_RUNNING
}
Loading