Skip to content

Commit

Permalink
Enable work app store only after adding a work account
Browse files Browse the repository at this point in the history
  • Loading branch information
fynngodau committed Sep 22, 2024
1 parent 68ef487 commit f257e83
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import android.accounts.Account
import android.accounts.AccountAuthenticatorResponse
import android.accounts.AccountManager
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.util.Log
Expand Down Expand Up @@ -80,6 +81,12 @@ class WorkAccountAuthenticator(val context: Context) : AbstractAccountAuthentica
putString(KEY_ACCOUNT_SERVICES, authResponse.services) // expected to be "android"
}
)) {

// Notify vending package
context.sendBroadcast(
Intent(WORK_ACCOUNT_CHANGED_BOARDCAST).setPackage("com.android.vending")
)

// Report successful creation to caller
response.onResult(Bundle().apply {
putString(AccountManager.KEY_ACCOUNT_NAME, authResponse.email)
Expand Down Expand Up @@ -203,6 +210,9 @@ class WorkAccountAuthenticator(val context: Context) : AbstractAccountAuthentica
companion object {
const val TAG = "WorkAccAuthenticator"
const val WORK_ACCOUNT_TYPE = "com.google.work"

const val WORK_ACCOUNT_CHANGED_BOARDCAST = "org.microg.vending.WORK_ACCOUNT_CHANGED"

const val KEY_ACCOUNT_CREATION_TOKEN = "creationToken"
private const val KEY_GOOGLE_USER_ID = "GoogleUserId" // TODO: use AuthConstants
private const val KEY_ACCOUNT_SERVICES = "services" // TODO: use AuthConstants
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import android.accounts.AccountManager
import android.app.admin.DevicePolicyManager
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
Expand All @@ -18,7 +19,9 @@ import android.util.Log
import com.google.android.gms.auth.account.IWorkAccountCallback
import com.google.android.gms.auth.account.IWorkAccountService
import com.google.android.gms.auth.account.authenticator.WorkAccountAuthenticator.Companion.KEY_ACCOUNT_CREATION_TOKEN
import com.google.android.gms.auth.account.authenticator.WorkAccountAuthenticator.Companion.WORK_ACCOUNT_CHANGED_BOARDCAST
import com.google.android.gms.auth.account.authenticator.WorkAccountAuthenticator.Companion.WORK_ACCOUNT_TYPE
import com.google.android.gms.auth.account.authenticator.WorkAccountAuthenticatorService
import com.google.android.gms.common.Feature
import com.google.android.gms.common.api.CommonStatusCodes
import com.google.android.gms.common.internal.ConnectionInfo
Expand Down Expand Up @@ -68,7 +71,7 @@ private fun DevicePolicyManager.isDeviceAdminApp(packageName: String?): Boolean
}
}

class WorkAccountServiceImpl(context: Context) : IWorkAccountService.Stub() {
class WorkAccountServiceImpl(val context: Context) : IWorkAccountService.Stub() {

val packageManager: PackageManager = context.packageManager
val accountManager: AccountManager = AccountManager.get(context)
Expand All @@ -82,8 +85,8 @@ class WorkAccountServiceImpl(context: Context) : IWorkAccountService.Stub() {
Log.d(TAG, "setWorkAuthenticatorEnabled with $enabled")

val componentName = ComponentName(
"com.google.android.gms",
"com.google.android.gms.auth.account.authenticator.WorkAccountAuthenticatorService"
context,
WorkAccountAuthenticatorService::class.java
)
packageManager.setComponentEnabledSetting(
componentName,
Expand Down Expand Up @@ -127,7 +130,14 @@ class WorkAccountServiceImpl(context: Context) : IWorkAccountService.Stub() {
Log.d(TAG, "removeWorkAccount with account ${account?.name}")
account?.let {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {

val success = accountManager.removeAccountExplicitly(it)

// Notify vending package
context.sendBroadcast(
Intent(WORK_ACCOUNT_CHANGED_BOARDCAST).setPackage("com.android.vending")
)

callback?.onAccountRemoved(success)
} else {
val future = accountManager.removeAccount(it, null, null)
Expand Down
11 changes: 10 additions & 1 deletion vending-app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -189,16 +189,25 @@
<receiver
android:name=".installer.SessionResultReceiver"
android:exported="false"/>

<!-- Work account store -->
<activity android:name="org.microg.vending.ui.VendingActivity"
android:exported="true"
android:theme="@style/Theme.Material3.DayNight"
android:label="@string/vending_activity_name">
android:label="@string/vending_activity_name"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="org.microg.vending.WorkAccountChangedReceiver"
android:exported="true">
<intent-filter>
<action android:name="org.microg.vending.WORK_ACCOUNT_CHANGED" />
</intent-filter>
</receiver>

</application>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.microg.vending

import android.accounts.AccountManager
import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.util.Log
import org.microg.vending.ui.VendingActivity

class WorkAccountChangedReceiver : BroadcastReceiver() {

override fun onReceive(context: Context, intent: Intent?) {
val accountManager = AccountManager.get(context)
val hasWorkAccounts = accountManager.getAccountsByType("com.google.work").isNotEmpty()

Log.d(TAG, "setting VendingActivity state to enabled = $hasWorkAccounts")

val componentName = ComponentName(
context,
VendingActivity::class.java

Check failure on line 22 in vending-app/src/main/java/org/microg/vending/WorkAccountChangedReceiver.kt

View workflow job for this annotation

GitHub Actions / Gradle build

Class requires API level 21 (current min is 19): VendingActivity [NewApi]

Check failure on line 22 in vending-app/src/main/java/org/microg/vending/WorkAccountChangedReceiver.kt

View workflow job for this annotation

GitHub Actions / Gradle build

Class requires API level 21 (current min is 19): VendingActivity [NewApi]
)
context.packageManager.setComponentEnabledSetting(
componentName,
if (hasWorkAccounts) PackageManager.COMPONENT_ENABLED_STATE_ENABLED else PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
0
)
}

companion object {
const val TAG = "GmsVendingWorkAccRcvr"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.microg.vending.ui

import android.accounts.Account
import android.accounts.AccountManager
import android.content.Intent
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
Expand All @@ -15,7 +16,6 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
Expand All @@ -37,6 +37,7 @@ import org.microg.gms.profile.Build
import org.microg.gms.profile.ProfileManager
import org.microg.gms.ui.TAG
import org.microg.vending.UploadDeviceConfigRequest
import org.microg.vending.WorkAccountChangedReceiver
import org.microg.vending.billing.AuthManager
import org.microg.vending.billing.core.AuthData
import org.microg.vending.billing.core.GooglePlayApi.Companion.URL_ENTERPRISE_CLIENT_POLICY
Expand All @@ -45,7 +46,6 @@ import org.microg.vending.billing.core.GooglePlayApi.Companion.URL_ITEM_DETAILS
import org.microg.vending.billing.core.HttpClient
import org.microg.vending.billing.createDeviceEnvInfo
import org.microg.vending.delivery.downloadPackageComponents
import org.microg.vending.enterprise.App
import org.microg.vending.enterprise.EnterpriseApp
import org.microg.vending.delivery.requestDownloadUrls
import org.microg.vending.enterprise.AppState
Expand All @@ -70,6 +70,10 @@ class VendingActivity : ComponentActivity() {
val accountManager = AccountManager.get(this)
val accounts = accountManager.getAccountsByType("com.google.work")
if (accounts.isEmpty()) {
// Component should not be enabled; disable through receiver, and redirect to main activity
WorkAccountChangedReceiver().onReceive(this, null)
startActivity(Intent(this, MainActivity::class.java))
finish()
TODO("App should only be visible if work accounts are added. Disable component and wonder why it was enabled in the first place")
} else if (accounts.size > 1) {
Log.w(TAG, "Multiple work accounts found. This is unexpected and could point " +
Expand Down Expand Up @@ -217,7 +221,7 @@ class VendingActivity : ComponentActivity() {
val state = if (!available && installedDetails == null) AppState.NOT_COMPATIBLE
else if (!available && installedDetails != null) AppState.INSTALLED
else if (available && installedDetails == null) AppState.NOT_INSTALLED
else if (available && installedDetails != null && installedDetails.versionCode > versionCode!!) AppState.UPDATE_AVAILABLE
else if (available && installedDetails != null && installedDetails.versionCode < versionCode!!) AppState.UPDATE_AVAILABLE
else /* if (available && installedDetails != null) */ AppState.INSTALLED

EnterpriseApp(
Expand Down

0 comments on commit f257e83

Please sign in to comment.