1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.spa 18 19 import android.app.ActivityManager 20 import android.content.Context 21 import android.content.Intent 22 import android.os.RemoteException 23 import android.os.UserHandle 24 import android.util.Log 25 import androidx.annotation.VisibleForTesting 26 import com.android.settings.spa.app.appinfo.AppInfoSettingsProvider 27 import com.android.settingslib.spa.framework.BrowseActivity 28 import com.android.settingslib.spa.framework.common.SettingsPage 29 import com.android.settingslib.spa.framework.util.SESSION_BROWSE 30 import com.android.settingslib.spa.framework.util.SESSION_EXTERNAL 31 import com.android.settingslib.spa.framework.util.appendSpaParams 32 import com.google.android.setupcompat.util.WizardManagerHelper 33 34 class SpaActivity : BrowseActivity() { isPageEnablednull35 override fun isPageEnabled(page: SettingsPage) = 36 super.isPageEnabled(page) && !isSuwAndPageBlocked(page.sppName) 37 38 companion object { 39 private const val TAG = "SpaActivity" 40 41 /** The pages that blocked from SUW. */ 42 private val SuwBlockedPages = setOf(AppInfoSettingsProvider.name) 43 44 @VisibleForTesting 45 fun Context.isSuwAndPageBlocked(name: String): Boolean = 46 if (name in SuwBlockedPages && !WizardManagerHelper.isDeviceProvisioned(this)) { 47 Log.w(TAG, "$name blocked before SUW completed."); 48 true 49 } else { 50 false 51 } 52 53 @JvmStatic 54 fun Context.startSpaActivity(destination: String) { 55 val intent = Intent(this, SpaActivity::class.java) 56 .appendSpaParams(destination = destination) 57 if (isLaunchedFromInternal()) { 58 intent.appendSpaParams(sessionName = SESSION_BROWSE) 59 } else { 60 intent.appendSpaParams(sessionName = SESSION_EXTERNAL) 61 } 62 startActivity(intent) 63 } 64 65 @JvmStatic 66 fun Context.startSpaActivityForApp(destinationPrefix: String, intent: Intent): Boolean { 67 val packageName = intent.data?.schemeSpecificPart ?: return false 68 startSpaActivity("$destinationPrefix/$packageName/${UserHandle.myUserId()}") 69 return true 70 } 71 72 fun Context.isLaunchedFromInternal(): Boolean { 73 var pkg: String? = null 74 try { 75 pkg = ActivityManager.getService().getLaunchedFromPackage(getActivityToken()) 76 } catch (e: RemoteException) { 77 Log.v(TAG, "Could not talk to activity manager.", e) 78 } 79 return applicationContext.packageName == pkg 80 } 81 } 82 } 83