package com.geek.wonderful.filemanager.view.operation.viewhelper.smb;
import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.widget.TextView;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import jcifs.netbios.NbtAddress;
import rx.Observable;
import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.functions.Func1;
import rx.schedulers.Schedulers;
import com.geek.wonderful.filemanager.assistant.busevent.EventBusHelper;
import com.geek.wonderful.filemanager.assistant.constant.DataConstant;
import com.geek.wonderful.filemanager.assistant.utils.TimeUtils;
import com.geek.wonderful.filemanager.orm.dao.SmbAccount;
import com.geek.wonderful.filemanager.orm.dao.base.SmbAccountDao;
import com.geek.wonderful.filemanager.orm.helper.DbUtils;
import com.geek.wonderful.filemanager.view.customview.animation.ScanAnimation;
import com.geek.wonderful.filemanager.view.customview.bottomview.BottomViewMgr;
/**
* Created by nizi on 2015/1/14.
*/
public class ScanLAN {
public static final int SUBNET_IP_COUNT = 254;
private static ScanLAN instance = null;
private ConcurrentLinkedQueue<String> allLANQueue1 = new ConcurrentLinkedQueue<>();
private ConcurrentLinkedQueue<String> allLANQueue2 = new ConcurrentLinkedQueue<>();
private ConcurrentLinkedQueue<String> lanQueue = new ConcurrentLinkedQueue<>();
private AtomicBoolean thread1Finish = new AtomicBoolean(false);
private AtomicBoolean thread2Finish = new AtomicBoolean(false);
private Subscription subscription;
private long startTime = 0;
private Subscription timer;
private AtomicBoolean endTimer = new AtomicBoolean(false);
private int curCheckSize = 1;
public List<Socket> connectSocket = new ArrayList<>();
private ScanLAN() {
}
public static ScanLAN getInstance() {
if (instance == null) {
instance = new ScanLAN();
}
return instance;
}
public void stopScan() {
allLANQueue1.clear();
allLANQueue2.clear();
thread1Finish.set(false);
thread2Finish.set(false);
endTimer.set(false);
if (subscription != null && subscription.isUnsubscribed()) {
subscription.unsubscribe();
}
if (timer != null && timer.isUnsubscribed()) {
timer.unsubscribe();
}
}
private List<String> getUserInfo() {
List<String> userList = new ArrayList<>();
List<SmbAccount> list = DbUtils.getSmbAccountHelper().queryBuilder().list();
for (SmbAccount smbAccount : list) {
userList.add(smbAccount.getServeraddress());
}
return userList;
}
public void addAllAddress(Context context, TextView ipTv, TextView leftTimeTv, ScanAnimation scanAnimation) {
stopScan();
String address = getIp(context);
List<String> userList = getUserInfo();
for (int i = 0; i <= SUBNET_IP_COUNT; i++) {
String cur = address + i;
if (!userList.contains(cur)) {
if (i % 2 != 0) {
allLANQueue2.add(cur);
} else {
allLANQueue1.add(cur);
}
}
}
curCheckSize = userList.size();
showTime(leftTimeTv);
getLAN(allLANQueue1, ipTv, leftTimeTv, thread1Finish);
getLAN(allLANQueue2, ipTv, leftTimeTv, thread2Finish);
addressToNameMethod(scanAnimation);
}
private void showTime(final TextView leftTimeTv) {
startTime = System.currentTimeMillis();
timer = Observable.interval(500, 500, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.filter(new Func1<Long, Boolean>() {
@Override
public Boolean call(Long aLong) {
long useTime = System.currentTimeMillis() - startTime;
if (useTime > 0) {
long speed = useTime / 1000;
if (speed != 0 && speed % 2 == 0) {
leftTimeTv.setText(TimeUtils.secToTime(((SUBNET_IP_COUNT - curCheckSize) / speed)));
}
}
return endTimer.get();
}
})
.subscribe(new Action1<Long>() {
@Override
public void call(Long aLong) {
timer.unsubscribe();
}
});
}
private void addressToNameMethod(final ScanAnimation scanAnimation) {
try {
subscription = Observable.interval(0, 70, TimeUnit.MILLISECONDS)
.observeOn(Schedulers.io())
.filter(new Func1<Long, Boolean>() {
@Override
public Boolean call(Long aLong) {
if (!lanQueue.isEmpty()) {
String rightAddress = lanQueue.poll();
if (null != rightAddress) {
insertToDb(rightAddress);
}
}
return thread1Finish.get() && thread2Finish.get() && lanQueue.isEmpty();
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Long>() {
@Override
public void call(Long aLong) {
subscription.unsubscribe();
scanAnimation.cancelAnimation();
endTimer.set(true);
EventBusHelper.refreshSpecifyFragment(DataConstant.SMB_ACCOUNT_ID);
BottomViewMgr.hideBottomView();
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
try {
Thread.sleep(500);
subscription.unsubscribe();
scanAnimation.cancelAnimation();
endTimer.set(true);
EventBusHelper.refreshSpecifyFragment(DataConstant.SMB_ACCOUNT_ID);
BottomViewMgr.hideBottomView();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
} catch (Exception e) {
e.printStackTrace();
subscription.unsubscribe();
}
}
private void getLAN(ConcurrentLinkedQueue<String> allLANQueue, final TextView ipTv, final TextView leftTimeTv, final AtomicBoolean finished) {
Observable.from(allLANQueue)
.observeOn(Schedulers.newThread())
.map(new Func1<String, String>() {
@Override
public String call(String address) {
boolean result = false;
try {
if (address != null) {
Socket socket = new Socket();
SocketAddress socketAddress = new InetSocketAddress(address, 139);
socket.connect(socketAddress, 100);
result = true;
connectSocket.add(socket);
}
} catch (Exception e) {
result = false;
e.printStackTrace();
}
if (result) {
lanQueue.add(address);
}
curCheckSize += 1;
return address;
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
finished.set(true);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(String address) {
ipTv.setText(address);
// int percent = (curCheckSize * 100) / SUBNET_IP_COUNT;
}
});
}
private String getIp(Context context) {
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
//检查Wifi状态
if (!wm.isWifiEnabled())
wm.setWifiEnabled(true);
WifiInfo wi = wm.getConnectionInfo();
//获取32位整型IP地址
int ipAdd = wi.getIpAddress();
//把整型地址转换成“*.*.*.*”地址
String ip = intToIp(ipAdd);
ip = ip.substring(0, ip.lastIndexOf(".") + 1);
return ip;
}
private String intToIp(int i) {
return (i & 0xFF) + "." +
((i >> 8) & 0xFF) + "." +
((i >> 16) & 0xFF) + "." +
(i >> 24 & 0xFF);
}
public synchronized void insertToDb(String address) {
final SmbAccount smbAccount = new SmbAccount();
try {
NbtAddress nbt = NbtAddress.getByName(address);
if (nbt != null && nbt.isActive()) {
NbtAddress[] all = NbtAddress.getAllByAddress(nbt);
for (NbtAddress n : all) {
if (!n.isGroupAddress() && n.getNameType() == 0) {
if (n.getHostName() != null) {
smbAccount.setPcname(n.getHostName());
}
}
}
}
} catch (UnknownHostException e) {
e.printStackTrace();
return;
}
smbAccount.setServeraddress(address);
smbAccount.setIsscan("true");
smbAccount.setIslogin("false");
smbAccount.setAnonymous("true");
smbAccount.setLoginTime(TimeUtils.getCurrentTime());
SmbAccount account = DbUtils.getSmbAccountHelper().queryBuilder()
.where(SmbAccountDao.Properties.Serveraddress.eq(address),
SmbAccountDao.Properties.Anonymous.eq("true")).unique();
if (account == null) {
DbUtils.getSmbAccountHelper().save(smbAccount);
}
}
}
package com.geek.wonderful.filemanager.assistant.searchengine.implement;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import com.geek.wonderful.filemanager.assistant.searchengine.SearchEngine;
import com.geek.wonderful.filemanager.assistant.searchengine.SearchResultHelper;
public class SQLEngine extends EngineBase implements SearchEngine {
private ConcurrentLinkedQueue<File> qualifiedFileQueue = new ConcurrentLinkedQueue<>();
private SearchResultHelper mResultHelper;
private ArrayList<AtomicBoolean> mFinishFlags;
private ExecutorService mService;
private int mThreadNum;
private boolean mContainFile;
public SQLEngine(SearchResultHelper resultHelper, int threadNum, boolean containFile) {
this.mResultHelper = resultHelper;
this.mThreadNum = threadNum;
this.mService = Executors.newCachedThreadPool();
this.mContainFile = containFile;
mFinishFlags = new ArrayList<>();
for (int index = 0; index < threadNum; index++) {
mFinishFlags.add(new AtomicBoolean(false));
}
}
@Override
public void indexFiles(File rootFile) throws Exception {
if (rootFile.exists()) {
List<Object> fileList = new ArrayList<>();
File[] files = rootFile.listFiles();
for (File file : files) {
if (!blackList.contains(file.getName().toLowerCase())) {
addToContentList(file, fileList);
}
}
mResultHelper.batchInsert(fileList);
for (int index = 0; index < mThreadNum; index++) {
mService.execute(new SearchThread(index));
}
}
}
private void addToContentList(File file, List<Object> contentList) {
if (isQualified(file)) {
Object object = mResultHelper.getContentObject(file);
if (object != null) {
contentList.add(object);
}
}
}
protected boolean isQualified(File file) {
if (file.isDirectory()) {
qualifiedFileQueue.add(file);
return true;
} else {
return mContainFile;
}
}
@Override
public void stopSearch() throws Exception {
qualifiedFileQueue.clear();
mService.shutdownNow();
}
@Override
public void onStart() throws Exception {
}
private class SearchThread implements Runnable {
private int mIndex;
public SearchThread(int index) {
this.mIndex = index;
}
@Override
public void run() {
indexFilesMethod();
mFinishFlags.get(mIndex).set(true);
while (true) {
int allFinished = 0;
for (int index = 0; index < mThreadNum; index++) {
allFinished += mFinishFlags.get(index).get() ? 1 : 0;
}
if (allFinished == mThreadNum) {
break;
} else {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private void indexFilesMethod() {
List<Object> contentList = new ArrayList<>();
int length;
int index;
while (!qualifiedFileQueue.isEmpty()) {
File dir = qualifiedFileQueue.poll();
if (dir == null) {
continue;
}
File[] files = dir.listFiles();
if (null == files || files.length == 0) {
continue;
}
length = files.length;
for (index = 0; index < length / 4; index += 4) {
addToContentList(files[index], contentList);
addToContentList(files[index + 1], contentList);
addToContentList(files[index + 2], contentList);
addToContentList(files[index + 3], contentList);
}
for (; index < length; index++) {
addToContentList(files[index], contentList);
}
if ((contentList.size() + 1) % 25 == 0) {
mResultHelper.batchInsert(contentList);
contentList.clear();
try {
Thread.sleep(150);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
if (!contentList.isEmpty()) {
mResultHelper.batchInsert(contentList);
}
}
}
}