wifidirectplugin 1.3.6 → 1.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -19,6 +19,7 @@ import android.os.Handler;
|
|
|
19
19
|
import android.os.Looper;
|
|
20
20
|
import android.provider.Settings;
|
|
21
21
|
import android.util.Log;
|
|
22
|
+
import android.widget.Toast;
|
|
22
23
|
|
|
23
24
|
import androidx.activity.result.ActivityResult;
|
|
24
25
|
|
|
@@ -49,6 +50,13 @@ public class WifiDirectPlugin extends Plugin {
|
|
|
49
50
|
|
|
50
51
|
private PluginCall pendingConnectCall = null;
|
|
51
52
|
|
|
53
|
+
// peer 검색: discoverPeers 는 "시작"만 알리므로, 실제 peer 는 WIFI_P2P_PEERS_CHANGED_ACTION
|
|
54
|
+
// 브로드캐스트가 올 때 requestPeers 로 수집한다. target 을 찾으면 즉시 resolve, 못 찾으면 timeout 으로 마감.
|
|
55
|
+
private PluginCall pendingScanCall = null;
|
|
56
|
+
private String pendingScanTargetName = null;
|
|
57
|
+
private Runnable pendingScanTimeout = null;
|
|
58
|
+
private static final long SCAN_TIMEOUT_MS = 15000L;
|
|
59
|
+
|
|
52
60
|
// Group 형성 broadcast가 안 올 경우 대비한 timeout과 메인 핸들러
|
|
53
61
|
private final Handler mainHandler = new Handler(Looper.getMainLooper());
|
|
54
62
|
private Runnable pendingConnectTimeout = null;
|
|
@@ -62,7 +70,7 @@ public class WifiDirectPlugin extends Plugin {
|
|
|
62
70
|
private Network boundP2pNetwork = null;
|
|
63
71
|
|
|
64
72
|
private void showToast(String message) {
|
|
65
|
-
Toast.makeText(
|
|
73
|
+
Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show();
|
|
66
74
|
}
|
|
67
75
|
|
|
68
76
|
private final BroadcastReceiver wifiP2pReceiver = new BroadcastReceiver() {
|
|
@@ -92,6 +100,11 @@ public class WifiDirectPlugin extends Plugin {
|
|
|
92
100
|
pendingConnectCall = null;
|
|
93
101
|
}
|
|
94
102
|
}
|
|
103
|
+
} else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
|
|
104
|
+
// peer 목록이 갱신됨 → 진행 중인 스캔이 있으면 수집 시도
|
|
105
|
+
if (pendingScanCall != null) {
|
|
106
|
+
requestAndResolvePeers(false);
|
|
107
|
+
}
|
|
95
108
|
}
|
|
96
109
|
}
|
|
97
110
|
};
|
|
@@ -126,6 +139,10 @@ public class WifiDirectPlugin extends Plugin {
|
|
|
126
139
|
} catch (IllegalArgumentException e) {
|
|
127
140
|
Log.w(TAG, "Receiver not registered or already registered");
|
|
128
141
|
}
|
|
142
|
+
if (pendingScanCall != null) {
|
|
143
|
+
pendingScanCall.reject("Plugin unloaded");
|
|
144
|
+
clearPendingScan();
|
|
145
|
+
}
|
|
129
146
|
unregisterP2pNetworkCallback();
|
|
130
147
|
}
|
|
131
148
|
@PluginMethod
|
|
@@ -137,47 +154,84 @@ public class WifiDirectPlugin extends Plugin {
|
|
|
137
154
|
call.reject("WifiP2pManager or Channel not initialized");
|
|
138
155
|
return;
|
|
139
156
|
}
|
|
157
|
+
|
|
158
|
+
// 진행 중인 이전 스캔이 있으면 정리(누수 방지)
|
|
159
|
+
if (pendingScanCall != null) {
|
|
160
|
+
pendingScanCall.reject("superseded by a new scan");
|
|
161
|
+
clearPendingScan();
|
|
162
|
+
}
|
|
163
|
+
pendingScanCall = call;
|
|
164
|
+
pendingScanTargetName = targetDeviceName;
|
|
165
|
+
|
|
166
|
+
// 타임아웃: 그때까지 target peer 를 못 찾으면 현재 목록(빈 배열 가능)으로 마감
|
|
167
|
+
pendingScanTimeout = () -> {
|
|
168
|
+
Log.d(TAG, "scanWifiPeers timeout — resolving with current peers");
|
|
169
|
+
requestAndResolvePeers(true);
|
|
170
|
+
};
|
|
171
|
+
mainHandler.postDelayed(pendingScanTimeout, SCAN_TIMEOUT_MS);
|
|
172
|
+
|
|
140
173
|
manager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
|
|
141
174
|
@Override
|
|
142
175
|
public void onSuccess() {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
peerWifiDirDevices.clear();
|
|
147
|
-
peerWifiDirDevices.addAll(peerList.getDeviceList());
|
|
148
|
-
JSONArray devicesJson = new JSONArray();
|
|
149
|
-
for(WifiP2pDevice device: peerWifiDirDevices) {
|
|
150
|
-
try {
|
|
151
|
-
if (targetDeviceName != null && !targetDeviceName.isEmpty()) {
|
|
152
|
-
if (!device.deviceName.toUpperCase().contains(targetDeviceName.toUpperCase())) {
|
|
153
|
-
continue;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
JSONObject deviceJson = new JSONObject();
|
|
157
|
-
deviceJson.put("deviceName", device.deviceName);
|
|
158
|
-
deviceJson.put("deviceAddress", device.deviceAddress);
|
|
159
|
-
deviceJson.put("status", device.status);
|
|
160
|
-
deviceJson.put("connected", device.status == WifiP2pDevice.CONNECTED);
|
|
161
|
-
|
|
162
|
-
devicesJson.put(deviceJson);
|
|
163
|
-
} catch (JSONException e) {
|
|
164
|
-
Log.e(TAG, "JSON error: ", e);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
JSObject ret = new JSObject();
|
|
168
|
-
ret.put("devices", devicesJson);
|
|
169
|
-
call.resolve(ret);
|
|
170
|
-
});
|
|
176
|
+
// discovery 가 "시작"된 것뿐. 실제 peer 는 WIFI_P2P_PEERS_CHANGED_ACTION 에서 수집한다.
|
|
177
|
+
Log.d(TAG, "discoverPeers started");
|
|
171
178
|
}
|
|
172
179
|
|
|
173
180
|
@Override
|
|
174
181
|
public void onFailure(int reason) {
|
|
175
182
|
Log.e(TAG, "scanWifi onFailure: " + reason);
|
|
183
|
+
clearPendingScan();
|
|
176
184
|
call.reject("Peer discovery failed: " + reason);
|
|
177
185
|
}
|
|
178
186
|
});
|
|
179
187
|
}
|
|
180
188
|
|
|
189
|
+
// 현재 peer 목록을 받아 target 필터를 적용해 pendingScanCall 을 resolve 한다.
|
|
190
|
+
// resolveEvenIfEmpty=false 면 target 을 찾았을 때만 resolve(아니면 계속 대기), true 면 빈 목록이라도 마감.
|
|
191
|
+
private void requestAndResolvePeers(boolean resolveEvenIfEmpty) {
|
|
192
|
+
if (manager == null || channel == null || pendingScanCall == null) return;
|
|
193
|
+
final String target = pendingScanTargetName;
|
|
194
|
+
manager.requestPeers(channel, peerList -> {
|
|
195
|
+
if (pendingScanCall == null) return; // 이미 처리됨
|
|
196
|
+
peerWifiDirDevices.clear();
|
|
197
|
+
peerWifiDirDevices.addAll(peerList.getDeviceList());
|
|
198
|
+
JSONArray devicesJson = new JSONArray();
|
|
199
|
+
for (WifiP2pDevice device : peerWifiDirDevices) {
|
|
200
|
+
if (target != null && !target.isEmpty()
|
|
201
|
+
&& !device.deviceName.toUpperCase().contains(target.toUpperCase())) {
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
try {
|
|
205
|
+
JSONObject deviceJson = new JSONObject();
|
|
206
|
+
deviceJson.put("deviceName", device.deviceName);
|
|
207
|
+
deviceJson.put("deviceAddress", device.deviceAddress);
|
|
208
|
+
deviceJson.put("status", device.status);
|
|
209
|
+
deviceJson.put("connected", device.status == WifiP2pDevice.CONNECTED);
|
|
210
|
+
devicesJson.put(deviceJson);
|
|
211
|
+
} catch (JSONException e) {
|
|
212
|
+
Log.e(TAG, "JSON error: ", e);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (devicesJson.length() > 0 || resolveEvenIfEmpty) {
|
|
216
|
+
PluginCall call = pendingScanCall;
|
|
217
|
+
clearPendingScan();
|
|
218
|
+
JSObject ret = new JSObject();
|
|
219
|
+
ret.put("devices", devicesJson);
|
|
220
|
+
call.resolve(ret);
|
|
221
|
+
}
|
|
222
|
+
// 그 외(target 미발견): 다음 PEERS_CHANGED 또는 timeout 까지 계속 대기
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
private void clearPendingScan() {
|
|
227
|
+
if (pendingScanTimeout != null) {
|
|
228
|
+
mainHandler.removeCallbacks(pendingScanTimeout);
|
|
229
|
+
pendingScanTimeout = null;
|
|
230
|
+
}
|
|
231
|
+
pendingScanCall = null;
|
|
232
|
+
pendingScanTargetName = null;
|
|
233
|
+
}
|
|
234
|
+
|
|
181
235
|
@PluginMethod
|
|
182
236
|
public void connectToDevice(PluginCall call) {
|
|
183
237
|
Log.d(TAG, "connectToDevice Called");
|