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

Commit 51deee21 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add a loading screen while enabling supervision app" into main

parents 34cd1e80 38733c8f
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -2811,6 +2811,12 @@
            </intent-filter>
        </activity>

        <activity
            android:enableOnBackInvokedCallback="true"
            android:name=".supervision.SupervisionDashboardLoadingActivity"
            android:label="@string/supervision_settings_title"
            android:exported="false"/>

        <activity
            android:name=".supervision.SupervisionDashboardActivity"
            android:label="@string/supervision_settings_title"
+34 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?><!--
  ~ Copyright (C) 2025 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.
  -->

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:layout_gravity="center_horizontal">

    <com.google.android.material.progressindicator.LinearProgressIndicator
        android:theme="@style/Theme.Material3.DynamicColors.DayNight"
        android:id="@+id/linearProgressIndicator"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp"
        android:layout_marginStart="18dp"
        android:layout_marginEnd="18dp"
        android:indeterminate="true"
        app:trackThickness="@dimen/settingslib_expressive_space_extrasmall4" />
</RelativeLayout>
+7 −3
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.settings.supervision

import android.content.Intent
import android.os.Bundle
import com.android.settings.CatalystSettingsActivity

@@ -29,10 +30,13 @@ class SupervisionDashboardActivity :
        SupervisionDashboardScreen.KEY,
        SupervisionDashboardFragment::class.java,
    ) {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // TODO(b/418837620) Show a loading screen if supervision app with required component is not
        // present.

        if (!hasNecessarySupervisionComponent()) {
            val loadingActivity = Intent(this, SupervisionDashboardLoadingActivity::class.java)
            startActivity(loadingActivity)
            finish()
        }
    }
}
+101 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.settings.supervision

import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
import android.view.MenuItem
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.lifecycleScope
import com.android.settings.R
import com.android.settings.core.CategoryMixin
import com.android.settings.overlay.FeatureFactory.Companion.featureFactory
import com.android.settingslib.collapsingtoolbar.R.drawable.settingslib_expressive_icon_back as EXPRESSIVE_BACK_ICON
import com.android.settingslib.drawer.CategoryKey.CATEGORY_SUPERVISION
import com.android.settingslib.widget.SettingsThemeHelper
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

class SupervisionDashboardLoadingActivity : FragmentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Get the supervision package name from the system config
        val supervisionPackage =
            resources.getString(com.android.internal.R.string.config_systemSupervision)
        if (supervisionPackage == null) {
            finish()
            return
        }

        setContentView(R.layout.supervision_dashboard_loading_screen)

        // Enable supervision app
        lifecycleScope.launch(Dispatchers.Default) {
            packageManager.setApplicationEnabledSetting(
                supervisionPackage,
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                0,
            )

            // Update category after enabling supervision app
            CategoryMixin(this@SupervisionDashboardLoadingActivity).updateCategories()
            val dashboardFeatureProvider = featureFactory.dashboardFeatureProvider

            while (
                !hasNecessarySupervisionComponent(supervisionPackage) ||
                    dashboardFeatureProvider.getTilesForCategory(CATEGORY_SUPERVISION) == null
            ) {
                delay(100) // Check every 100 ms (adjust as needed)
            }

            lifecycleScope.launch(Dispatchers.Main) {
                val dashboardActivity =
                    Intent(
                        this@SupervisionDashboardLoadingActivity,
                        SupervisionDashboardActivity::class.java,
                    )
                startActivity(dashboardActivity)
                finish()
            }
        }
    }

    override fun onResume() {
        super.onResume()

        val actionBar = getActionBar()
        if (actionBar != null) {
            actionBar.elevation = 0f
            actionBar.setDisplayHomeAsUpEnabled(true)
            if (SettingsThemeHelper.isExpressiveTheme(this)) {
                actionBar.setHomeAsUpIndicator(EXPRESSIVE_BACK_ICON)
            }
        }
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        if (item.itemId == android.R.id.home) {
            finish()
            return true
        }
        return super.onOptionsItemSelected(item)
    }
}
+11 −0
Original line number Diff line number Diff line
@@ -18,10 +18,12 @@ package com.android.settings.supervision
import android.app.KeyguardManager
import android.app.role.RoleManager
import android.content.Context
import android.content.Intent
import android.os.UserHandle
import android.os.UserManager
import android.os.UserManager.USER_TYPE_PROFILE_SUPERVISING
import android.util.Log
import com.android.settings.supervision.ipc.SupervisionMessengerClient.Companion.SUPERVISION_MESSENGER_SERVICE_BIND_ACTION
import com.android.settingslib.supervision.SupervisionLog.TAG

val Context.isSupervisingCredentialSet: Boolean
@@ -53,3 +55,12 @@ val Context.supervisionPackageName: String?
        // supervision role is exclusive, only one app may hold this role in a user
        return roleHolders.firstOrNull()
    }

fun Context.hasNecessarySupervisionComponent() =
    hasNecessarySupervisionComponent(supervisionPackageName)

fun Context.hasNecessarySupervisionComponent(packageName: String?): Boolean {
    if (packageName == null) return false
    val intent = Intent(SUPERVISION_MESSENGER_SERVICE_BIND_ACTION).setPackage(packageName)
    return packageManager?.queryIntentServices(intent, 0)?.isNotEmpty() == true
}
Loading