summaryrefslogtreecommitdiffstats
path: root/lib/data/data_providers/app_launcher.dart
blob: 917dd21a2c292fe725c99b273675f470a294b4ac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import 'package:flutter_ics_homescreen/export.dart';
import 'package:protos/applauncher_api.dart';
import 'package:protos/agl_shell_api.dart';

class AppLauncher {
  final Ref ref;

  late ClientChannel aglShellChannel;
  late AglShellManagerServiceClient aglShell;
  late ClientChannel appLauncherChannel;
  late AppLauncherClient appLauncher;

  List<String> appStack = ['homescreen'];

  AppLauncher({required this.ref}) {
    aglShellChannel = ClientChannel('localhost',
        port: 14005,
        options: const ChannelOptions(credentials: ChannelCredentials.insecure()));

    aglShell = AglShellManagerServiceClient(aglShellChannel);

    appLauncherChannel = ClientChannel('localhost',
        port: 50052,
        options: const ChannelOptions(credentials: ChannelCredentials.insecure()));
    appLauncher = AppLauncherClient(appLauncherChannel);
  }

  run() async {
    getAppList();

    try {
      var response = appLauncher.getStatusEvents(StatusRequest());
      await for (var event in response) {
        if (event.hasApp()) {
          AppStatus appStatus = event.app;
          debugPrint("Got app status:");
          debugPrint("$appStatus");
          if (appStatus.hasId() && appStatus.hasStatus()) {
            if (appStatus.status == "started") {
              activateApp(appStatus.id);
            } else if (appStatus.status == "terminated") {
              deactivateApp(appStatus.id);
            }
          }
        }
      }
    } catch (e) {
      print(e);
    }
  }

  getAppList() async {
    try {
      var response = await appLauncher.listApplications(ListRequest());
      List<AppLauncherInfo> apps = [];
      for (AppInfo info in response.apps) {
        debugPrint("Got app:");
        debugPrint("$info");
        // Existing icons are currently not usable, so leave blank for now
        apps.add(AppLauncherInfo(
            id: info.id, name: info.name, icon: "", internal: false));
      }
      apps.sort((a, b) => a.name.compareTo(b.name));

      // Add built-in app widgets
      apps.insert(
          0,
          AppLauncherInfo(
              id: "clock", name: "Clock", icon: "clock.svg", internal: true));
      apps.insert(
          0,
          AppLauncherInfo(
              id: "weather",
              name: "Weather",
              icon: "weather.svg",
              internal: true));

      ref.read(appLauncherListProvider.notifier).update(apps);
    } catch (e) {
      print(e);
    }
  }

  void startApp(String id) async {
    await appLauncher.startApplication(StartRequest(id: id));
  }

  addAppToStack(String id) {
    if (!appStack.contains(id)) {
      appStack.add(id);
    } else {
      int current = appStack.indexOf(id);
      if (current != (appStack.length - 1)) {
        appStack.removeAt(current);
        appStack.add(id);
      }
    }
  }

  activateApp(String id) async {
    if (appStack.last != id) {
      var req = ActivateRequest(appId: id);
      aglShell.activateApp(req);
      addAppToStack(id);
    }
  }

  deactivateApp(String id) async {
    if (appStack.contains(id)) {
      appStack.remove(id);
      if (appStack.isNotEmpty) {
        activateApp(appStack.last);
      }
    }
  }
}