Skip to content

Commit

Permalink
add register push command (#229)
Browse files Browse the repository at this point in the history
* add register push command

* vup
  • Loading branch information
wasnot authored Apr 20, 2023
1 parent 00ede45 commit 3cceb85
Show file tree
Hide file tree
Showing 16 changed files with 291 additions and 151 deletions.
15 changes: 13 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,25 @@

| モジュール/プラグイン名 | Description | 最新のバージョン |
| :-- | :-- | :-- |
| core | イベントトラッキング機能を提供します。 | 2.21.2 |
| core | イベントトラッキング機能を提供します。 | 2.22.0 |
| inappmessaging | アプリ内メッセージ機能を提供します。 | 2.15.0 |
| notifications | プッシュ通知の受信および効果測定機能を提供します。 | 2.9.1 |
| notifications | プッシュ通知の受信および効果測定機能を提供します。 | 2.10.0 |
| variables | 設定値配信機能を提供します。 | 2.4.0 |
| visualtracking | ビジュアルトラッキング機能を提供します。| 2.8.0 |
| inbox | Push通知の送信履歴を取得する機能を提供します(β版)。 | 0.1.0 |
| Karte Gradle Plugin | ビジュアルトラッキング機能に必要なプラグインです。| 2.5.0 |

# Releases - xxxx.xx.xx

### Core 2.22.0
** 🔨CHANGED**
- Native機能呼び出しをサブモジュールから追加可能にしました。

### Notifications 2.10.0
** 🎉 FEATURE**
- Android 13以降において、[Native機能呼び出し](https://support.karte.io/post/1F1VeY2yy3mrTIO2U4HhHi)のプッシュ通知の許可を求めるアラートの表示に対応しました。
- アプリ内メッセージ経由でのみ呼び出し可能です。(プッシュ通知は権限がないと表示できないため)

# Releases - 2023.04.11

### Core 2.21.2
Expand Down
10 changes: 7 additions & 3 deletions core/src/main/java/io/karte/android/KarteApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import io.karte.android.core.command.CommandExecutor
import io.karte.android.core.config.Config
import io.karte.android.core.library.ActionModule
import io.karte.android.core.library.CommandModule
import io.karte.android.core.library.DeepLinkModule
import io.karte.android.core.library.Library
import io.karte.android.core.library.LibraryConfig
Expand Down Expand Up @@ -172,9 +172,13 @@ class KarteApp private constructor() : ActivityLifecycleCallback() {
* コマンドスキームを処理し、結果を返します。
*
* **SDK内部で利用するクラスであり、通常のSDK利用でこちらのクラスを利用することはありません。**
*
* @param[uri] コマンドを表現するURI
* @param[isDelay] 通知タップなど、即時に実行すべきでない場合にtrueとします。デフォルトはfalseです。
*/
fun executeCommand(uri: Uri): List<Any?> {
return CommandExecutor.execute(uri)
@JvmOverloads
fun executeCommand(uri: Uri, isDelay: Boolean = false): List<Any?> {
return modules.filterIsInstance<CommandModule>().filter { it.validate(uri) }.map { it.execute(uri, isDelay) }
}

private fun handleDeeplink(intent: Intent) {
Expand Down
35 changes: 35 additions & 0 deletions core/src/main/java/io/karte/android/core/library/Module.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package io.karte.android.core.library

import android.content.Intent
import android.net.Uri
import io.karte.android.tracking.client.TrackRequest
import io.karte.android.tracking.client.TrackResponse
import io.karte.android.tracking.queue.TrackEventRejectionFilterRule
Expand Down Expand Up @@ -119,3 +120,37 @@ interface TrackModule : Module {
*/
fun intercept(request: TrackRequest): TrackRequest
}

private const val karteSchemeLength = 36

/**
* コマンドを実行するためのモジュールタイプです。
*
* **サブモジュールと連携するために用意している機能であり、通常利用で使用することはありません。**
*/
interface CommandModule : Module {
/**
* コマンドを実行します。
*
* @param[uri] コマンドを表現するURL
* @param[isDelay] 遅延実行すべきかを表す真偽値
* @return コマンドの実行するための[Intent]
*/
fun execute(uri: Uri, isDelay: Boolean = false): Intent? {
return null
}

/**
* 対象のKARTEのコマンドかどうか検証します。
*
* @param[uri] 検証対象のURL
* @return コマンドの検証結果
*/
fun validate(uri: Uri): Boolean {
val scheme = uri.scheme
if (scheme != null && scheme.startsWith("krt-") && scheme.length == karteSchemeLength) {
return true
}
return false
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2020 PLAID, Inc.
// Copyright 2023 PLAID, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -13,55 +13,36 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
package io.karte.android.core.command

package io.karte.android.modules.commands

import android.content.Intent
import android.net.Uri
import android.provider.Settings
import io.karte.android.BuildConfig
import io.karte.android.KarteApp
import io.karte.android.core.library.CommandModule
import io.karte.android.core.library.Library

internal object CommandExecutor {
fun execute(uri: Uri): List<Any?> {
val commands = listOf(
OpenSettingsCommand(),
OpenStoreCommand()
)
return commands.filter { it.validate(uri) }.map { it.execute() }
}
}
internal class CoreCommands : Library {
override val name: String = "CoreCommands"
override val version: String = BuildConfig.LIB_VERSION
override val isPublic: Boolean = false
private val commands = listOf(OpenSettingsCommandExecutor(), OpenStoreCommandExecutor())

private const val karteSchemeLength = 36

/**
* コマンドを表現するインターフェースです。
*
* **SDK内部で利用するタイプであり、通常のSDK利用でこちらのタイプを利用することはありません。**
*
*/
private interface Command {
/**
* コマンドを実行します。
*
* @return コマンドの実行結果
*/
fun execute(): Any?
override fun configure(app: KarteApp) {
commands.forEach { app.register(it) }
}

/**
* 有効なKARTEのコマンドかどうか検証します。
*
* @return コマンドの検証結果
*/
fun validate(uri: Uri): Boolean {
val scheme = uri.scheme
if (scheme != null && scheme.startsWith("krt-") && scheme.length == karteSchemeLength) {
return true
}
return false
override fun unconfigure(app: KarteApp) {
commands.forEach { app.unregister(it) }
}
}

private class OpenSettingsCommand : Command {
override fun execute(): Any? {
private class OpenSettingsCommandExecutor : CommandModule {
override val name: String = "OpenSettingsCommand"

override fun execute(uri: Uri, isDelay: Boolean): Intent {
val uriString = "package:" + KarteApp.self.application.packageName
return Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse(uriString))
}
Expand All @@ -80,8 +61,9 @@ private class OpenSettingsCommand : Command {
}
}

private class OpenStoreCommand : Command {
override fun execute(): Any? {
private class OpenStoreCommandExecutor : CommandModule {
override val name: String = "OpenStoreCommand"
override fun execute(uri: Uri, isDelay: Boolean): Intent {
val uriString = "market://details?id=" + KarteApp.self.application.packageName
return Intent(Intent.ACTION_VIEW, Uri.parse(uriString))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
io.karte.android.modules.findmyself.FindMyself
io.karte.android.modules.crashreporting.CrashReporting
io.karte.android.modules.deeplinkevent.DeepLinkEvent
io.karte.android.modules.commands.CoreCommands
58 changes: 57 additions & 1 deletion core/src/test/java/io/karte/android/integration/ModuleTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import android.content.Intent
import android.net.Uri
import io.karte.android.KarteApp
import io.karte.android.core.library.ActionModule
import io.karte.android.core.library.CommandModule
import io.karte.android.core.library.DeepLinkModule
import io.karte.android.core.library.Library
import io.karte.android.core.library.Module
Expand Down Expand Up @@ -178,7 +179,7 @@ class ModuleTest {
override val mock = mockk<TrackModule>(relaxed = true)

@Test
fun interceptが呼ばれること() {
fun interceptが毎回呼ばれること() {
// interceptではrequestをそのまま返す
every { mock.intercept(any()) } returnsArgument 0

Expand All @@ -187,6 +188,61 @@ class ModuleTest {
Tracker.track("test")
proceedBufferedCall()
verify(exactly = 1) { mock.intercept(any()) }

Tracker.track("test")
proceedBufferedCall()
verify(exactly = 2) { mock.intercept(any()) }
}

@Test
fun eventRejectionFilterRulesが一度だけ呼ばれること() {
every { mock.eventRejectionFilterRules } returns emptyList()
verify(exactly = 0) { mock.eventRejectionFilterRules }

Tracker.track("test")
proceedBufferedCall()
verify(exactly = 1) { mock.eventRejectionFilterRules }

// 二回目以降も1度しか呼ばれない。
Tracker.track("test")
proceedBufferedCall()
verify(exactly = 1) { mock.eventRejectionFilterRules }
}
}

class CommandModuleTest : ModuleTestCase() {
override val mock = mockk<CommandModule>(relaxed = true)

@Test
fun validateが毎回呼ばれること() {
every { mock.validate(any()) } returns false

verify(exactly = 0) { mock.validate(any()) }

KarteApp.self.executeCommand(Uri.parse("test://aa"))
verify(exactly = 1) { mock.validate(any()) }

KarteApp.self.executeCommand(Uri.parse("test://bb"))
verify(exactly = 2) { mock.validate(any()) }
}

@Test
fun executeが呼ばれること() {
val validUri = Uri.parse("test://valid")
val invalidUri = Uri.parse("test://invalid")
every { mock.validate(validUri) } returns true
every { mock.validate(invalidUri) } returns false
every { mock.execute(any()) } returns null

verify(exactly = 0) { mock.execute(any()) }

// invalidなuriでは呼ばれない
KarteApp.self.executeCommand(invalidUri)
verify(exactly = 0) { mock.execute(any()) }

// validなuriでは呼ばれる
KarteApp.self.executeCommand(validUri)
verify(exactly = 1) { mock.execute(any()) }
}
}
}
2 changes: 1 addition & 1 deletion core/version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.21.2
2.22.0

This file was deleted.

4 changes: 2 additions & 2 deletions notifications/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ def fcmCompileVersion = "20.3.0"

android {
namespace 'io.karte.android.notifications'
compileSdkVersion 31
compileSdkVersion 33

defaultConfig {
minSdkVersion 16
//noinspection OldTargetApi
targetSdkVersion 31
targetSdkVersion 33
buildConfigField "String", "LIB_VERSION", "\"$version\""

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
Expand Down
Loading

0 comments on commit 3cceb85

Please sign in to comment.