Skip to content

Commit

Permalink
Merge branch 'microg:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
ysfchn authored Aug 8, 2024
2 parents 076143c + 75a23ed commit ceb6d45
Show file tree
Hide file tree
Showing 16 changed files with 303 additions and 63 deletions.
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
microG Services
=======
# microG Services

[![Build status](https://github.com/microg/GmsCore/actions/workflows/build.yml/badge.svg)](https://github.com/microg/GmsCore/actions/workflows/build.yml)
<a href=TRANSLATION.md>
<img src="https://hosted.weblate.org/widget/microg/svg-badge.svg" alt="Translation status" />
</a>

microG Services is a FLOSS (Free/Libre Open Source Software) framework to allow applications designed for Google Play Services to run on systems, where Play Services is not available.

### Please refer to the [wiki](https://github.com/microg/GmsCore/wiki) for downloads and instructions

## Translations

If you'd like to help translate microG, take a look at [TRANSLATION](TRANSLATION.md).


License
-------
Expand Down
9 changes: 9 additions & 0 deletions TRANSLATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# How to translate microG

microG can be translated using Weblate. The microG project is hosted at https://hosted.weblate.org/projects/microg/.

> At the moment, [microG-UI-tools](play-services-core/microg-ui-tools), an internal component, is not available for translation using Weblate. You may want to open a PR for this. This component hosts strings for the "Self-Check" menu and a few other things.
Preferably do not open a PR for components that can be translated with Weblate. Otherwise, merge conflicts can happen. If you already made a PR, you can try [importing](https://docs.weblate.org/en/latest/user/files.html#uploading-translations) the files manually into Weblate for each component.

If your language is not available for translation from a quick look, you may need to first create an account, set your language in your settings, check the project again, and then you should be able to add it.
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@

public class CallerInfo extends AutoSafeParcelable {
@Field(1)
public String s1;
public String source;
@Field(2)
public String s2;
public String medium;
@Field(3)
public String s3;
public String campaign;
@Field(4)
public String s4;
public String content;

@NonNull
@Override
public String toString() {
return "CallerInfo(" + s1 + "," + s2 + "," + s3 + "," + s4 + ")";
return "CallerInfo(" + source + "," + medium + "," + campaign + "," + content + ")";
}

public static final Creator<CallerInfo> CREATOR = new AutoCreator<>(CallerInfo.class);
Expand Down
7 changes: 7 additions & 0 deletions play-services-core/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -885,6 +885,13 @@
android:excludeFromRecents="true"
android:theme="@style/Theme.App.Translucent"/>

<activity
android:name="com.google.android.gms.credential.manager.PasswordManagerActivity"
android:exported="true"
android:process=":ui"
android:excludeFromRecents="true"
android:theme="@style/Theme.Translucent"/>

<service android:name="org.microg.gms.clearcut.ClearcutLoggerService">
<intent-filter>
<action android:name="com.google.android.gms.clearcut.service.START" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.google.android.gms.credential.manager

import android.accounts.AccountManager
import android.os.Bundle
import android.util.Log
import android.view.View
import android.webkit.WebView
import android.widget.ProgressBar
import android.widget.RelativeLayout
import androidx.appcompat.app.AppCompatActivity
import org.microg.gms.accountsettings.ui.WebViewHelper
import org.microg.gms.auth.AuthConstants

const val PASSWORD_MANAGER_CLASS_NAME = "com.google.android.gms.credential.manager.PasswordManagerActivity"

const val EXTRA_KEY_ACCOUNT_NAME = "pwm.DataFieldNames.accountName"

private const val TAG = "PasswordManagerActivity"

private const val PSW_MANAGER_PATH = "https://passwords.google.com/"

class PasswordManagerActivity : AppCompatActivity() {

private lateinit var webView: WebView

private val accountName: String?
get() = runCatching { intent?.getStringExtra(EXTRA_KEY_ACCOUNT_NAME) }.getOrNull()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d(TAG, "onCreate: start")

val accounts = AccountManager.get(this).getAccountsByType(AuthConstants.DEFAULT_ACCOUNT_TYPE)
val realAccountName = accounts.find { it.name.equals(accountName) }?.name

Log.d(TAG, "realAccountName: $realAccountName")

val layout = RelativeLayout(this)
layout.addView(ProgressBar(this).apply {
layoutParams = RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT).apply {
addRule(RelativeLayout.CENTER_HORIZONTAL)
addRule(RelativeLayout.CENTER_VERTICAL)
}
isIndeterminate = true
})
webView = WebView(this).apply {
layoutParams = RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT)
visibility = View.INVISIBLE
}
layout.addView(webView)
setContentView(layout)
WebViewHelper(this, webView).openWebView(PSW_MANAGER_PATH, realAccountName)
}

override fun onBackPressed() {
if (this::webView.isInitialized && webView.canGoBack()) {
webView.goBack()
} else {
super.onBackPressed()
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ private val SCREEN_ID_TO_URL = hashMapOf(
235 to "https://myactivity.google.com/activitycontrols/youtube",
238 to "https://www.google.com/setting/search/privateresults/",
241 to "https://myaccount.google.com/communication-preferences",
242 to "https://myadcenter.google.com/controls",
300 to "https://myaccount.google.com/language",
301 to "https://drive.google.com/settings/storage",
302 to "https://myaccount.google.com/deleteservices",
Expand Down Expand Up @@ -108,7 +109,8 @@ private val ALLOWED_WEB_PREFIXES = setOf(
"https://payments.google.com/",
"https://policies.google.com/",
"https://fit.google.com/privacy/settings",
"https://maps.google.com/maps/timeline"
"https://maps.google.com/maps/timeline",
"https://myadcenter.google.com/controls"
)

private val ACTION_TO_SCREEN_ID = hashMapOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,17 @@ class AssistedSignInFragment(
private fun filterAccountsLogin(multiMethod: (List<Account>) -> Unit, loginMethod: (Account, Boolean) -> Unit) {
lifecycleScope.launch {
val allowAutoLoginAccounts = mutableListOf<Account>()
accounts.forEach { account ->
val authStatus = checkAppAuthStatus(requireContext(), clientPackageName, options, account)
if (authStatus) {
allowAutoLoginAccounts.add(account)
runCatching {
accounts.forEach { account ->
val authStatus = checkAppAuthStatus(requireContext(), clientPackageName, options, account)
if (authStatus) {
allowAutoLoginAccounts.add(account)
}
}
}.onFailure {
Log.d(TAG, "filterAccountsLogin: error", it)
errorBlock(Status(CommonStatusCodes.INTERNAL_ERROR, "auth error"))
return@launch
}
if (accounts.size == 1) {
loginMethod(accounts.first(), allowAutoLoginAccounts.isNotEmpty())
Expand Down Expand Up @@ -255,15 +261,20 @@ class AssistedSignInFragment(
lastChooseAccountPermitted = permitted
isSigningIn = true
delay(3000)
val googleSignInAccount = withContext(Dispatchers.IO) {
performSignIn(requireContext(), clientPackageName, options, account, permitted)
}
if (googleSignInAccount == null) {
isSigningIn = false
prepareChooseLogin(account, showConsent = true, permitted = true)
return@launch
runCatching {
val googleSignInAccount = withContext(Dispatchers.IO) {
performSignIn(requireContext(), clientPackageName, options, account, permitted)
}
if (googleSignInAccount == null) {
isSigningIn = false
prepareChooseLogin(account, showConsent = true, permitted = true)
return@launch
}
loginBlock(googleSignInAccount)
}.onFailure {
Log.d(TAG, "startLogin: error", it)
errorBlock(Status(CommonStatusCodes.INTERNAL_ERROR, "signIn error"))
}
loginBlock(googleSignInAccount)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@

package org.microg.gms.credential

import android.app.PendingIntent
import android.content.Context
import android.os.Bundle
import android.content.Intent
import android.os.Parcel
import android.util.Base64
import android.util.Log
Expand All @@ -20,11 +21,14 @@ import com.google.android.gms.common.api.internal.IStatusCallback
import com.google.android.gms.common.internal.ConnectionInfo
import com.google.android.gms.common.internal.GetServiceRequest
import com.google.android.gms.common.internal.IGmsCallbacks
import com.google.android.gms.credential.manager.EXTRA_KEY_ACCOUNT_NAME
import com.google.android.gms.credential.manager.PASSWORD_MANAGER_CLASS_NAME
import com.google.android.gms.credential.manager.common.IPendingIntentCallback
import com.google.android.gms.credential.manager.common.ISettingsCallback
import com.google.android.gms.credential.manager.firstparty.internal.ICredentialManagerService
import com.google.android.gms.credential.manager.invocationparams.CredentialManagerInvocationParams
import org.microg.gms.BaseService
import org.microg.gms.common.Constants
import org.microg.gms.common.GmsService
import org.microg.gms.common.GooglePackagePermission
import org.microg.gms.common.PackageUtils
Expand Down Expand Up @@ -53,13 +57,20 @@ class CredentialManagerService : BaseService(TAG, GmsService.CREDENTIAL_MANAGER)

private class CredentialManagerServiceImpl(private val context: Context, override val lifecycle: Lifecycle) : ICredentialManagerService.Stub(), LifecycleOwner {

override fun getCredentialManagerIntent(callback: IPendingIntentCallback?, params: CredentialManagerInvocationParams?) {
Log.d(TAG, "Not yet implemented: getCredentialManagerIntent $params")
override fun getCredentialManagerIntent(callback: IPendingIntentCallback?, params: CredentialManagerInvocationParams) {
Log.d(TAG, "Method getCredentialManagerIntent $params called")
lifecycleScope.launchWhenStarted {
try {
runCatching {
val intent = Intent().apply {
setClassName(Constants.GMS_PACKAGE_NAME, PASSWORD_MANAGER_CLASS_NAME)
putExtra(EXTRA_KEY_ACCOUNT_NAME, params.account.name)
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
callback?.onPendingIntent(Status.SUCCESS, pendingIntent)
}.onFailure {
Log.d(TAG, "getCredentialManagerIntent error", it)
callback?.onPendingIntent(Status.INTERNAL_ERROR, null)
} catch (e: Exception) {
Log.w(TAG, e)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ package org.microg.gms.languageprofile

import android.os.Bundle
import android.util.Log
import com.google.android.gms.common.Feature
import com.google.android.gms.common.api.CommonStatusCodes
import com.google.android.gms.common.api.Status
import com.google.android.gms.common.api.internal.IStatusCallback
import com.google.android.gms.common.internal.ConnectionInfo
import com.google.android.gms.common.internal.GetServiceRequest
import com.google.android.gms.common.internal.IGmsCallbacks
import com.google.android.gms.languageprofile.ClientLanguageSettings
Expand All @@ -21,10 +23,17 @@ import org.microg.gms.BaseService
import org.microg.gms.common.GmsService

private const val TAG = "LanguageProfileService"
private val FEATURES = arrayOf(
Feature("get_application_locale_suggestions_api", 1L),
Feature("get_language_preferences_for_product_id_api", 1L),
Feature("set_language_settings_api", 1L),
)

class LanguageProfileService : BaseService(TAG, GmsService.LANGUAGE_PROFILE) {
override fun handleServiceRequest(callback: IGmsCallbacks, request: GetServiceRequest, service: GmsService) {
callback.onPostInitComplete(CommonStatusCodes.SUCCESS, LanguageProfileServiceImpl(), Bundle())
callback.onPostInitCompleteWithConnectionInfo(CommonStatusCodes.SUCCESS, LanguageProfileServiceImpl(), ConnectionInfo().apply {
features = FEATURES
})
}
}

Expand Down
15 changes: 15 additions & 0 deletions play-services-location/core/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,21 @@
</intent-filter>
</activity>

<activity
android:name="org.microg.gms.location.settings.GoogleLocationSettingsActivity"
android:excludeFromRecents="true"
android:exported="true"
android:launchMode="singleTask"
android:process=":ui"
android:theme="@style/Theme.App.Translucent">
<intent-filter>
<action android:name="com.google.android.location.settings.GOOGLE_LOCATION_SETTINGS" />
<action android:name="com.google.android.gms.location.settings.GOOGLE_LOCATION_SETTINGS" />

<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

<activity
android:name="org.microg.gms.location.manager.AskPermissionActivity"
android:excludeFromRecents="true"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/

package org.microg.gms.location.settings

import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

class GoogleLocationSettingsActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
runCatching { startActivity(Intent("android.settings.LOCATION_SOURCE_SETTINGS")) }
finish()
}
}
Loading

0 comments on commit ceb6d45

Please sign in to comment.