From 69c3c8136fb66eebffd852816d822903e032703b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 16 Mar 2023 18:12:54 +0100 Subject: [PATCH] Add `:services:toolbox` modules. --- .../kotlin/extension/DependencyHandleScope.kt | 3 +- services/toolbox/api/build.gradle.kts | 27 +++++++++ .../toolbox/api/appname/AppNameProvider.kt | 21 +++++++ .../toolbox/api/strings/StringProvider.kt | 46 ++++++++++++++ .../toolbox/api/systemclock/SystemClock.kt | 21 +++++++ services/toolbox/impl/build.gradle.kts | 36 +++++++++++ .../impl/appname/DefaultAppNameProvider.kt | 47 +++++++++++++++ .../toolbox/impl/strings/StringProvider.kt | 60 +++++++++++++++++++ .../impl/systemclock/DefaultSystemClock.kt | 36 +++++++++++ settings.gradle.kts | 2 + 10 files changed, 298 insertions(+), 1 deletion(-) create mode 100644 services/toolbox/api/build.gradle.kts create mode 100644 services/toolbox/api/src/main/kotlin/io/element/android/services/toolbox/api/appname/AppNameProvider.kt create mode 100644 services/toolbox/api/src/main/kotlin/io/element/android/services/toolbox/api/strings/StringProvider.kt create mode 100644 services/toolbox/api/src/main/kotlin/io/element/android/services/toolbox/api/systemclock/SystemClock.kt create mode 100644 services/toolbox/impl/build.gradle.kts create mode 100644 services/toolbox/impl/src/main/kotlin/io/element/android/services/toolbox/impl/appname/DefaultAppNameProvider.kt create mode 100644 services/toolbox/impl/src/main/kotlin/io/element/android/services/toolbox/impl/strings/StringProvider.kt create mode 100644 services/toolbox/impl/src/main/kotlin/io/element/android/services/toolbox/impl/systemclock/DefaultSystemClock.kt diff --git a/plugins/src/main/kotlin/extension/DependencyHandleScope.kt b/plugins/src/main/kotlin/extension/DependencyHandleScope.kt index 1474ab72d2..c54adc8492 100644 --- a/plugins/src/main/kotlin/extension/DependencyHandleScope.kt +++ b/plugins/src/main/kotlin/extension/DependencyHandleScope.kt @@ -65,8 +65,9 @@ fun DependencyHandlerScope.allLibrariesImpl() { } fun DependencyHandlerScope.allServicesImpl() { - implementation(project(":services:appnavstate:impl")) implementation(project(":services:analytics:noop")) + implementation(project(":services:appnavstate:impl")) + implementation(project(":services:toolbox:impl")) } fun DependencyHandlerScope.allFeaturesApi() { diff --git a/services/toolbox/api/build.gradle.kts b/services/toolbox/api/build.gradle.kts new file mode 100644 index 0000000000..bb748f7ca2 --- /dev/null +++ b/services/toolbox/api/build.gradle.kts @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + id("io.element.android-library") +} + +android { + namespace = "io.element.android.services.toolbox.api" +} + +dependencies { + implementation(libs.androidx.corektx) +} diff --git a/services/toolbox/api/src/main/kotlin/io/element/android/services/toolbox/api/appname/AppNameProvider.kt b/services/toolbox/api/src/main/kotlin/io/element/android/services/toolbox/api/appname/AppNameProvider.kt new file mode 100644 index 0000000000..414c9b632e --- /dev/null +++ b/services/toolbox/api/src/main/kotlin/io/element/android/services/toolbox/api/appname/AppNameProvider.kt @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.services.toolbox.api.appname + +interface AppNameProvider { + fun getAppName(): String +} diff --git a/services/toolbox/api/src/main/kotlin/io/element/android/services/toolbox/api/strings/StringProvider.kt b/services/toolbox/api/src/main/kotlin/io/element/android/services/toolbox/api/strings/StringProvider.kt new file mode 100644 index 0000000000..4233ea3423 --- /dev/null +++ b/services/toolbox/api/src/main/kotlin/io/element/android/services/toolbox/api/strings/StringProvider.kt @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.services.toolbox.api.strings + +import androidx.annotation.PluralsRes +import androidx.annotation.StringRes + +interface StringProvider { + /** + * Returns a localized string from the application's package's + * default string table. + * + * @param resId Resource id for the string + * @return The string data associated with the resource, stripped of styled + * text information. + */ + fun getString(@StringRes resId: Int): String + + /** + * Returns a localized formatted string from the application's package's + * default string table, substituting the format arguments as defined in + * [java.util.Formatter] and [java.lang.String.format]. + * + * @param resId Resource id for the format string + * @param formatArgs The format arguments that will be used for + * substitution. + * @return The string data associated with the resource, formatted and + * stripped of styled text information. + */ + fun getString(@StringRes resId: Int, vararg formatArgs: Any?): String + fun getQuantityString(@PluralsRes resId: Int, quantity: Int, vararg formatArgs: Any?): String +} diff --git a/services/toolbox/api/src/main/kotlin/io/element/android/services/toolbox/api/systemclock/SystemClock.kt b/services/toolbox/api/src/main/kotlin/io/element/android/services/toolbox/api/systemclock/SystemClock.kt new file mode 100644 index 0000000000..7cde29d7c3 --- /dev/null +++ b/services/toolbox/api/src/main/kotlin/io/element/android/services/toolbox/api/systemclock/SystemClock.kt @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.services.toolbox.api.systemclock + +interface SystemClock { + fun epochMillis(): Long +} diff --git a/services/toolbox/impl/build.gradle.kts b/services/toolbox/impl/build.gradle.kts new file mode 100644 index 0000000000..03cca7957d --- /dev/null +++ b/services/toolbox/impl/build.gradle.kts @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + id("io.element.android-library") + alias(libs.plugins.anvil) +} + +android { + namespace = "io.element.android.services.toolbox.impl" +} + +anvil { + generateDaggerFactories.set(true) +} + +dependencies { + implementation(libs.dagger) + implementation(projects.libraries.androidutils) + implementation(projects.libraries.di) + api(projects.services.toolbox.api) + implementation(libs.androidx.corektx) +} diff --git a/services/toolbox/impl/src/main/kotlin/io/element/android/services/toolbox/impl/appname/DefaultAppNameProvider.kt b/services/toolbox/impl/src/main/kotlin/io/element/android/services/toolbox/impl/appname/DefaultAppNameProvider.kt new file mode 100644 index 0000000000..7a5cbd46f0 --- /dev/null +++ b/services/toolbox/impl/src/main/kotlin/io/element/android/services/toolbox/impl/appname/DefaultAppNameProvider.kt @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.services.toolbox.impl.appname + +import android.content.Context +import com.squareup.anvil.annotations.ContributesBinding +import io.element.android.libraries.androidutils.system.getApplicationLabel +import io.element.android.libraries.di.AppScope +import io.element.android.libraries.di.ApplicationContext +import io.element.android.services.toolbox.api.appname.AppNameProvider +import timber.log.Timber +import javax.inject.Inject + +@ContributesBinding(AppScope::class) +class DefaultAppNameProvider @Inject constructor(@ApplicationContext private val context: Context) : + AppNameProvider { + + override fun getAppName(): String { + return try { + val appPackageName = context.packageName + var appName = context.getApplicationLabel(appPackageName) + + // Use appPackageName instead of appName if appName contains any non-ASCII character + if (!appName.matches("\\A\\p{ASCII}*\\z".toRegex())) { + appName = appPackageName + } + appName + } catch (e: Exception) { + Timber.e(e, "## AppNameProvider() : failed") + "ElementAndroid" + } + } +} diff --git a/services/toolbox/impl/src/main/kotlin/io/element/android/services/toolbox/impl/strings/StringProvider.kt b/services/toolbox/impl/src/main/kotlin/io/element/android/services/toolbox/impl/strings/StringProvider.kt new file mode 100644 index 0000000000..657ffc24c2 --- /dev/null +++ b/services/toolbox/impl/src/main/kotlin/io/element/android/services/toolbox/impl/strings/StringProvider.kt @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.services.toolbox.impl.strings + +import android.content.res.Resources +import androidx.annotation.PluralsRes +import androidx.annotation.StringRes +import com.squareup.anvil.annotations.ContributesBinding +import io.element.android.libraries.di.AppScope +import io.element.android.services.toolbox.api.strings.StringProvider +import javax.inject.Inject + +@ContributesBinding(AppScope::class) +class AndroidStringProvider @Inject constructor(private val resources: Resources) : StringProvider { + + /** + * Returns a localized string from the application's package's + * default string table. + * + * @param resId Resource id for the string + * @return The string data associated with the resource, stripped of styled + * text information. + */ + override fun getString(@StringRes resId: Int): String { + return resources.getString(resId) + } + + /** + * Returns a localized formatted string from the application's package's + * default string table, substituting the format arguments as defined in + * [java.util.Formatter] and [java.lang.String.format]. + * + * @param resId Resource id for the format string + * @param formatArgs The format arguments that will be used for + * substitution. + * @return The string data associated with the resource, formatted and + * stripped of styled text information. + */ + override fun getString(@StringRes resId: Int, vararg formatArgs: Any?): String { + return resources.getString(resId, *formatArgs) + } + + override fun getQuantityString(@PluralsRes resId: Int, quantity: Int, vararg formatArgs: Any?): String { + return resources.getQuantityString(resId, quantity, *formatArgs) + } +} diff --git a/services/toolbox/impl/src/main/kotlin/io/element/android/services/toolbox/impl/systemclock/DefaultSystemClock.kt b/services/toolbox/impl/src/main/kotlin/io/element/android/services/toolbox/impl/systemclock/DefaultSystemClock.kt new file mode 100644 index 0000000000..85479d44b0 --- /dev/null +++ b/services/toolbox/impl/src/main/kotlin/io/element/android/services/toolbox/impl/systemclock/DefaultSystemClock.kt @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.services.toolbox.impl.systemclock + +import com.squareup.anvil.annotations.ContributesBinding +import io.element.android.libraries.di.AppScope +import io.element.android.services.toolbox.api.systemclock.SystemClock +import javax.inject.Inject + +@ContributesBinding(AppScope::class) +class DefaultSystemClock @Inject constructor() : SystemClock { + + /** + * Provides a UTC epoch in milliseconds + * + * This value is not guaranteed to be correct with reality + * as a User can override the system time and date to any values. + */ + override fun epochMillis(): Long { + return System.currentTimeMillis() + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 85939a4eea..1591c5fdb3 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -70,6 +70,8 @@ include(":services:analytics:api") include(":services:analytics:noop") include(":services:appnavstate:api") include(":services:appnavstate:impl") +include(":services:toolbox:api") +include(":services:toolbox:impl") include(":features:onboarding:api") include(":features:onboarding:impl")