Skip to content

Commit 5eb364c

Browse files
committed
Squashed commit of the following:
commit b3d92d0 Author: Alex Rosengarten <[email protected]> Date: Wed Mar 4 12:17:17 2020 -0800 updated test name commit ba7884b Author: Alex Rosengarten <[email protected]> Date: Wed Mar 4 12:16:09 2020 -0800 nested unit tests commit ef36fdf Author: Alex Rosengarten <[email protected]> Date: Wed Mar 4 12:15:00 2020 -0800 renamed to tryResolve commit 5703f02 Author: Alex Rosengarten <[email protected]> Date: Wed Mar 4 12:07:18 2020 -0800 rm generator commit 658cb1a Author: Alex Rosengarten <[email protected]> Date: Wed Mar 4 12:01:54 2020 -0800 implemented more review suggestions commit 0056ee3 Merge: cae89c3 0f0f82a Author: Alex Rosengarten <[email protected]> Date: Wed Mar 4 11:54:23 2020 -0800 Merge branch 'master' of github.com:PolymerLabs/arcs into r2p commit 0f0f82a Author: Maria Mandlis <[email protected]> Date: Wed Mar 4 09:33:29 2020 -0800 add queryable capability (PolymerLabs#4794) commit d032c75 Author: Maria Mandlis <[email protected]> Date: Wed Mar 4 09:23:07 2020 -0800 add creatimeTimestamp to entities (kt) (PolymerLabs#4823) commit 30267fc Author: jblebrun <[email protected]> Date: Wed Mar 4 09:09:39 2020 -0800 Remove some unused deps (PolymerLabs#4831) commit c519181 Author: Cameron Silvestrini <[email protected]> Date: Wed Mar 4 17:14:07 2020 +1100 Increase size of DatabaseImplTest to medium (PolymerLabs#4827) * Increase size of DatabaseImplTest to medium Was a bit flaky. * Check flakiness * Revert presubmit tweak commit fa621c6 Author: jblebrun <[email protected]> Date: Tue Mar 3 22:05:07 2020 -0800 Fix a race condition when setting up `ServiceStore` message channel (PolymerLabs#4826) This seems to be the cause of the flakiness in `AndroidAllocatorTest` and `AndroidHandleManagerTest` (PolymerLabs#4781) commit 78bf4f0 Author: Gogul Balakrishnan <[email protected]> Date: Tue Mar 3 18:00:49 2020 -0800 Utility to convert type proto to field type (if possible). (PolymerLabs#4814) commit cae89c3 Merge: 0360752 e587539 Author: Alex Rosengarten <[email protected]> Date: Tue Mar 3 15:50:34 2020 -0800 Merge branch 'master' of github.com:PolymerLabs/arcs into r2p commit e587539 Author: jblebrun <[email protected]> Date: Tue Mar 3 15:07:16 2020 -0800 Apply simplified test pattern tests in `arcs.android.host` (PolymerLabs#4821) As in 5c6310d commit 1af1aac Author: Joshua Pratt <[email protected]> Date: Wed Mar 4 09:48:15 2020 +1100 Multinomials (PolymerLabs#4804) * multinomial * added tests * making constant readable again * reindent * added multivariate rearrangement tests * updated comment * pr comments: Co-authored-by: Ragav Sachdeva <[email protected]> commit 0360752 Author: Alex Rosengarten <[email protected]> Date: Tue Mar 3 11:42:31 2020 -0800 fix, bad comparison op commit 4b05a28 Merge: f4c1d26 99000c2 Author: Alex Rosengarten <[email protected]> Date: Tue Mar 3 11:18:14 2020 -0800 Merge branch 'r2p' of github.com:alxrsngrtn/arcs into r2p commit f4c1d26 Merge: 140111f 5c6310d Author: Alex Rosengarten <[email protected]> Date: Tue Mar 3 11:14:35 2020 -0800 Merge branch 'master' of github.com:PolymerLabs/arcs into r2p Fixed lint errors commit 99000c2 Merge: 140111f 5c6310d Author: Alex Rosengarten <[email protected]> Date: Tue Mar 3 11:14:35 2020 -0800 Merge branch 'master' of github.com:PolymerLabs/arcs into r2p Fixed lint errors commit 140111f Author: Alex Rosengarten <[email protected]> Date: Tue Mar 3 11:08:12 2020 -0800 Removed flatMap, added TODOs and link to GH issue commit 5c6310d Author: jblebrun <[email protected]> Date: Tue Mar 3 11:02:34 2020 -0800 Simplify service test pattern (PolymerLabs#4817) * Make a simple test lifecycle registry, instead of creating empty testactivity * Remove use of `runBlockingTest`: according to Kotlin/kotlinx.coroutines#1222, if the test results in coroutines being finished on other threads, it's possible to receive "This job has not yet completed" exceptions, even though the jobs were properly terminated. Since we don't need the delay-skipping properties of `runBlockingTest`, I think it's OK to use `runBlocking`. commit 472bc84 Author: Alex Rosengarten <[email protected]> Date: Tue Mar 3 10:27:56 2020 -0800 Improved build rules commit ca1ebf8 Author: Alex Rosengarten <[email protected]> Date: Tue Mar 3 10:17:13 2020 -0800 Impl suggestsions for r2p commit b5578ea Author: Jason Feinstein <[email protected]> Date: Tue Mar 3 09:54:17 2020 -0800 Add tests for dereferencing references to the HandleManagerTest(s) (PolymerLabs#4816) * Add dereferencing tests to the android handle manager test. * Add dereferencing tests to core HandleManager. commit a695797 Author: Jason Feinstein <[email protected]> Date: Mon Mar 2 18:14:07 2020 -0800 Create RawEntityDereferencerTest, storage Reference-> CrdtEntity.Reference (PolymerLabs#4812) * Create RawEntityDereferencerTest, make storage Reference implement CrdtEntity.Reference. Also: Create ParcelableReference. * Add dep. Also, apparently read/writeBoolean is Q-only. * Just write null if there is no version map. * Just write null if there is no version map. commit ba7a107 Author: Gogul Balakrishnan <[email protected]> Date: Mon Mar 2 17:51:35 2020 -0800 Add a decoder for PrimitiveTypeProto and an option to disable android constraints in BUILD. (PolymerLabs#4793) commit f6df54a Author: Alex Rosengarten <[email protected]> Date: Mon Mar 2 15:44:32 2020 -0800 tools/sigh lint commit bede8d9 Author: Alex Rosengarten <[email protected]> Date: Mon Mar 2 14:52:02 2020 -0800 Fixed build rule, simplified runtime commit 62dcc57 Author: Alex Rosengarten <[email protected]> Date: Mon Mar 2 14:38:14 2020 -0800 Fixed test, added TODO
1 parent 2e299ab commit 5eb364c

32 files changed

+708
-361
lines changed

java/arcs/android/crdt/ParcelableRawEntity.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ data class ParcelableRawEntity(
3939
parcel.writeTypedObject(ParcelableReferencable(it), flags)
4040
}
4141
}
42+
parcel.writeLong(actual.creationTimestamp)
4243
parcel.writeLong(actual.expirationTimestamp)
4344
}
4445

