-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Work app store #2553
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Work app store #2553
Changes from 58 commits
Commits
Show all changes
88 commits
Select commit
Hold shift + click to select a range
34ccbe2
SplitInstallService Additions
DaVinci9196 5e6f01e
add permission
DaVinci9196 1962f33
ISplitInstallServiceCallback added
DaVinci9196 c9bfbc0
remove Phenotype / Experiment
DaVinci9196 796c3ab
Merge branch 'microg:master' into split_install_service
DaVinci9196 e8a0058
Optimizing the code
DaVinci9196 b8d2b20
SplitInstallService add call super.onBind
DaVinci9196 6cdd488
Fixed the issue that multiple versions of language packs could not be…
DaVinci9196 36651db
Formatting Code
DaVinci9196 ff837d9
Formatting Code
DaVinci9196 8a68044
Execute processing suggestions
DaVinci9196 5a9f1b3
cleanup
DaVinci9196 7df6f93
Location/Huawei: Fix permission notification cancelling
mar-v-in bc57d78
Added the automatic login function for Games (#2435)
DaVinci9196 a7a2584
Location: Make sure current interval and configured interval stay in …
mar-v-in c5b7383
Create Work Account service
fynngodau 686ab6d
Introduce WorkAccountAuthenticatorService
jonathanklee 96e6b0c
Work account POC
fynngodau 7f4f252
Work profile: use correct AIDL
fynngodau 762fa53
Call account creation when app is using API to create work account
fynngodau 999e1d3
Work account: Fix rough edges
fynngodau 3af3991
Work account: Add security checks
fynngodau 5e2c9d3
Work account: Redeem token when signing in to account
fynngodau 3128c06
Add license identifiers and remove unwanted changes
fynngodau 30f4858
Work account: Fix `NewApi` lint failure
fynngodau 482038a
Deduplicate work account service declaration
fynngodau 5a39c65
POC: Test activity in companion app to show client policy
fynngodau 0db6eed
Improve visuals of vending activity
fynngodau c621098
Fetch bulk details for apps retrieved from policy
fynngodau 1e17cc1
Load app details using getItems
fynngodau 8e5ca13
Cleanup: Remove nonfunctional bulkDetails request
fynngodau 20e04fe
UI: Add download button
fynngodau e99cbd3
Fetch app download URLs
fynngodau 80c9c52
Add app installation support
fynngodau 7ab6cf1
Add app uninstallation support
fynngodau c3398b9
Refactor SplitInstallManager: data types
fynngodau 3edeb83
Refactor SplitInstallManager: structural pt. 1
fynngodau 23d4459
`FLAG_MUTABLE` instead of `FLAG_IMMUTABLE`
fynngodau e434c8c
Refactor SplitInstallManager: structural pt. 2
fynngodau 73f1a3a
Refactor SplitInstallManager: structural pt. 3
fynngodau 3b8509d
Work vending: Show installation success without reload
fynngodau 68ef487
Use cache dir instead of files dir
fynngodau f257e83
Enable work app store only after adding a work account
fynngodau 1887759
Fix lint
fynngodau 85bd1c9
Fix split installs
fynngodau 2e1dfec
Organize vending protobuf files
fynngodau ec18cdb
Replace volley with ktor + okhttp
fynngodau 09acd1a
Install packages directly to improve performance
fynngodau 9ee71fb
Add progress bar to work app store
fynngodau 352260d
Reimplement caching in `HttpClient`
fynngodau 2109e46
Discard session after exception to clear up storage
fynngodau c237146
Notifications upon install progress
fynngodau f39a889
Deduplicate auth-related files
fynngodau c976df1
Clean up constants
fynngodau f14124c
Merge master branch into workaccount-store
fynngodau 655cc6f
Fix crash when no apps in enterprise policy
fynngodau 4f0665c
Fix build
fynngodau a6dc3b3
Purchase apps before downloading in work store
fynngodau b2cec33
Support additional strange behaviors
fynngodau 04afa56
Show info: wait before work app store can be used
fynngodau ed745dc
Apply review
fynngodau 74c6e05
Fix file name of `strings.xml`
fynngodau 7eea5f3
Merge master branch into workaccount-store
fynngodau e0a4bf5
Reapply "Enable multidex"
fynngodau 2c449c4
Add interaction with work profile to self-check
fynngodau 63c8154
Transfer settings provider URI from primary to work profile
fynngodau 9ff41af
Fix too long app name pushing out icons
fynngodau 0ae381d
Dependency installation (experimental)
fynngodau c2732da
Send URI as response data rather than activity creation data
fynngodau a85efb1
Improve documentation
fynngodau 423f762
Create request activity even outside of activity contexts
fynngodau 127184c
Always show positive self-check on INTERACT_ACROSS_USERS
fynngodau 4490e64
Establish access to main profile's data on managed profile setup
fynngodau cbf4784
Avoid crash when failing to add work account
fynngodau d1474ca
Add preference for work account
fynngodau 6e18e47
Work profile preferences UI
fynngodau bbac09b
Only share work profile-related preferences
fynngodau 6e66498
Merge branch 'workaccount-store-cross-profile' into workaccount-store
fynngodau 072ab8d
Install library dependencies only if not yet installed
fynngodau 774a5bd
Rename function that accesses cross-profile prefs
fynngodau f140d55
Move app installation to foreground service
fynngodau bc30c8a
Remove app installation notification recreation
fynngodau 0cefb34
Switch for on-demand downloading of specific app features
DaVinci9196 40c7a24
Minor logging adjustments
fynngodau c126362
Add missing license headers
fynngodau 3ac9f2e
Remove duplicate class
fynngodau 0d7c28f
Merge master branch into workaccount-store
fynngodau df9d7cb
Emit error on early install failure
fynngodau File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| /* | ||
| * SPDX-FileCopyrightText: 2023 e foundation | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| apply plugin: 'com.android.library' | ||
| apply plugin: 'maven-publish' | ||
| apply plugin: 'signing' | ||
|
|
||
| android { | ||
| namespace "com.google.android.gms.auth.workaccount" | ||
|
|
||
| compileSdkVersion androidCompileSdk | ||
| buildToolsVersion "$androidBuildVersionTools" | ||
|
|
||
| buildFeatures { | ||
| aidl = true | ||
| } | ||
|
|
||
| defaultConfig { | ||
| versionName version | ||
| minSdkVersion androidMinSdk | ||
| targetSdkVersion androidTargetSdk | ||
| } | ||
|
|
||
| compileOptions { | ||
| sourceCompatibility = 1.8 | ||
| targetCompatibility = 1.8 | ||
| } | ||
|
|
||
| } | ||
|
|
||
| apply from: '../gradle/publish-android.gradle' | ||
|
|
||
| description = 'microG implementation of managed work account support' | ||
|
|
||
| dependencies { | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| /* | ||
| * SPDX-FileCopyrightText: 2023 e foundation | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| apply plugin: 'com.android.library' | ||
| apply plugin: 'kotlin-android' | ||
|
|
||
| dependencies { | ||
| api project(':play-services-auth-workaccount') | ||
| api project(':play-services-auth') | ||
| implementation project(':play-services-base-core') | ||
|
|
||
| implementation "androidx.appcompat:appcompat:$appcompatVersion" | ||
| } | ||
|
|
||
| android { | ||
| namespace "com.google.android.gms.auth.workaccount" | ||
|
|
||
| compileSdkVersion androidCompileSdk | ||
| buildToolsVersion "$androidBuildVersionTools" | ||
|
|
||
| defaultConfig { | ||
| versionName version | ||
| minSdkVersion androidMinSdk | ||
| targetSdkVersion androidTargetSdk | ||
| } | ||
|
|
||
| sourceSets { | ||
| main.java.srcDirs += 'src/main/kotlin' | ||
| } | ||
|
|
||
| compileOptions { | ||
| sourceCompatibility = 1.8 | ||
| targetCompatibility = 1.8 | ||
| } | ||
|
|
||
| kotlinOptions { | ||
| jvmTarget = 1.8 | ||
| } | ||
|
|
||
| lintOptions { | ||
| disable 'MissingTranslation' | ||
| } | ||
| } |
49 changes: 49 additions & 0 deletions
49
play-services-auth-workaccount/core/src/main/AndroidManifest.xml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <!-- | ||
| ~ SPDX-FileCopyrightText: 2023 e foundation | ||
| ~ SPDX-License-Identifier: Apache-2.0 | ||
| --> | ||
|
|
||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android"> | ||
|
|
||
| <uses-permission | ||
| android:name="android.permission.AUTHENTICATE_ACCOUNTS" | ||
| android:maxSdkVersion="22" /> | ||
| <uses-permission | ||
| android:name="android.permission.GET_ACCOUNTS" | ||
| android:maxSdkVersion="22" /> | ||
| <uses-permission | ||
| android:name="android.permission.MANAGE_ACCOUNTS" | ||
| android:maxSdkVersion="22" /> | ||
|
|
||
| <application> | ||
|
|
||
| <service android:name="org.microg.gms.auth.workaccount.WorkAccountService" | ||
| android:exported="true"> | ||
| <intent-filter> | ||
| <action android:name="com.google.android.gms.auth.account.workaccount.START" /> | ||
| </intent-filter> | ||
| </service> | ||
|
|
||
| <service | ||
| android:name="com.google.android.gms.auth.account.authenticator.WorkAccountAuthenticatorService" | ||
| android:process=":persistent" | ||
| android:enabled="false" | ||
| android:exported="false"> | ||
|
|
||
| <intent-filter> | ||
| <action android:name="android.accounts.AccountAuthenticator"/> | ||
| </intent-filter> | ||
|
|
||
| <meta-data | ||
| android:name="android.accounts.AccountAuthenticator" | ||
| android:resource="@xml/auth_work_authenticator"/> | ||
|
|
||
| <meta-data | ||
| android:name="android.accounts.AccountAuthenticator.customTokens" | ||
| android:value="1"/> | ||
|
|
||
| </service> | ||
|
|
||
| </application> | ||
| </manifest> |
222 changes: 222 additions & 0 deletions
222
...main/kotlin/com/google/android/gms/auth/account/authenticator/WorkAccountAuthenticator.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,222 @@ | ||
| /* | ||
| * SPDX-FileCopyrightText: 2024 e foundation | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| package com.google.android.gms.auth.account.authenticator | ||
|
|
||
| import android.accounts.AbstractAccountAuthenticator | ||
| 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 | ||
| import com.google.android.gms.auth.workaccount.R | ||
| import org.microg.gms.auth.AuthConstants | ||
| import org.microg.gms.common.PackageUtils | ||
| import org.microg.gms.auth.AuthRequest | ||
| import org.microg.gms.auth.AuthResponse | ||
| import java.io.IOException | ||
|
|
||
| class WorkAccountAuthenticator(val context: Context) : AbstractAccountAuthenticator(context) { | ||
|
|
||
| override fun editProperties( | ||
| response: AccountAuthenticatorResponse, | ||
| accountType: String? | ||
| ): Bundle { | ||
| TODO("Not yet implemented: editProperties") | ||
| } | ||
|
|
||
| override fun addAccount( | ||
| response: AccountAuthenticatorResponse, | ||
| accountType: String, | ||
| authTokenType: String?, | ||
| requiredFeatures: Array<out String>?, | ||
| options: Bundle | ||
| ): Bundle? { | ||
| if ( | ||
| !options.containsKey(KEY_ACCOUNT_CREATION_TOKEN) | ||
| || options.getString(KEY_ACCOUNT_CREATION_TOKEN) == null | ||
| || options.getInt(AccountManager.KEY_CALLER_UID) != android.os.Process.myUid()) { | ||
| Log.e(TAG, | ||
| "refusing to add account without creation token or from external app: " + | ||
| "could have been manually initiated by user (not supported) " + | ||
| "or by unauthorized app (not allowed)" | ||
| ) | ||
|
|
||
| // TODO: The error message is not automatically displayed by the settings app as of now. | ||
| // We can consider showing the error message through a popup instead. | ||
|
|
||
| return Bundle().apply { | ||
| putInt(AccountManager.KEY_ERROR_CODE, AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION) | ||
| putString(AccountManager.KEY_ERROR_MESSAGE, context.getString(R.string.auth_work_authenticator_add_manual_error) | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| val oauthToken: String = options.getString(KEY_ACCOUNT_CREATION_TOKEN)!! | ||
|
|
||
| try { | ||
| val authResponse = AuthRequest().fromContext(context) | ||
| .appIsGms() | ||
| .callerIsGms() | ||
| .service("ac2dm") | ||
| .token(oauthToken).isAccessToken() | ||
| .addAccount() | ||
| .getAccountId() | ||
| .droidguardResults(null) | ||
| .response | ||
|
|
||
| val accountManager = AccountManager.get(context) | ||
| if (accountManager.addAccountExplicitly( | ||
| Account(authResponse.email, AuthConstants.WORK_ACCOUNT_TYPE), | ||
| authResponse.token, Bundle().apply { | ||
| // Work accounts have no SID / LSID ("BAD_COOKIE") and no first/last name. | ||
| if (authResponse.accountId.isNotBlank()) { | ||
| putString(KEY_GOOGLE_USER_ID, authResponse.accountId) | ||
| } | ||
| putString(AuthConstants.KEY_ACCOUNT_CAPABILITIES, authResponse.capabilities) | ||
| putString(AuthConstants.KEY_ACCOUNT_SERVICES, authResponse.services) | ||
| if (authResponse.services != "android") { | ||
| Log.i(TAG, "unexpected 'services' value ${authResponse.services} (usually '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) | ||
| putString(AccountManager.KEY_ACCOUNT_TYPE, AuthConstants.WORK_ACCOUNT_TYPE) | ||
| }) | ||
| } | ||
|
|
||
| } catch (exception: Exception) { | ||
| response.onResult(Bundle().apply { | ||
| putInt( | ||
| AccountManager.KEY_ERROR_CODE, | ||
| AccountManager.ERROR_CODE_NETWORK_ERROR | ||
| ) | ||
| putString(AccountManager.KEY_ERROR_MESSAGE, exception.message) | ||
| }) | ||
| } | ||
|
|
||
| /* Note: as is not documented, `null` must only be returned after `response.onResult` was | ||
| * already called, hence forcing the requests to be synchronous. They are still async to | ||
| * the caller's main thread because AccountManager forces potentially blocking operations, | ||
| * like waiting for a response upon `addAccount`, not to be on the main thread. | ||
| */ | ||
| return null | ||
| } | ||
|
|
||
| override fun confirmCredentials( | ||
| response: AccountAuthenticatorResponse?, | ||
| account: Account?, | ||
| options: Bundle? | ||
| ): Bundle { | ||
| return Bundle().apply { | ||
| putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true) | ||
| } | ||
| } | ||
|
|
||
| override fun getAuthToken( | ||
| response: AccountAuthenticatorResponse?, | ||
| account: Account, | ||
| authTokenType: String?, | ||
| options: Bundle? | ||
| ): Bundle { | ||
| try { | ||
| val authResponse: AuthResponse = | ||
| AuthRequest().fromContext(context) | ||
| .source("android") | ||
| .app( | ||
| context.packageName, | ||
| PackageUtils.firstSignatureDigest(context, context.packageName) | ||
| ) | ||
| .email(account.name) | ||
| .token(AccountManager.get(context).getPassword(account)) | ||
| .service(authTokenType) | ||
| .delegation(0, null) | ||
| // .oauth2Foreground(oauth2Foreground) | ||
| // .oauth2Prompt(oauth2Prompt) | ||
| // .oauth2IncludeProfile(includeProfile) | ||
| // .oauth2IncludeEmail(includeEmail) | ||
| // .itCaveatTypes(itCaveatTypes) | ||
| // .tokenRequestOptions(tokenRequestOptions) | ||
| .systemPartition(true) | ||
| .hasPermission(true) | ||
| // .putDynamicFiledMap(dynamicFields) | ||
| .appIsGms() | ||
| .callerIsApp() | ||
| .response | ||
|
|
||
| return Bundle().apply { | ||
| putString(AccountManager.KEY_ACCOUNT_NAME, account.name) | ||
| putString(AccountManager.KEY_ACCOUNT_TYPE, account.type) | ||
| putString(AccountManager.KEY_AUTHTOKEN, authResponse.auth) | ||
| } | ||
| } catch (e: IOException) { | ||
| return Bundle().apply { | ||
| putInt(AccountManager.KEY_ERROR_CODE, AccountManager.ERROR_CODE_NETWORK_ERROR) | ||
| putString(AccountManager.KEY_ERROR_MESSAGE, e.message) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| override fun getAuthTokenLabel(authTokenType: String?): String { | ||
| TODO("Not yet implemented: getAuthTokenLabel") | ||
| } | ||
|
|
||
| override fun updateCredentials( | ||
| response: AccountAuthenticatorResponse?, | ||
| account: Account?, | ||
| authTokenType: String?, | ||
| options: Bundle? | ||
| ): Bundle { | ||
| TODO("Not yet implemented: updateCredentials") | ||
| } | ||
|
|
||
| override fun hasFeatures( | ||
| response: AccountAuthenticatorResponse?, | ||
| account: Account?, | ||
| features: Array<out String> | ||
| ): Bundle { | ||
| Log.i(TAG, "Queried features: " + features.joinToString(", ")) | ||
| return Bundle().apply { | ||
| putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false) | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Prevent accidental deletion, unlike GMS. The account can only be removed through client apps; | ||
| * ideally, it would only be removed by the app that requested it to be created / the DPC | ||
| * manager, though this is not enforced. On API 21, the account can also be removed by hand | ||
| * because `removeAccountExplicitly` is not available on API 21. | ||
| */ | ||
| override fun getAccountRemovalAllowed( | ||
| response: AccountAuthenticatorResponse?, | ||
| account: Account? | ||
| ): Bundle { | ||
| return Bundle().apply { | ||
| putBoolean(AccountManager.KEY_BOOLEAN_RESULT, | ||
| Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1 | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| companion object { | ||
| const val TAG = "WorkAccAuthenticator" | ||
|
|
||
| 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 = AuthConstants.GOOGLE_USER_ID | ||
| } | ||
| } | ||
22 changes: 22 additions & 0 deletions
22
...tlin/com/google/android/gms/auth/account/authenticator/WorkAccountAuthenticatorService.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| /* | ||
| * SPDX-FileCopyrightText: 2024 e foundation | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| package com.google.android.gms.auth.account.authenticator | ||
|
|
||
| import android.accounts.AccountManager | ||
| import android.app.Service | ||
| import android.content.Intent | ||
| import android.os.IBinder | ||
|
|
||
| class WorkAccountAuthenticatorService : Service() { | ||
| private val authenticator by lazy { WorkAccountAuthenticator(this) } | ||
|
|
||
| override fun onBind(intent: Intent): IBinder? { | ||
| if (intent.action == AccountManager.ACTION_AUTHENTICATOR_INTENT) { | ||
| return authenticator.iBinder | ||
| } | ||
| return null | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.