package com.epson.mobilephone.common.wifidirect; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.wifi.ScanResult; import android.net.wifi.WifiManager; import android.net.wifi.p2p.WifiP2pDevice; import android.net.wifi.p2p.WifiP2pDeviceList; import android.net.wifi.p2p.WifiP2pManager; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.SystemClock; import java.util.ArrayList; import java.util.Collection; import java.util.List; import epson.print.CommonDefine; public class SearchWiFiDirectPrinterTask { private static final int DELEY_SEARCH = 1000; public static final String MACADDR_INFRA = "addr_infra"; public static final String MACADDR_P2P = "addr_p2p"; private static final int MAX_RETRY_SCANNING = 5; private static final int MAX_RETRY_SCANNING_CHECKINGTIME = 3; private static final int MAX_RETRY_SCANNING_P2P = 30; private static final int MAX_SCANRESULT_TIME = 30000; public static final String NETWORK_ID = "id"; public static final String PRINTER_NAME = "name"; public static final int PRINTER_P2P = 2; public static final int PRINTER_SIMPLEAP = 1; public static final String PRINTER_SSID = "ssid"; public static final int SCANNING_TIMEOUT = 15; public static final String TAG = "SearchWiFiDirectPrinterTask"; protected static long lastScan; private static SearchWiFiDirectPrinterTask searchWiFiDirectPrinterTask; private final int DISCOVER_PEERS = 0; boolean bDisConnectP2P = false; Context context = null; int idResult = 0; ArrayList listFoundSSID = new ArrayList<>(); Handler mHandler = null; WifiP2pManager mWiFiP2PManager = null; WifiManager mWifiManager = null; NetworkStateChangeReciever networkStateChangeReciever = null; WifiP2pManager.Channel p2pChannnel = null; WiFiDirectBroadcastReceiver p2pStateChangeReciever = null; int retryScaning = 0; int retryScaningP2P = 0; ScanningObserver scannigObserver = new ScanningObserver(); Handler searchHandler = new Handler(new Handler.Callback() { public boolean handleMessage(Message message) { if (message.what == 0) { WifiP2pUtils.ConnectionInfo connectionInfo = WifiP2pUtils.getInstance (context).getConnectionInfo(); if (connectionInfo != null) { if (context).isExcludedMacAddress(WiFiControl.p2pAddr2PtrAddr(connectionInfo.p2PMacAdder, connectionInfo.printerName))) { bDisConnectP2P = true; } } SearchWiFiDirectPrinterTask.mWiFiP2PManager.discoverPeers (p2pChannnel, new WifiP2pManager.ActionListener() { public void onSuccess() { EPLog.d(SearchWiFiDirectPrinterTask.TAG, "discoverPeers Start"); serarchingStatus |= 2; } public void onFailure(int i) { switch (i) { case 0: EPLog.w(SearchWiFiDirectPrinterTask.TAG, "P2P_Operation ERROR"); break; case 1: EPLog.w(SearchWiFiDirectPrinterTask.TAG, "P2P_Operation P2P_UNSUPPORTED"); break; case 2: EPLog.w(SearchWiFiDirectPrinterTask.TAG, "P2P_Operation BUSY"); if (!bDisConnectP2P && WifiP2pUtils.getInstance (context).isConnectedWiFiP2P()) { EPLog.w(SearchWiFiDirectPrinterTask.TAG, "Disconnect P2P and And Retry"); WifiP2pUtils.getInstance (context).disconnect(); bDisConnectP2P = true; searchHandler.sendEmptyMessageDelayed(0, 1000); return; } default: EPLog.w(SearchWiFiDirectPrinterTask.TAG, "P2P_Operation Fail"); break; } if (serarchingStatus == 0) { SearchWiFiDirectPrinterTask.mHandler.sendEmptyMessage (idResult); } } }); } return true; } }); volatile int serarchingStatus = 0; int timeout = 15; public static SearchWiFiDirectPrinterTask getInstance(Context context2) { SearchWiFiDirectPrinterTask searchWiFiDirectPrinterTask2 = searchWiFiDirectPrinterTask; if (searchWiFiDirectPrinterTask2 != null) { return searchWiFiDirectPrinterTask2; } searchWiFiDirectPrinterTask = new SearchWiFiDirectPrinterTask(context2); return searchWiFiDirectPrinterTask; } private SearchWiFiDirectPrinterTask(Context context2) { context = context2.getApplicationContext(); mWifiManager = (WifiManager) context2.getSystemService(Service.WIFI_SERVICE); mWiFiP2PManager = (WifiP2pManager) context2.getSystemService("wifip2p"); WifiP2pManager wifiP2pManager = mWiFiP2PManager; if (wifiP2pManager != null) { p2pChannnel = wifiP2pManager.initialize(context2, context2.getMainLooper(), (WifiP2pManager.ChannelListener) null); } } private boolean start(int i, Handler handler, int i2, int i3) { if (serarchingStatus != 0) { EPLog.d(TAG, "Already started"); return true; } EPLog.d(TAG, "start()"); mHandler = handler; idResult = i2; timeout = i3; if (!mWifiManager.isWifiEnabled()) { return false; } listFoundSSID.clear(); retryScaning = 0; retryScaningP2P = 0; scannigObserver.start(i3 * 1000); if ((i & 1) != 0) { networkStateChangeReciever = new NetworkStateChangeReciever(); context.registerReceiver(networkStateChangeReciever, new IntentFilter("android.net.wifi.SCAN_RESULTS")); serarchingStatus |= 1; onScanResultAvailable(); } if (!((i & 2) == 0 || mWiFiP2PManager == null || p2pChannnel == null)) { p2pStateChangeReciever = new WiFiDirectBroadcastReceiver(); context.registerReceiver(p2pStateChangeReciever, new IntentFilter("android.net.wifi.p2p.PEERS_CHANGED")); bDisConnectP2P = false; searchHandler.sendEmptyMessage(0); } return true; } public void interrupt() { EPLog.d(TAG, "interrupt()"); Handler handler = searchHandler; if (handler != null) { handler.removeMessages(0); } scannigObserver.interrunpt(); if (!(mWiFiP2PManager == null || p2pChannnel == null)) { EPLog.d(TAG, "stopPeerDiscovery"); mWiFiP2PManager.stopPeerDiscovery(p2pChannnel, (WifiP2pManager.ActionListener) null); } unRegisterReceiverSimpleAp(); unRegisterReceiverP2P(); serarchingStatus = 0; } private void unRegisterReceiverSimpleAp() { NetworkStateChangeReciever networkStateChangeReciever2 = networkStateChangeReciever; if (networkStateChangeReciever2 != null) { try { context.unregisterReceiver(networkStateChangeReciever2); } catch (IllegalArgumentException e) { e.printStackTrace(); } networkStateChangeReciever = null; } } private void unRegisterReceiverP2P() { WiFiDirectBroadcastReceiver wiFiDirectBroadcastReceiver = p2pStateChangeReciever; if (wiFiDirectBroadcastReceiver != null) { try { context.unregisterReceiver(wiFiDirectBroadcastReceiver); } catch (IllegalArgumentException e) { e.printStackTrace(); } p2pStateChangeReciever = null; } } private void onScanResultAvailable() { boolean z; int existSimpleApDisabled; long elapsedRealtime = SystemClock.elapsedRealtime(); if (Build.VERSION.SDK_INT >= 17) { z = true; } else { long j = lastScan; if (j != 0 && elapsedRealtime - j < 30000) { EPLog.i(TAG, "onScanResultAvailable, use this Result"); z = true; } else if (retryScaning > 0) { EPLog.i(TAG, "onScanResultAvailable, use this Retry Result"); z = true; } else { EPLog.w(TAG, "onScanResultAvailable, ignore this Result"); z = false; } } if (z) { List arrayList = new ArrayList<>(); try { arrayList = mWifiManager.getScanResults(); } catch (SecurityException e) { e.printStackTrace(); } if (arrayList.size() != 0) { for (ScanResult scanResult : arrayList) { if (retryScaning < 3 && Build.VERSION.SDK_INT >= 17) { long j2 = elapsedRealtime - (scanResult.timestamp / 1000); if (j2 >= 30000) { EPLog.w(TAG, "onScanResultAvailable, Ignore for timeout : SSID =" + scanResult.SSID + " past " + j2 + " msec"); } } String removeQuotationsInSSID = WiFiUtils.removeQuotationsInSSID(scanResult.SSID); if (WiFiControl.isSimpleAP(removeQuotationsInSSID)) { int networkId = WiFiUtils.getInstance(context).getNetworkId(removeQuotationsInSSID); if (networkId != -1) { onFindPrinterResult(WiFiControl.addSSIDPrefix(removeQuotationsInSSID, WiFiControl.ConnectType.SimpleAP), networkId, scanResult.BSSID); } else if (Build.VERSION.SDK_INT < 23 && (existSimpleApDisabled = WiFiUtils.getInstance(context).getExistSimpleApDisabled(removeQuotationsInSSID)) != -1) { onFindPrinterResult(WiFiControl.addSSIDPrefix(removeQuotationsInSSID, WiFiControl.ConnectType.SimpleAP), existSimpleApDisabled, scanResult.BSSID); } } } } } lastScan = elapsedRealtime; retryScaning++; if (retryScaning < 5) { EPLog.i(TAG, "Retry startScan()"); mWifiManager.startScan(); return; } EPLog.i(TAG, "MAX_RETRY_SCANING"); unRegisterReceiverSimpleAp(); serarchingStatus &= -2; if (serarchingStatus == 0) { mHandler.sendEmptyMessage(idResult); interrupt(); } } private void onFindPrinterResult(String str, int i, String str2) { if (listFoundSSID.contains(str)) { listFoundSSID.add(str); SimpleAPInfoDB.SimpleAPInfo simpleAPInfoDB = SimpleAPInfoDB.getSimpleAPInfoDB(context, str); if (simpleAPInfoDB == null) { simpleAPInfoDB = new SimpleAPInfoDB.SimpleAPInfo(); simpleAPInfoDB.ssid = str; WiFiControl.getInstance(context); simpleAPInfoDB.printerName = WiFiControl.getPrinterNetworkName(str); } Message obtain = Message.obtain(); obtain.what = idResult; Bundle bundle = new Bundle(); bundle.putString("ssid", simpleAPInfoDB.ssid); bundle.putString("name", simpleAPInfoDB.printerName); bundle.putInt("id", i); bundle.putString(MACADDR_P2P, str2); if (-1 != i) { bundle.putString(MACADDR_INFRA, WiFiControl.p2pAddr2PtrAddr(str2, (String) null)); } else { bundle.putString(MACADDR_INFRA, WiFiControl.p2pAddr2PtrAddr(str2, simpleAPInfoDB.ssid)); } EPLog.d(TAG, "onFindPrinterResult() data = " + bundle.getString("ssid") + CommonDefine.SLASH + bundle.getString("name") + CommonDefine.SLASH + bundle.getString(MACADDR_INFRA) + CommonDefine.SLASH + bundle.getString(MACADDR_P2P)); obtain.setData(bundle); mHandler.sendMessage(obtain); } } class NetworkStateChangeReciever extends BroadcastReceiver { NetworkStateChangeReciever() { } public void onReceive(Context context, Intent intent) { if (intent.getAction().equals("android.net.wifi.SCAN_RESULTS")) { EPLog.d(SearchWiFiDirectPrinterTask.TAG, "Scan Results Available"); onScanResultAvailable(); } } } class WiFiDirectBroadcastReceiver extends BroadcastReceiver { WiFiDirectBroadcastReceiver() { } public void onReceive(Context context, Intent intent) { WifiP2pDeviceList wifiP2pDeviceList; if (intent.getAction().equals("android.net.wifi.p2p.PEERS_CHANGED") && (wifiP2pDeviceList = (WifiP2pDeviceList) intent.getParcelableExtra("wifiP2pDeviceList")) != null) { Collection deviceList = wifiP2pDeviceList.getDeviceList(); if (deviceList.size() == 0) { EPLog.d(SearchWiFiDirectPrinterTask.TAG, "No devices found"); return; } for (WifiP2pDevice next : deviceList) { if (next.deviceName == null || next.deviceName.trim().isEmpty()) { EPLog.w(SearchWiFiDirectPrinterTask.TAG, "deviceName is empty" + next.deviceAddress); } else if (!WifiP2pUtils.PrimaryDeviceType.isPrinter(next.primaryDeviceType)) { EPLog.i(SearchWiFiDirectPrinterTask.TAG, "Category Not Printer " + next.deviceName); } else if (MacAddrFilter.getInstance(context).isExcludedMacAddress(WiFiControl.p2pAddr2PtrAddr(next.deviceAddress, next.deviceName))) { EPLog.i(SearchWiFiDirectPrinterTask.TAG, "Excluded Printer " + next.deviceName); } else { onFindPrinterResult(WiFiControl.addSSIDPrefix(next.deviceName, WiFiControl.ConnectType.WiFiP2P), -1, next.deviceAddress); } } EPLog.i(SearchWiFiDirectPrinterTask.TAG, "Continue discover Peers()"); } } } class ScanningObserver { AsyncTask observerTask = null; ScanningObserver() { } private void start(final int i) { interrunpt(); EPLog.d(SearchWiFiDirectPrinterTask.TAG, "Start ScanningObserver"); observerTask = new AsyncTask() { protected Void doInBackground(Void... voidArr) { int i = 0; do { try { if (i >= i) { return null; } Thread.sleep(100); i += 100; } catch (InterruptedException e) { e.printStackTrace(); return null; } } while (!isCancelled()); return null; } protected void onPostExecute(Void voidR) { EPLog.i(SearchWiFiDirectPrinterTask.TAG, "Timeout ScanningObserver"); SearchWiFiDirectPrinterTask.mHandler.sendEmptyMessage (idResult); interrupt(); } }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new Void[0]); } private void interrunpt() { AsyncTask asyncTask = observerTask; if (asyncTask != null && asyncTask.getStatus() == AsyncTask.Status.RUNNING && !this.observerTask.isCancelled()) { EPLog.d(SearchWiFiDirectPrinterTask.TAG, "Stop ScanningObserver"); observerTask.cancel(false); } } } }