Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
285 changes: 170 additions & 115 deletions .github/workflows/build.yml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 20 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,29 @@ test-unit:
./gradlew test

test-e2e:
# Run only screenshot test, for now
./gradlew connectedAndroidTest --stacktrace

test-e2e-screenshot-only:
@# To only run screenshot test:
./gradlew connectedAndroidTest \
-Pandroid.testInstrumentationRunnerArguments.class=net.activitywatch.android.ScreenshotTest

test-e2e-adb:
# Requires that you have a device connected with the necessary APKs installed
# Alternative to using gradle, if you don't want to rebuild.
# Run only screenshot test, for now
adb shell pm list instrumentation
@# Requires that you have a device connected with the necessary APKs installed
@# Alternative to using gradle, if you don't want to rebuild.
@#
@# To list instrumentation tests, run:
@# adb shell pm list instrumentation
@#
@# Run only screenshot test, for now
adb shell am instrument -w \
-e class net.activitywatch.android.ScreenshotTest
net.activitywatch.android.debug.test/androidx.test.runner.AndroidJUnitRunner

install-apk-debug: $(APKDIR)/debug/mobile-debug.apk
adb install $(APKDIR)/debug/mobile-debug.apk
adb install $(APKDIR)/debug/mobile-debug-androidTest.apk

