/
AppLinkActivity.java
172 lines (148 loc) · 5.29 KB
/
AppLinkActivity.java
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
package org.dolphinemu.dolphinemu.activities;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle;
import androidx.fragment.app.FragmentActivity;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.util.Log;
import android.widget.Toast;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.model.GameFile;
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
import org.dolphinemu.dolphinemu.services.GameFileCacheService;
import org.dolphinemu.dolphinemu.ui.main.TvMainActivity;
import org.dolphinemu.dolphinemu.utils.AppLinkHelper;
import org.dolphinemu.dolphinemu.utils.DirectoryStateReceiver;
/**
* Linker between leanback homescreen and app
*/
public class AppLinkActivity extends FragmentActivity
{
private static final String TAG = "AppLinkActivity";
private AppLinkHelper.PlayAction playAction;
private DirectoryStateReceiver directoryStateReceiver;
private BroadcastReceiver gameFileCacheReceiver;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Intent intent = getIntent();
Uri uri = intent.getData();
Log.v(TAG, uri.toString());
if (uri.getPathSegments().isEmpty())
{
Log.e(TAG, "Invalid uri " + uri);
finish();
return;
}
AppLinkHelper.AppLinkAction action = AppLinkHelper.extractAction(uri);
switch (action.getAction())
{
case AppLinkHelper.PLAY:
playAction = (AppLinkHelper.PlayAction) action;
initResources();
break;
case AppLinkHelper.BROWSE:
browse();
break;
default:
throw new IllegalArgumentException("Invalid Action " + action);
}
}
/**
* Need to init these since they usually occur in the main activity.
*/
private void initResources()
{
IntentFilter directoryStateIntentFilter = new IntentFilter(
DirectoryInitialization.BROADCAST_ACTION);
IntentFilter gameFileCacheIntentFilter = new IntentFilter(
GameFileCacheService.BROADCAST_ACTION);
directoryStateReceiver =
new DirectoryStateReceiver(directoryInitializationState ->
{
if (directoryInitializationState ==
DirectoryInitialization.DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED)
{
tryPlay(playAction);
}
else if (directoryInitializationState ==
DirectoryInitialization.DirectoryInitializationState.EXTERNAL_STORAGE_PERMISSION_NEEDED)
{
Toast.makeText(this, R.string.write_permission_needed, Toast.LENGTH_SHORT)
.show();
}
else if (directoryInitializationState ==
DirectoryInitialization.DirectoryInitializationState.CANT_FIND_EXTERNAL_STORAGE)
{
Toast.makeText(this, R.string.external_storage_not_mounted, Toast.LENGTH_SHORT)
.show();
}
});
gameFileCacheReceiver =
new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent)
{
if (DirectoryInitialization.areDolphinDirectoriesReady())
{
tryPlay(playAction);
}
}
};
LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(this);
broadcastManager.registerReceiver(directoryStateReceiver, directoryStateIntentFilter);
broadcastManager.registerReceiver(gameFileCacheReceiver, gameFileCacheIntentFilter);
DirectoryInitialization.start(this);
GameFileCacheService.startLoad(this);
}
/**
* Action if channel icon is selected
*/
private void browse()
{
Intent openApp = new Intent(this, TvMainActivity.class);
startActivity(openApp);
finish();
}
private void tryPlay(AppLinkHelper.PlayAction action)
{
// TODO: This approach of getting the game from the game file cache without rescanning
// the library means that we can fail to launch games if the cache file has been deleted.
GameFile game = GameFileCacheService.getGameFileByGameId(action.getGameId());
// If game == null and the load isn't done, wait for the next GameFileCacheService broadcast.
// If game == null and the load is done, call play with a null game, making us exit in failure.
if (game != null || GameFileCacheService.hasLoadedCache())
{
play(action, game);
}
}
/**
* Action if program(game) is selected
*/
private void play(AppLinkHelper.PlayAction action, GameFile game)
{
Log.d(TAG, "Playing game "
+ action.getGameId()
+ " from channel "
+ action.getChannelId());
if (game == null)
Log.e(TAG, "Invalid Game: " + action.getGameId());
else
startGame(game);
finish();
}
private void startGame(GameFile game)
{
if (directoryStateReceiver != null)
{
LocalBroadcastManager.getInstance(this).unregisterReceiver(directoryStateReceiver);
directoryStateReceiver = null;
}
EmulationActivity.launch(this, game);
}
}