Move auth to service, UI/UX improvements

- Service handles auth: auto-login via Quest SDK on onCreate, periodic
  token refresh, isAuthenticated/login AIDL methods
- Clients tab shows actual connected game clients from ClientTracker
  instead of plans filtered by status
- Create Plan service picker shows "YouTube - DisplayName" per linked
  account instead of raw service IDs
- createDefaultPlan AIDL method creates plan with one destination per
  linked account (unlisted)
- Session validation on Activity open via getMe() call
- Backend health indicator (green/red dot) on Dashboard nav icon
- ConnectedClientInfo parcelable for client data over AIDL
- SDK client exposes isAuthenticated, login, createDefaultPlan,
  getConnectedClients, authenticated StateFlow
This commit is contained in:
2026-02-27 13:20:48 +01:00
parent ad2c398d78
commit 5b8ede3a19
24 changed files with 623 additions and 183 deletions

View File

@@ -0,0 +1,3 @@
package com.omixlab.lckcontrol.shared;
parcelable ConnectedClientInfo;

View File

@@ -7,4 +7,5 @@ interface ILckControlCallback {
void onStreamPlanUpdated(in StreamPlan plan);
void onClientRegistered(String clientId);
void onClientUnregistered(String clientId);
void onAuthStateChanged(boolean authenticated);
}

View File

@@ -1,21 +1,35 @@
package com.omixlab.lckcontrol.shared;
import com.omixlab.lckcontrol.shared.ConnectedClientInfo;
import com.omixlab.lckcontrol.shared.LinkedAccount;
import com.omixlab.lckcontrol.shared.StreamPlan;
import com.omixlab.lckcontrol.shared.StreamPlanConfig;
import com.omixlab.lckcontrol.shared.ILckControlCallback;
interface ILckControlService {
// Auth
boolean isAuthenticated();
void login();
// Accounts
List<LinkedAccount> getLinkedAccounts();
// Stream plans
StreamPlan createStreamPlan(in StreamPlanConfig config);
StreamPlan createDefaultPlan(String clientName);
StreamPlan prepareStreamPlan(String planId);
List<StreamPlan> getStreamPlans();
StreamPlan getStreamPlan(String planId);
boolean startStreamPlan(String planId);
boolean endStreamPlan(String planId);
// Clients
String registerClient(String clientName, String packageName);
void unregisterClient(String clientId);
void setClientActivePlan(String clientId, String planId);
List<ConnectedClientInfo> getConnectedClients();
// Callbacks
void registerCallback(ILckControlCallback callback);
void unregisterCallback(ILckControlCallback callback);
}

View File

@@ -0,0 +1,33 @@
package com.omixlab.lckcontrol.shared
import android.os.Parcel
import android.os.Parcelable
data class ConnectedClientInfo(
val clientId: String,
val clientName: String,
val packageName: String,
val activePlanId: String? = null,
) : Parcelable {
constructor(parcel: Parcel) : this(
clientId = parcel.readString()!!,
clientName = parcel.readString()!!,
packageName = parcel.readString()!!,
activePlanId = parcel.readString(),
)
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(clientId)
parcel.writeString(clientName)
parcel.writeString(packageName)
parcel.writeString(activePlanId)
}
override fun describeContents(): Int = 0
companion object CREATOR : Parcelable.Creator<ConnectedClientInfo> {
override fun createFromParcel(parcel: Parcel) = ConnectedClientInfo(parcel)
override fun newArray(size: Int) = arrayOfNulls<ConnectedClientInfo>(size)
}
}