# APK targets
$(APKDIR)/release/mobile-release-unsigned.apk:
TERM=xterm ./gradlew assembleRelease
Expand Down Expand Up @@ -97,18 +107,19 @@ $(JNILIBS): $(JNI_arm7)/libaw_server.so $(JNI_arm8)/libaw_server.so $(JNI_x86)/l
@ls -lL $@/*/* # Check that symlinks are valid

# There must be a better way to do this without repeating almost the same rule over and over?
# NOTE: These must be hard links for CI caching to work
$(JNI_arm7)/libaw_server.so: $(TARGET_arm7)/$(RELEASE_TYPE)/libaw_server.so
mkdir -p $$(dirname $@)
ln -sfnv $$(pwd)/$^ $@
ln -fnv $$(pwd)/$^ $@
$(JNI_arm8)/libaw_server.so: $(TARGET_arm8)/$(RELEASE_TYPE)/libaw_server.so
mkdir -p $$(dirname $@)
ln -sfnv $$(pwd)/$^ $@
ln -fnv $$(pwd)/$^ $@
$(JNI_x86)/libaw_server.so: $(TARGET_x86)/$(RELEASE_TYPE)/libaw_server.so
mkdir -p $$(dirname $@)
ln -sfnv $$(pwd)/$^ $@
ln -fnv $$(pwd)/$^ $@
$(JNI_x64)/libaw_server.so: $(TARGET_x64)/$(RELEASE_TYPE)/libaw_server.so
mkdir -p $$(dirname $@)
ln -sfnv $$(pwd)/$^ $@
ln -fnv $$(pwd)/$^ $@

RUSTFLAGS_ANDROID="-C debuginfo=2 -Awarnings"
# Explanation of RUSTFLAGS:
Expand Down
8 changes: 4 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

buildscript {
ext.kotlin_version = '1.7.20'
ext.androidXTestVersion = '1.4.0'
ext.espressoVersion = '3.5.0-rc01'
ext.extJUnitVersion = '1.1.3'
ext.servicesVersion = "1.4.2-rc01"
ext.androidXTestVersion = '1.5.0'
ext.espressoVersion = '3.5.0'
ext.extJUnitVersion = '1.1.4'
ext.servicesVersion = '1.4.2'
repositories {
google()
mavenCentral()
Expand Down
10 changes: 7 additions & 3 deletions mobile/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

android {
compileSdkVersion 33
Expand All @@ -18,7 +17,8 @@ android {
versionCode 25

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArguments useTestStorageService: 'true'
// NOTE: This only works for API level 28 and above
//testInstrumentationRunnerArguments useTestStorageService: 'true'

// WARNING: Never commit this uncommented!
packagingOptions {
Expand Down Expand Up @@ -57,6 +57,10 @@ android {
applicationVariants.all { variant ->
variant.resValue "string", "versionName", 'v' + variant.versionName
}

buildFeatures {
viewBinding true
}
}

dependencies {
Expand All @@ -72,7 +76,7 @@ dependencies {
implementation 'androidx.annotation:annotation:1.5.0'

implementation 'com.google.android.material:material:1.7.0'
implementation 'com.jakewharton.threetenabp:threetenabp:1.1.1'
implementation 'com.jakewharton.threetenabp:threetenabp:1.4.3'

testImplementation "junit:junit:4.13.2"
androidTestImplementation "androidx.test.ext:junit-ktx:$extJUnitVersion"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4

import org.junit.Test
import org.junit.Before
import org.junit.runner.RunWith

import org.junit.Assert.*
Expand All @@ -17,12 +16,12 @@ import java.time.Instant
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
class BasicTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("net.activitywatch.android", appContext.packageName)
assertEquals("net.activitywatch.android.debug", appContext.packageName)
}

@Test
Expand All @@ -33,7 +32,7 @@ class ExampleInstrumentedTest {
val bucketId = "test-${Math.random()}"
val oldLen = ri.getBucketsJSON().length()
ri.createBucket("""{"id": "$bucketId", "type": "test", "hostname": "test", "client": "test"}""")
assertEquals(ri.getBucketsJSON().length(), oldLen + 1)
assertEquals(oldLen + 1, ri.getBucketsJSON().length())
}

@Test
Expand All @@ -42,8 +41,8 @@ class ExampleInstrumentedTest {
val ri = RustInterface(appContext)
val bucketId = "test-${Math.random()}"
ri.createBucket("""{"id": "$bucketId", "type": "test", "hostname": "test", "client": "test"}""")
val oldLen = ri.getEventsJSON(bucketId, 3).length()
ri.heartbeat(bucketId, """{"timestamp": "${Instant.now()}", "duration": 0, "data": {"key": "value"}}""", 1.0)
sleep(10)
assertEquals(1, ri.getEventsJSON(bucketId).length())
assertEquals(oldLen + 1, ri.getEventsJSON(bucketId, 3).length())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,12 @@ class ScreenshotTest {
Log.i(TAG, "Taking screenshot")

val bitmap = takeScreenshot()
bitmap.writeToTestStorage("${javaClass.simpleName}_${nameRule.methodName}")
// Only supported on API levels >=28
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
bitmap.writeToTestStorage("${javaClass.simpleName}_${nameRule.methodName}")
} else {
Log.i(TAG, "Screenshot not saved to test storage, API level too low")
}
Log.i(TAG, "Took screenshot!")
}
}
35 changes: 14 additions & 21 deletions mobile/src/main/java/net/activitywatch/android/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AppCompatActivity
import android.view.Menu
import android.view.MenuItem
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.app_bar_main.*
import androidx.fragment.app.Fragment
import android.util.Log
import net.activitywatch.android.databinding.ActivityMainBinding
import net.activitywatch.android.databinding.AppBarMainBinding
import net.activitywatch.android.fragments.TestFragment
import net.activitywatch.android.fragments.WebUIFragment
import net.activitywatch.android.watcher.UsageStatsWatcher
Expand All @@ -24,6 +24,8 @@ const val baseURL = "http://127.0.0.1:5600"

class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener, WebUIFragment.OnFragmentInteractionListener {

private lateinit var binding: ActivityMainBinding

val version: String
get() {
return packageManager.getPackageInfo(packageName, 0).versionName
Expand All @@ -35,20 +37,11 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

setSupportActionBar(toolbar)

val toggle = ActionBarDrawerToggle(
this, drawer_layout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close
)
drawer_layout.addDrawerListener(toggle)
toggle.syncState()

// Hide the top menu/title bar
supportActionBar?.hide()
binding = ActivityMainBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)

nav_view.setNavigationItemSelectedListener(this)
binding.navView.setNavigationItemSelectedListener(this)

val ri = RustInterface(this)
ri.startServerTask(this)
Expand All @@ -74,8 +67,8 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
}

override fun onBackPressed() {
if (drawer_layout.isDrawerOpen(GravityCompat.START)) {
drawer_layout.closeDrawer(GravityCompat.START)
if (binding.drawerLayout.isDrawerOpen(GravityCompat.START)) {
binding.drawerLayout.closeDrawer(GravityCompat.START)
} else {
super.onBackPressed()
}
Expand All @@ -93,7 +86,7 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
// as you specify a parent activity in AndroidManifest.xml.
return when (item.itemId) {
R.id.action_settings -> {
Snackbar.make(coordinator_layout, "The settings button was clicked, but it's not yet implemented!", Snackbar.LENGTH_LONG)
Snackbar.make(binding.coordinatorLayout, "The settings button was clicked, but it's not yet implemented!", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
true
}
Expand Down Expand Up @@ -123,11 +116,11 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
url = "$baseURL/#/settings/"
}
R.id.nav_share -> {
Snackbar.make(coordinator_layout, "The share button was clicked, but it's not yet implemented!", Snackbar.LENGTH_LONG)
Snackbar.make(binding.coordinatorLayout, "The share button was clicked, but it's not yet implemented!", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
}
R.id.nav_send -> {
Snackbar.make(coordinator_layout, "The send button was clicked, but it's not yet implemented!", Snackbar.LENGTH_LONG)
Snackbar.make(binding.coordinatorLayout, "The send button was clicked, but it's not yet implemented!", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
}
}
Expand All @@ -149,7 +142,7 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
fragmentManager.beginTransaction().replace(R.id.fragment_container, fragment).commit()
}

drawer_layout.closeDrawer(GravityCompat.START)
binding.drawerLayout.closeDrawer(GravityCompat.START)
return true
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package net.activitywatch.android

import android.content.Context
import android.os.AsyncTask
import android.os.Handler
import android.os.Looper
import android.system.Os
Expand Down
6 changes: 3 additions & 3 deletions mobile/src/main/res/layout/app_bar_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
android:layout_height="match_parent"
tools:context=".MainActivity">

<com.google.android.material.appbar.AppBarLayout
<!--com.google.android.material.appbar.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:theme="@style/AppTheme.AppBarOverlay">
Expand All @@ -19,8 +19,8 @@
android:background="#FFFFFF"
app:popupTheme="@style/AppTheme.PopupOverlay" />

</com.google.android.material.appbar.AppBarLayout>
</com.google.android.material.appbar.AppBarLayout-->

<include layout="@layout/content_main"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
2 changes: 1 addition & 1 deletion mobile/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<resources>

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
Expand Down