From ab9d19e242036f559daf9194b63e4e31f8f28023 Mon Sep 17 00:00:00 2001 From: MatheoLevallois Date: Tue, 25 Mar 2025 17:39:39 +0100 Subject: [PATCH 01/95] Add screen time setting in Paco's setup wizard --- .../e/parentalcontrol/MainActivity.kt | 32 +++- .../e/parentalcontrol/data/Pages.kt | 3 +- .../e/parentalcontrol/ui/buttons/Slider.kt | 33 ++++ .../ui/view/SelectAllowedScreenTime.kt | 175 ++++++++++++++++++ .../e/parentalcontrol/utils/Constants.kt | 1 + .../e/parentalcontrol/utils/PrefsUtils.kt | 4 + app/src/main/res/values/strings.xml | 13 ++ 7 files changed, 259 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/foundation/e/parentalcontrol/ui/buttons/Slider.kt create mode 100644 app/src/main/java/foundation/e/parentalcontrol/ui/view/SelectAllowedScreenTime.kt diff --git a/app/src/main/java/foundation/e/parentalcontrol/MainActivity.kt b/app/src/main/java/foundation/e/parentalcontrol/MainActivity.kt index 65b36cb..c3b22bb 100644 --- a/app/src/main/java/foundation/e/parentalcontrol/MainActivity.kt +++ b/app/src/main/java/foundation/e/parentalcontrol/MainActivity.kt @@ -103,6 +103,7 @@ import foundation.e.parentalcontrol.ui.view.AskPassword import foundation.e.parentalcontrol.ui.view.AuthenticationTypeSelectionView import foundation.e.parentalcontrol.ui.view.MainUI import foundation.e.parentalcontrol.ui.view.SelectAge +import foundation.e.parentalcontrol.ui.view.SelectAllowedScreenTime import foundation.e.parentalcontrol.ui.view.selectedAge import foundation.e.parentalcontrol.utils.Constants import foundation.e.parentalcontrol.utils.CryptUtils @@ -832,6 +833,32 @@ class MainActivity : ComponentActivity() { SelectAge( onRadioClick = {}, + onNextClick = { mainScreen(page = Pages.SelectAllowedScreenTime) } + ) + } + } + + @Composable + fun SelectAllowedScreenTimePage() { + fun onBackPress() { + mainScreen(page = Pages.SelectAge) + } + + BackHandler(onBack = { onBackPress() }) + + CustomTopAppBar( + title = stringResource(R.string.allowed_screen_time), + onClick = { onBackPress() } + ) + + Column( + modifier = + Modifier.fillMaxSize() + .padding(start = Dimens.SCREEN_PADDING, end = Dimens.SCREEN_PADDING), + horizontalAlignment = Alignment.Start, + verticalArrangement = Arrangement.Top + ) { + SelectAllowedScreenTime( onNextClick = { mainScreen(page = Pages.AuthenticationTypeSelectionView) } ) } @@ -903,7 +930,7 @@ class MainActivity : ComponentActivity() { if (isAdminActive()) { mainScreen(page = Pages.ActivateAdmin) } else { - mainScreen(page = Pages.SelectAge) + mainScreen(page = Pages.SelectAllowedScreenTime) } }, onSelection = { mainScreen(page = Pages.SetupPinPassword) } @@ -968,6 +995,9 @@ class MainActivity : ComponentActivity() { Pages.NotMainUser -> { NotMainUser() } + Pages.SelectAllowedScreenTime -> { + SelectAllowedScreenTimePage() + } } } } diff --git a/app/src/main/java/foundation/e/parentalcontrol/data/Pages.kt b/app/src/main/java/foundation/e/parentalcontrol/data/Pages.kt index 80a1116..9bd4733 100644 --- a/app/src/main/java/foundation/e/parentalcontrol/data/Pages.kt +++ b/app/src/main/java/foundation/e/parentalcontrol/data/Pages.kt @@ -29,5 +29,6 @@ enum class Pages { AskPasswordForAgeReset, AskPasswordForDebugMenu, SelectAge, - NotMainUser + NotMainUser, + SelectAllowedScreenTime } diff --git a/app/src/main/java/foundation/e/parentalcontrol/ui/buttons/Slider.kt b/app/src/main/java/foundation/e/parentalcontrol/ui/buttons/Slider.kt new file mode 100644 index 0000000..98556ee --- /dev/null +++ b/app/src/main/java/foundation/e/parentalcontrol/ui/buttons/Slider.kt @@ -0,0 +1,33 @@ +package foundation.e.parentalcontrol.ui.buttons + +import androidx.compose.foundation.layout.Column +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Slider +import androidx.compose.material3.SliderDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.getValue +import androidx.compose.runtime.setValue +import androidx.compose.runtime.remember + +@Composable +fun SliderWithStep( + steps: Int, + value: Float, + onValueChange: (Float) -> Unit +) { + var sliderPosition by remember { mutableStateOf(value) } + Column{ + Slider( + value = sliderPosition, + onValueChange = { sliderPosition = it; onValueChange(it)}, + colors = SliderDefaults.colors( + thumbColor = MaterialTheme.colorScheme.secondaryContainer, + activeTrackColor = MaterialTheme.colorScheme.secondaryContainer, + inactiveTrackColor = MaterialTheme.colorScheme.secondary, + ), + steps = steps, + valueRange = 0f..9f, + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/foundation/e/parentalcontrol/ui/view/SelectAllowedScreenTime.kt b/app/src/main/java/foundation/e/parentalcontrol/ui/view/SelectAllowedScreenTime.kt new file mode 100644 index 0000000..4d24d8c --- /dev/null +++ b/app/src/main/java/foundation/e/parentalcontrol/ui/view/SelectAllowedScreenTime.kt @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2024 MURENA SAS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package foundation.e.parentalcontrol.ui.view + +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Button +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.colorResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.withStyle +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import foundation.e.parentalcontrol.DeviceAdmin +import foundation.e.parentalcontrol.R +import foundation.e.parentalcontrol.ui.buttons.SliderWithStep +import foundation.e.parentalcontrol.ui.buttons.buttonColor +import foundation.e.parentalcontrol.utils.Dimens +import foundation.e.parentalcontrol.utils.PrefsUtils + + +var selectedAllowedScreenTime: Int by mutableStateOf(0) + + +@Composable +fun SelectAllowedScreenTime(onNextClick: () -> Unit) { + val context = LocalContext.current + + + if (DeviceAdmin().isAdminActive(context)) { + selectedAllowedScreenTime = PrefsUtils.getAllowedScreenTime() + } + + + Text( + text = stringResource(R.string.activate_screen_time_limitation), + color = colorResource(foundation.e.elib.R.color.e_primary_text_color), + fontWeight = FontWeight.Bold, + modifier = + Modifier.padding(top = Dimens.SCREEN_PADDING / 2, bottom = Dimens.SCREEN_PADDING / 2) + ) + + Column( + modifier = + Modifier.padding(start = Dimens.SCREEN_PADDING / 2, end = Dimens.SCREEN_PADDING / 2), + ) { + SliderWithStep( + 8, + selectedAllowedScreenTime.toFloat(), + onValueChange = {selectedAllowedScreenTime = it.toInt()}) + + + Text( + text = stringResource(R.string.recommendations), + fontWeight = FontWeight.Bold, + modifier = Modifier.padding(bottom = Dimens.SCREEN_PADDING) + ) + Box( + modifier = + Modifier + .clip(RoundedCornerShape(16.dp)) + .border(0.5.dp, Color.LightGray, RoundedCornerShape(16.dp)) + .padding(16.dp) + + ){ + Column( + ) { + Text( + text = buildAnnotatedString { + withStyle(style = SpanStyle(fontWeight = FontWeight.Bold, color = Color.Black)) { + append(stringResource(R.string.screen_time_limit_0_3_years_text) + " ") + } + withStyle(style = SpanStyle(color = Color.Gray)) { + append(stringResource(R.string.screen_time_limit_recommendations_0_3_years_text)) + } + }, + style = TextStyle(fontSize = 14.sp) + ) + Text( + text = buildAnnotatedString { + withStyle(style = SpanStyle(fontWeight = FontWeight.Bold, color = Color.Black)) { + append(stringResource(R.string.screen_time_limit_4_6_years_text) + " ") + } + withStyle(style = SpanStyle(color = Color.Gray)) { + append(stringResource(R.string.screen_time_limit_recommendations_4_6_years_text)) + } + }, + style = TextStyle(fontSize = 14.sp) + + ) + Text( + text = buildAnnotatedString { + withStyle(style = SpanStyle(fontWeight = FontWeight.Bold, color = Color.Black)) { + append(stringResource(R.string.screen_time_limit_7_11_years_text) + " ") + } + withStyle(style = SpanStyle(color = Color.Gray)) { + append(stringResource(R.string.screen_time_limit_recommendations_7_11_years_text)) + } + }, + style = TextStyle(fontSize = 14.sp) + + ) + Text( + text = buildAnnotatedString { + withStyle(style = SpanStyle(fontWeight = FontWeight.Bold, color = Color.Black)) { + append(stringResource(R.string.screen_time_limit_12_15_years_text) + " ") + } + withStyle(style = SpanStyle(color = Color.Gray)) { + append(stringResource(R.string.screen_time_limit_recommendations_12_15_years_text)) + } + }, + style = TextStyle(fontSize = 14.sp) + + ) + Text( + text = buildAnnotatedString { + withStyle(style = SpanStyle(fontWeight = FontWeight.Bold, color = Color.Black)) { + append(stringResource(R.string.screen_time_limit_16_17_years_text) + " ") + } + withStyle(style = SpanStyle(color = Color.Gray)) { + append(stringResource(R.string.screen_time_limit_recommendations_16_17_years_text)) + } + }, + style = TextStyle(fontSize = 14.sp) + + ) + } + } + } + if (!DeviceAdmin().isAdminActive(context)) { + Box( + modifier = Modifier.fillMaxSize().padding(top = Dimens.SCREEN_PADDING), + contentAlignment = Alignment.TopCenter, + ) { + Button( + onClick = { onNextClick() }, + colors = buttonColor(), + ) { + Text(stringResource(R.string.next)) + } + } + } +} diff --git a/app/src/main/java/foundation/e/parentalcontrol/utils/Constants.kt b/app/src/main/java/foundation/e/parentalcontrol/utils/Constants.kt index 4197c71..1b8c38f 100644 --- a/app/src/main/java/foundation/e/parentalcontrol/utils/Constants.kt +++ b/app/src/main/java/foundation/e/parentalcontrol/utils/Constants.kt @@ -23,6 +23,7 @@ object Constants { const val PREF_PASSWORD_SET = "password_set" const val PREF_PASSWORD = "password" const val PREF_AGE = "age" + const val PREF_ALLOWED_SCREEN_TIME = "time_allowed_screen_time" const val PREF_DNS_HOST_MODE = "dns_host_mode" const val PREF_DNS_HOST_NAME = "dns_host_name" const val PREF_DEFAULT_DNS_HOST_NAME = "dns_default_host_name" diff --git a/app/src/main/java/foundation/e/parentalcontrol/utils/PrefsUtils.kt b/app/src/main/java/foundation/e/parentalcontrol/utils/PrefsUtils.kt index a53ff8a..9db9107 100644 --- a/app/src/main/java/foundation/e/parentalcontrol/utils/PrefsUtils.kt +++ b/app/src/main/java/foundation/e/parentalcontrol/utils/PrefsUtils.kt @@ -61,6 +61,10 @@ object PrefsUtils { return Ages.entries[ordinal] } + fun getAllowedScreenTime(): Int { + return sharedPreferences.getInt(Constants.PREF_ALLOWED_SCREEN_TIME, 24) + } + fun clearAll() { sharedPreferences.edit().clear().apply() } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b683c6b..40a0345 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -48,4 +48,17 @@ "Security > Device admin apps" Open settings Link copied to clipboard + Set the number of hours that your child is allowed to use this device daily + Avoid screens for under 2, except live video calls. Very limited, supervised use if older toddlers watch.\n + Limit to about 1 hour of quality, age-appropriate content.\n + Aim for 1–2 hours of recreational screen time daily.\n + Target up to 2 hours of recreational screen time, with flexibility for homework.\n + About 2–3 hours of recreational screen time, focusing on healthy digital habits. + Recommendations: + • 0–3 years: + • 4–6 years: + • 7–11 years: + • 12–15 years: + • 16–17 years: + Allowed screen time \ No newline at end of file -- GitLab From 881382f2c4dc83d367e346830e0b8c9ea73fe2e3 Mon Sep 17 00:00:00 2001 From: MatheoLevallois Date: Wed, 26 Mar 2025 09:58:12 +0100 Subject: [PATCH 02/95] fix linter --- .../main/java/foundation/e/parentalcontrol/ui/buttons/Slider.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/foundation/e/parentalcontrol/ui/buttons/Slider.kt b/app/src/main/java/foundation/e/parentalcontrol/ui/buttons/Slider.kt index 98556ee..b7a2748 100644 --- a/app/src/main/java/foundation/e/parentalcontrol/ui/buttons/Slider.kt +++ b/app/src/main/java/foundation/e/parentalcontrol/ui/buttons/Slider.kt @@ -30,4 +30,4 @@ fun SliderWithStep( valueRange = 0f..9f, ) } -} \ No newline at end of file +} -- GitLab From df18d24116677c51581971924ed82616fe31c13f Mon Sep 17 00:00:00 2001 From: MatheoLevallois Date: Wed, 26 Mar 2025 14:00:07 +0100 Subject: [PATCH 03/95] fix build problem --- .../e/parentalcontrol/MainActivity.kt | 9 ++ .../e/parentalcontrol/ui/buttons/Slider.kt | 45 ++++-- .../ui/view/SelectAllowedScreenTime.kt | 148 +++++++++++------- 3 files changed, 132 insertions(+), 70 deletions(-) diff --git a/app/src/main/java/foundation/e/parentalcontrol/MainActivity.kt b/app/src/main/java/foundation/e/parentalcontrol/MainActivity.kt index c3b22bb..c75732a 100644 --- a/app/src/main/java/foundation/e/parentalcontrol/MainActivity.kt +++ b/app/src/main/java/foundation/e/parentalcontrol/MainActivity.kt @@ -105,6 +105,7 @@ import foundation.e.parentalcontrol.ui.view.MainUI import foundation.e.parentalcontrol.ui.view.SelectAge import foundation.e.parentalcontrol.ui.view.SelectAllowedScreenTime import foundation.e.parentalcontrol.ui.view.selectedAge +import foundation.e.parentalcontrol.ui.view.selectedAllowedScreenTime import foundation.e.parentalcontrol.utils.Constants import foundation.e.parentalcontrol.utils.CryptUtils import foundation.e.parentalcontrol.utils.Dimens @@ -333,6 +334,7 @@ class MainActivity : ComponentActivity() { confirmPassText = "" onSetAge() + onSetAllowedScreenTime() if (!isAdminActive()) { setAdmin(true) @@ -864,6 +866,13 @@ class MainActivity : ComponentActivity() { } } + private fun onSetAllowedScreenTime() { + with(PrefsUtils.getEdit()) { + putInt(Constants.PREF_ALLOWED_SCREEN_TIME, selectedAllowedScreenTime) + apply() + } + } + @Composable fun NotMainUser() { BackHandler(onBack = { onExitApp() }) diff --git a/app/src/main/java/foundation/e/parentalcontrol/ui/buttons/Slider.kt b/app/src/main/java/foundation/e/parentalcontrol/ui/buttons/Slider.kt index b7a2748..ec648c4 100644 --- a/app/src/main/java/foundation/e/parentalcontrol/ui/buttons/Slider.kt +++ b/app/src/main/java/foundation/e/parentalcontrol/ui/buttons/Slider.kt @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2024 MURENA SAS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ package foundation.e.parentalcontrol.ui.buttons import androidx.compose.foundation.layout.Column @@ -5,27 +22,27 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Slider import androidx.compose.material3.SliderDefaults import androidx.compose.runtime.Composable -import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.getValue -import androidx.compose.runtime.setValue +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue @Composable -fun SliderWithStep( - steps: Int, - value: Float, - onValueChange: (Float) -> Unit -) { +fun SliderWithStep(steps: Int, value: Float, onValueChange: (Float) -> Unit) { var sliderPosition by remember { mutableStateOf(value) } - Column{ + Column { Slider( value = sliderPosition, - onValueChange = { sliderPosition = it; onValueChange(it)}, - colors = SliderDefaults.colors( - thumbColor = MaterialTheme.colorScheme.secondaryContainer, - activeTrackColor = MaterialTheme.colorScheme.secondaryContainer, - inactiveTrackColor = MaterialTheme.colorScheme.secondary, - ), + onValueChange = { + sliderPosition = it + onValueChange(it) + }, + colors = + SliderDefaults.colors( + thumbColor = MaterialTheme.colorScheme.secondaryContainer, + activeTrackColor = MaterialTheme.colorScheme.secondaryContainer, + inactiveTrackColor = MaterialTheme.colorScheme.secondary, + ), steps = steps, valueRange = 0f..9f, ) diff --git a/app/src/main/java/foundation/e/parentalcontrol/ui/view/SelectAllowedScreenTime.kt b/app/src/main/java/foundation/e/parentalcontrol/ui/view/SelectAllowedScreenTime.kt index 4d24d8c..7cc6641 100644 --- a/app/src/main/java/foundation/e/parentalcontrol/ui/view/SelectAllowedScreenTime.kt +++ b/app/src/main/java/foundation/e/parentalcontrol/ui/view/SelectAllowedScreenTime.kt @@ -50,20 +50,16 @@ import foundation.e.parentalcontrol.ui.buttons.buttonColor import foundation.e.parentalcontrol.utils.Dimens import foundation.e.parentalcontrol.utils.PrefsUtils - var selectedAllowedScreenTime: Int by mutableStateOf(0) - @Composable fun SelectAllowedScreenTime(onNextClick: () -> Unit) { val context = LocalContext.current - if (DeviceAdmin().isAdminActive(context)) { selectedAllowedScreenTime = PrefsUtils.getAllowedScreenTime() } - Text( text = stringResource(R.string.activate_screen_time_limitation), color = colorResource(foundation.e.elib.R.color.e_primary_text_color), @@ -79,8 +75,8 @@ fun SelectAllowedScreenTime(onNextClick: () -> Unit) { SliderWithStep( 8, selectedAllowedScreenTime.toFloat(), - onValueChange = {selectedAllowedScreenTime = it.toInt()}) - + onValueChange = { selectedAllowedScreenTime = it.toInt() } + ) Text( text = stringResource(R.string.recommendations), @@ -89,72 +85,112 @@ fun SelectAllowedScreenTime(onNextClick: () -> Unit) { ) Box( modifier = - Modifier - .clip(RoundedCornerShape(16.dp)) + Modifier.clip(RoundedCornerShape(16.dp)) .border(0.5.dp, Color.LightGray, RoundedCornerShape(16.dp)) .padding(16.dp) - - ){ - Column( - ) { + ) { + Column() { Text( - text = buildAnnotatedString { - withStyle(style = SpanStyle(fontWeight = FontWeight.Bold, color = Color.Black)) { - append(stringResource(R.string.screen_time_limit_0_3_years_text) + " ") - } - withStyle(style = SpanStyle(color = Color.Gray)) { - append(stringResource(R.string.screen_time_limit_recommendations_0_3_years_text)) - } - }, + text = + buildAnnotatedString { + withStyle( + style = SpanStyle(fontWeight = FontWeight.Bold, color = Color.Black) + ) { + append( + stringResource(R.string.screen_time_limit_0_3_years_text) + " " + ) + } + withStyle(style = SpanStyle(color = Color.Gray)) { + append( + stringResource( + R.string.screen_time_limit_recommendations_0_3_years_text + ) + ) + } + }, style = TextStyle(fontSize = 14.sp) ) Text( - text = buildAnnotatedString { - withStyle(style = SpanStyle(fontWeight = FontWeight.Bold, color = Color.Black)) { - append(stringResource(R.string.screen_time_limit_4_6_years_text) + " ") - } - withStyle(style = SpanStyle(color = Color.Gray)) { - append(stringResource(R.string.screen_time_limit_recommendations_4_6_years_text)) - } - }, + text = + buildAnnotatedString { + withStyle( + style = SpanStyle(fontWeight = FontWeight.Bold, color = Color.Black) + ) { + append( + stringResource(R.string.screen_time_limit_4_6_years_text) + " " + ) + } + withStyle(style = SpanStyle(color = Color.Gray)) { + append( + stringResource( + R.string.screen_time_limit_recommendations_4_6_years_text + ) + ) + } + }, style = TextStyle(fontSize = 14.sp) - ) Text( - text = buildAnnotatedString { - withStyle(style = SpanStyle(fontWeight = FontWeight.Bold, color = Color.Black)) { - append(stringResource(R.string.screen_time_limit_7_11_years_text) + " ") - } - withStyle(style = SpanStyle(color = Color.Gray)) { - append(stringResource(R.string.screen_time_limit_recommendations_7_11_years_text)) - } - }, + text = + buildAnnotatedString { + withStyle( + style = SpanStyle(fontWeight = FontWeight.Bold, color = Color.Black) + ) { + append( + stringResource(R.string.screen_time_limit_7_11_years_text) + " " + ) + } + withStyle(style = SpanStyle(color = Color.Gray)) { + append( + stringResource( + R.string.screen_time_limit_recommendations_7_11_years_text + ) + ) + } + }, style = TextStyle(fontSize = 14.sp) - ) Text( - text = buildAnnotatedString { - withStyle(style = SpanStyle(fontWeight = FontWeight.Bold, color = Color.Black)) { - append(stringResource(R.string.screen_time_limit_12_15_years_text) + " ") - } - withStyle(style = SpanStyle(color = Color.Gray)) { - append(stringResource(R.string.screen_time_limit_recommendations_12_15_years_text)) - } - }, + text = + buildAnnotatedString { + withStyle( + style = SpanStyle(fontWeight = FontWeight.Bold, color = Color.Black) + ) { + append( + stringResource(R.string.screen_time_limit_12_15_years_text) + + " " + ) + } + withStyle(style = SpanStyle(color = Color.Gray)) { + append( + stringResource( + R.string.screen_time_limit_recommendations_12_15_years_text + ) + ) + } + }, style = TextStyle(fontSize = 14.sp) - ) Text( - text = buildAnnotatedString { - withStyle(style = SpanStyle(fontWeight = FontWeight.Bold, color = Color.Black)) { - append(stringResource(R.string.screen_time_limit_16_17_years_text) + " ") - } - withStyle(style = SpanStyle(color = Color.Gray)) { - append(stringResource(R.string.screen_time_limit_recommendations_16_17_years_text)) - } - }, + text = + buildAnnotatedString { + withStyle( + style = SpanStyle(fontWeight = FontWeight.Bold, color = Color.Black) + ) { + append( + stringResource(R.string.screen_time_limit_16_17_years_text) + + " " + ) + } + withStyle(style = SpanStyle(color = Color.Gray)) { + append( + stringResource( + R.string.screen_time_limit_recommendations_16_17_years_text + ) + ) + } + }, style = TextStyle(fontSize = 14.sp) - ) } } -- GitLab From 1d673268ef47cd101341e76a3c7718fed48624c2 Mon Sep 17 00:00:00 2001 From: MatheoLevallois Date: Wed, 26 Mar 2025 15:06:37 +0100 Subject: [PATCH 04/95] fix build problem --- .../e/parentalcontrol/OverlayService.kt | 72 +++++++++++++++++++ .../main/res/drawable/rounded_background.xml | 5 ++ app/src/main/res/layout/overlay_popup.xml | 23 ++++++ 3 files changed, 100 insertions(+) create mode 100644 app/src/main/java/foundation/e/parentalcontrol/OverlayService.kt create mode 100644 app/src/main/res/drawable/rounded_background.xml create mode 100644 app/src/main/res/layout/overlay_popup.xml diff --git a/app/src/main/java/foundation/e/parentalcontrol/OverlayService.kt b/app/src/main/java/foundation/e/parentalcontrol/OverlayService.kt new file mode 100644 index 0000000..ce00ac5 --- /dev/null +++ b/app/src/main/java/foundation/e/parentalcontrol/OverlayService.kt @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2024 MURENA SAS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package foundation.e.parentalcontrol + +import android.app.Service +import android.content.Intent +import android.graphics.PixelFormat +import android.os.IBinder +import android.util.Log +import android.view.Gravity +import android.view.LayoutInflater +import android.view.View +import android.view.WindowManager +import android.widget.Button + +class OverlayService : Service() { + + private lateinit var windowManager: WindowManager + private lateinit var overlayView: View + + override fun onCreate() { + super.onCreate() + Log.d("popup", "in create") + windowManager = getSystemService(WINDOW_SERVICE) as WindowManager + + val inflater = getSystemService(LAYOUT_INFLATER_SERVICE) as LayoutInflater + overlayView = inflater.inflate(R.layout.overlay_popup, null) + + val params = + WindowManager.LayoutParams( + WindowManager.LayoutParams.WRAP_CONTENT, + WindowManager.LayoutParams.WRAP_CONTENT, + WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, + WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or + WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, + PixelFormat.TRANSLUCENT + ) + + params.gravity = Gravity.CENTER + + windowManager.addView(overlayView, params) + + val closeButton = overlayView.findViewById