@@ -67,10 +68,19 @@ data class ParcelableRawEntity(
6768
collections[key] = set
6869
}
6970

71+
@Suppress("GoodTime") // use Instant
72+
val creationTimestamp = requireNotNull(parcel.readLong())
73+
7074
@Suppress("GoodTime") // use Instant
7175
val expirationTimestamp = requireNotNull(parcel.readLong())
7276

73-
val rawEntity = RawEntity(id, singletons, collections, expirationTimestamp)
77+
val rawEntity = RawEntity(
78+
id,
79+
singletons,
80+
collections,
81+
creationTimestamp,
82+
expirationTimestamp
83+
)
7484
return ParcelableRawEntity(rawEntity)
7585
}
7686

java/arcs/core/common/Referencable.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ interface Referencable {
1919
/** Unique identifier of the Referencable object. */
2020
val id: ReferenceId
2121

22+
/** Creation timestamp (in millis) on the Referencable object. */
23+
var creationTimestamp: Long
24+
get() = TODO("not implemented")
25+
set(@Suppress("UNUSED_PARAMETER") value) = TODO("not implemented")
26+
2227
/** Expiration timestamp (in millis) on the Referencable object. */
2328
var expirationTimestamp: Long
2429
get() = TODO("not implemented")

java/arcs/core/data/RawEntity.kt

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,34 @@ data class RawEntity(
2929
override fun unwrap(): Referencable {
3030
val entity = RawEntity(
3131
id = id,
32+
creationTimestamp = creationTimestamp,
3233
expirationTimestamp = expirationTimestamp,
3334
singletons = singletons.mapValues { it.value?.unwrap() },
3435
collections = collections.mapValues {
3536
it.value.map { item -> item.unwrap() }.toSet()
3637
}
3738
)
39+
entity.creationTimestamp = creationTimestamp
3840
entity.expirationTimestamp = expirationTimestamp
3941
return entity
4042
}
4143

44+
/** Entity creation time (in millis). */
45+
@Suppress("GoodTime") // use Instant
46+
override var creationTimestamp: Long = UNINITIALIZED_TIMESTAMP
47+
set(value) {
48+
require(this.creationTimestamp == UNINITIALIZED_TIMESTAMP) {
49+
"cannot override creationTimestamp $value"
50+
}
51+
@Suppress("GoodTime") // use Instant
52+
field = value
53+
}
54+
4255
/** Entity expiration time (in millis). */
4356
@Suppress("GoodTime") // use Instant
44-
override var expirationTimestamp: Long = NO_EXPIRATION
57+
override var expirationTimestamp: Long = UNINITIALIZED_TIMESTAMP
4558
set(value) {
46-
require(this.expirationTimestamp == NO_EXPIRATION) {
59+
require(this.expirationTimestamp == UNINITIALIZED_TIMESTAMP) {
4760
"cannot override expirationTimestamp $value"
4861
}
4962
@Suppress("GoodTime") // use Instant
@@ -62,7 +75,8 @@ data class RawEntity(
6275
id: ReferenceId = NO_REFERENCE_ID,
6376
singletonFields: Set<FieldName> = emptySet(),
6477
collectionFields: Set<FieldName> = emptySet(),
65-
expirationTimestamp: Long = NO_EXPIRATION
78+
creationTimestamp: Long = UNINITIALIZED_TIMESTAMP,
79+
expirationTimestamp: Long = UNINITIALIZED_TIMESTAMP
6680
) : this(
6781
id,
6882
singletonFields.associateWith { null },
@@ -73,17 +87,21 @@ data class RawEntity(
7387

7488
companion object {
7589
const val NO_REFERENCE_ID = "NO REFERENCE ID"
76-
const val NO_EXPIRATION: Long = -1
90+
const val UNINITIALIZED_TIMESTAMP: Long = -1
7791
}
7892
}
7993

8094
fun RawEntity(
8195
id: String,
8296
singletons: Map<FieldName, Referencable?>,
8397
collections: Map<FieldName, Set<Referencable>>,
98+
creationTimestamp: Long,
8499
expirationTimestamp: Long
85100
) = RawEntity(
86101
id,
87102
singletons,
88103
collections
89-
).also { it.expirationTimestamp = expirationTimestamp }
104+
).also {
105+
it.creationTimestamp = creationTimestamp
106+
it.expirationTimestamp = expirationTimestamp
107+
}

java/arcs/core/data/Ttl.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ sealed class Ttl(count: Int, val isInfinite: Boolean = false) {
3434
override fun hashCode(): Int = minutes.hashCode()
3535

3636
fun calculateExpiration(time: Time): Long =
37-
if (isInfinite) RawEntity.NO_EXPIRATION
37+
if (isInfinite) RawEntity.UNINITIALIZED_TIMESTAMP
3838
else requireNotNull(time).currentTimeMillis + (minutes * 60 * 1000)
3939

4040
data class Minutes(val count: Int) : Ttl(count)

java/arcs/core/data/proto/TypeProtoDecoders.kt

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@
1111

1212
package arcs.core.data.proto
1313

14+
import arcs.core.data.FieldType
1415
import arcs.core.data.PrimitiveType
1516

1617
/**
17-
* Converts a [PrimitiveTypeProto] protobuf instance into a native kotlin [PrimitiveType] instance.
18+
* Converts a [PrimitiveTypeProto] protobuf instance into a Kotlin [PrimitiveType] instance.
1819
*/
1920
fun PrimitiveTypeProto.decode(): PrimitiveType =
2021
when (this) {
@@ -24,3 +25,25 @@ fun PrimitiveTypeProto.decode(): PrimitiveType =
2425
PrimitiveTypeProto.UNRECOGNIZED ->
2526
throw IllegalArgumentException("Unknown PrimitiveTypeProto value.")
2627
}
28+
29+
/**
30+
* Converts a [PrimitiveTypeProto] protobuf instance into a Kotlin [FieldType] instance.
31+
*/
32+
fun PrimitiveTypeProto.decodeAsFieldType(): FieldType.Primitive = FieldType.Primitive(decode())
33+
34+
/**
35+
* Converts a [TypeProto] protobuf instance into a Kotlin [FieldType] instance.
36+
*
37+
* @throws [IllegalArgumentexception] if the type cannot be converted to [FieldType].
38+
*/
39+
fun TypeProto.decodeAsFieldType(): FieldType =
40+
when (getDataCase()) {
41+
TypeProto.DataCase.PRIMITIVE -> getPrimitive().decodeAsFieldType()
42+
// TODO: Handle FieldType.EntityRef. It is not clear how it is
43+
// represented in the proto.
44+
TypeProto.DataCase.DATA_NOT_SET ->
45+
throw IllegalArgumentException("Unknown data field in TypeProto.")
46+
else ->
47+
throw IllegalArgumentException(
48+
"Cannot decode a ${getDataCase().name} type to a [FieldType].")
49+
}

java/arcs/core/storage/handle/CollectionImpl.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ class CollectionImpl<T : Referencable>(
8888
*/
8989
suspend fun store(entity: T): Boolean {
9090
log.debug { "Storing: $entity" }
91+
@Suppress("GoodTime") // use Instant
92+
entity.creationTimestamp = requireNotNull(time).currentTimeMillis
9193
if (!Ttl.Infinite.equals(ttl)) {
9294
@Suppress("GoodTime") // use Instant
9395
entity.expirationTimestamp = ttl.calculateExpiration(time)

java/arcs/core/storage/handle/SingletonImpl.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ class SingletonImpl<T : Referencable>(
6464
* did not apply fully. Fetch the latest value and retry.
6565
* */
6666
suspend fun store(entity: T): Boolean {
67+
@Suppress("GoodTime") // use Instant
68+
entity.creationTimestamp = requireNotNull(time).currentTimeMillis
6769
if (!Ttl.Infinite.equals(ttl)) {
6870
@Suppress("GoodTime") // use Instant
6971
entity.expirationTimestamp = ttl.calculateExpiration(time)

java/arcs/sdk/android/dev/api/CollectionProxy.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,15 @@ public Referencable unwrap() {
286286
return this;
287287
}
288288

289+
@Override
290+
public long getCreationTimestamp() {
291+
throw new AssertionError("ModelEntry::getCreationTimestamp not implemented");
292+
}
293+
294+
@Override
295+
public void setCreationTimestamp(long creationTimestamp) {
296+
throw new AssertionError("ModelEntry::setCreationTimestamp not implemented");
297+
}
289298

290299
@Override
291300
public long getExpirationTimestamp() {

java/arcs/sdk/android/storage/ServiceStore.kt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,12 +142,15 @@ class ServiceStore<Data : CrdtData, Op : CrdtOperation, ConsumerData>(
142142
val service = connection.connectAsync().await()
143143

144144
val messageChannel = ParcelableProxyMessageChannel(coroutineContext)
145-
serviceCallbackToken = withContext(coroutineContext) {
146-
service.registerCallback(messageChannel)
147-
}
148145

146+
// Open subscription before attaching callback to make sure that we capture all messages
147+
val subscription = messageChannel.openSubscription()
149148
scope.launch {
150-
messageChannel.openSubscription().consumeEach { handleMessageAndResultFromService(it) }
149+
subscription.consumeEach { handleMessageAndResultFromService(it) }
150+
}
151+
152+
serviceCallbackToken = withContext(coroutineContext) {
153+
service.registerCallback(messageChannel)
151154
}
152155

153156
this.serviceConnection = connection

javatests/arcs/android/host/AndroidAllocatorTest.kt

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ package arcs.android.host
1313

1414
import android.content.Context
1515
import androidx.lifecycle.Lifecycle
16-
import androidx.test.core.app.ActivityScenario
1716
import androidx.test.core.app.ApplicationProvider
1817
import androidx.test.ext.junit.runners.AndroidJUnit4
1918
import androidx.work.testing.WorkManagerTestInitHelper
@@ -26,12 +25,9 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
2625
import kotlinx.coroutines.GlobalScope
2726
import kotlinx.coroutines.launch
2827
import kotlinx.coroutines.runBlocking
29-
import kotlinx.coroutines.test.TestCoroutineScope
30-
import kotlinx.coroutines.test.runBlockingTest
3128
import org.junit.Before
3229
import org.junit.runner.RunWith
3330
import org.robolectric.Robolectric
34-
import kotlin.coroutines.CoroutineContext
3531

3632
/**
3733
* These tests are the same as [AllocatorTestBase] but run with Android Services,
@@ -82,24 +78,4 @@ open class AndroidAllocatorTest : AllocatorTestBase() {
8278
writingService = Robolectric.setupService(TestWritingExternalHostService::class.java)
8379
super.setUp()
8480
}
85-
86-
override fun runAllocatorTest(
87-
coroutineContext: CoroutineContext,
88-
testBody: suspend TestCoroutineScope.() -> Unit
89-
) = runBlockingTest(coroutineContext) {
90-
val scenario = ActivityScenario.launch(TestActivity::class.java)
91-
92-
scenario.moveToState(Lifecycle.State.STARTED)
93-
94-
val activityJob = launch {
95-
scenario.onActivity { activity ->
96-
runBlocking {
97-
this@runBlockingTest.testBody()
98-
}
99-
scenario.close()
100-
}
101-
}
102-
103-
activityJob.join()
104-
}
10581
}

javatests/arcs/android/host/AndroidEntityHandleManagerTest.kt

Lines changed: 21 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ package arcs.android.host
22

33
import android.app.Application
44
import androidx.lifecycle.Lifecycle
5-
import androidx.test.core.app.ActivityScenario
5+
import androidx.lifecycle.LifecycleOwner
6+
import androidx.lifecycle.LifecycleRegistry
67
import androidx.test.core.app.ApplicationProvider
78
import androidx.test.ext.junit.runners.AndroidJUnit4
89
import androidx.work.testing.WorkManagerTestInitHelper
@@ -27,8 +28,6 @@ import arcs.sdk.android.storage.service.testutil.TestBindingDelegate
2728
import com.google.common.truth.Truth.assertThat
2829
import kotlinx.coroutines.launch
2930
import kotlinx.coroutines.runBlocking
30-
import kotlinx.coroutines.test.TestCoroutineScope
31-
import kotlinx.coroutines.test.runBlockingTest
3231
import org.junit.Before
3332
import org.junit.Test
3433
import org.junit.runner.RunWith
@@ -38,12 +37,15 @@ typealias Person = TestParticleInternal1
3837

3938
@Suppress("EXPERIMENTAL_API_USAGE")
4039
@RunWith(AndroidJUnit4::class)
41-
class AndroidEntityHandleManagerTest {
40+
class AndroidEntityHandleManagerTest : LifecycleOwner {
4241
private lateinit var app: Application
42+
private lateinit var lifecycle: LifecycleRegistry
43+
override fun getLifecycle() = lifecycle
4344

4445
val entity1 = Person("Jason", 21.0, false)
4546
val entity2 = Person("Jason", 22.0, true)
4647
lateinit var handleHolder: TestParticleHandles
48+
private lateinit var handleManager: EntityHandleManager
4749

4850
private val schema = Schema(
4951
listOf(SchemaName("Person")),
@@ -69,37 +71,24 @@ class AndroidEntityHandleManagerTest {
6971
@Before
7072
fun setUp() {
7173
app = ApplicationProvider.getApplicationContext()
72-
app.setTheme(R.style.Theme_AppCompat);
74+
lifecycle = LifecycleRegistry(this).apply {
75+
setCurrentState(Lifecycle.State.CREATED)
76+
setCurrentState(Lifecycle.State.STARTED)
77+
setCurrentState(Lifecycle.State.RESUMED)
78+
}
7379

7480
// Initialize WorkManager for instrumentation tests.
7581
WorkManagerTestInitHelper.initializeTestWorkManager(app)
7682

7783
handleHolder = TestParticleHandles()
78-
}
7984

80-
fun handleManagerTest(
81-
block: suspend TestCoroutineScope.(EntityHandleManager) -> Unit
82-
) = runBlockingTest {
83-
val scenario = ActivityScenario.launch(TestActivity::class.java)
84-
85-
scenario.moveToState(Lifecycle.State.STARTED)
86-
87-
val activityJob = launch {
88-
scenario.onActivity { activity ->
89-
val hf = AndroidHandleManager(
90-
lifecycle = activity.lifecycle, context = activity,
91-
connectionFactory = DefaultConnectionFactory(
92-
activity, TestBindingDelegate(app), coroutineContext
93-
),
94-
coroutineContext = coroutineContext
95-
)
96-
runBlocking {
97-
this@runBlockingTest.block(EntityHandleManager(hf))
98-
}
99-
scenario.close()
100-
}
101-
}
102-
activityJob.join()
85+
handleManager = EntityHandleManager(
86+
AndroidHandleManager(
87+
lifecycle = lifecycle,
88+
context = app,
89+
connectionFactory = DefaultConnectionFactory(app, TestBindingDelegate(app))
90+
)
91+
)
10392
}
10493

10594
private fun expectHandleException(handleName: String, block: () -> Unit) {
@@ -110,7 +99,7 @@ class AndroidEntityHandleManagerTest {
11099
}
111100

112101
@Test
113-
fun handle_uninitializedThrowsException() = handleManagerTest {
102+
fun handle_uninitializedThrowsException() = runBlocking {
114103
expectHandleException("writeHandle") {
115104
handleHolder.writeHandle
116105
}
@@ -161,7 +150,7 @@ class AndroidEntityHandleManagerTest {
161150
)
162151

163152
@Test
164-
fun singletonHandle_writeFollowedByReadWithOnUpdate() = handleManagerTest { handleManager ->
153+
fun singletonHandle_writeFollowedByReadWithOnUpdate() = runBlocking {
165154
val writeHandle = createSingletonHandle(
166155
handleManager,
167156
"writeHandle",
@@ -208,7 +197,7 @@ class AndroidEntityHandleManagerTest {
208197
}
209198

210199
@Test
211-
fun setHandle_writeFollowedByReadWithOnUpdate() = handleManagerTest { handleManager ->
200+
fun setHandle_writeFollowedByReadWithOnUpdate() = runBlocking<Unit> {
212201
val writeSetHandle = createSetHandle(
213202
handleManager,
214203
"writeSetHandle",

javatests/arcs/android/host/AndroidManifest.xml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,6 @@
1515
</intent-filter>
1616
</service>
1717
<service android:name="arcs.sdk.android.service.StorageService" android:exported="false"/>
18-
<activity android:name="arcs.android.host.TestActivity" >
19-
<intent-filter>
20-
<action android:name="android.intent.action.MAIN"/>
21-
<category android:name="android.intent.category.LAUNCHER"/>
22-
</intent-filter>
23-
</activity>
2418
</application>
2519

2620
</manifest>

0 commit comments

Comments
 (0)