vysor_vysor原理 - CSDN
  • vysor_2_1_7_0.zip

    2020-07-30 23:33:16
    vysor2.7安装,包教包会,符有详细安装步骤和常见错误,如有问题,请参照我的博客,可以写评论提问哦,https://mp.csdn.net/postedit/103765649
  • 破解vysor为专业版

    千次阅读 2017-01-19 15:53:56
    \Users\Administrator\AppData\Local\Google\Chrome\User Data\Default\Extensions\gidgenkbbabolejbgbpnhbimgjbffefm\1.6.3_02、修改uglify.js文件中的(如果找不到这样的代码,请从低版本的vysor中复制一份并替换...

    1、找到Google浏览器插件位置

    C:\Users\Administrator\AppData\Local\Google\Chrome\User Data\Default\Extensions\gidgenkbbabolejbgbpnhbimgjbffefm\1.6.3_0

    2、修改uglify.js文件中的(如果找不到这样的代码,请从低版本的vysor中复制一份并替换uglify.js)

    function e() {
    
      this.licensed = true;
    
      this.licenseCached = true
    
    }

    当然你也可以直接复制这段代码,覆盖原uglify.js文件

    function nextTick(e){setTimeout(e,0)}function make4Len16(e){var t=e.toString(16);while(t.length<4){t="0"+t}return t}function encode_utf8(e){return unescape(encodeURIComponent(e))}function decode_utf8(e){return decodeURIComponent(escape(e))}function ab2str(e){if(e.constructor.name=="ArrayBuffer"){e=new Uint8Array(e)}return decode_utf8(String.fromCharCode.apply(null,e))}function str2ab(e,t,n){e=encode_utf8(e);var r=e.length;if(n)r++;if(!t){t=new ArrayBuffer(r)}var o=new Uint8Array(t);if(n)o[e.length]=0;for(var i=0,s=e.length;i<s;i++){o[i]=e.charCodeAt(i)}return t}var slashN="\n".charCodeAt(0);function writeLine(e,t,n){if(t.constructor.name=="Object")t=JSON.stringify(t);writeString(e,t+"\n",n)}function readLine(e,t){var n=[];function r(){e.read(function(o){for(var i=0;i<o.byteLength;i++){if(o[i]==slashN){var s=o.subarray(0,i);n.push(s);var c="";for(var a in n){a=n[a];c+=ab2str(a)}var l=o.subarray(i+1);e.unshift(l);t(c);return}}n.push(o);r()})}r()}function readString(e,t){var n="";e.onClose=function(){t(n)};function r(t){n+=ab2str(t);e.read(r)}e.read(r)}function writeString(e,t,n){if(t.constructor.name=="Object")t=JSON.stringify(t);e.write(str2ab(t),n)}function appendBuffer(e,t){var n=new Uint8Array(e.byteLength+t.byteLength);n.set(e,0);n.set(t,e.byteLength);return n}var timeThing=(new Date).getTime();function timeTrace(e){var t=(new Date).getTime();console.log(e+": "+(t-timeThing));timeThing=t}function bufferToHex(e){var t=new Uint8Array(e);var n="";for(var r in t){r=t[r];if(r<16)n+="0"+r.toString(16);else n+=r.toString(16)}return n}function hexToBuffer(e){var t=new ArrayBuffer(e.length/2);var n=new Uint8Array(t);for(var r=0;r<e.length/2;r++){var o=e.substr(r*2,2);n[r]=parseInt(o,16)}return t}function base64ToArrayBuffer(e){var t=window.atob(e);var n=t.length;var r=new Uint8Array(n);for(var o=0;o<n;o++){var i=t.charCodeAt(o);r[o]=i}return r.buffer}function arrayBufferToBase64(e){var t="";var n=new Uint8Array(e);var r=n.byteLength;for(var o=0;o<r;o++){t+=String.fromCharCode(n[o])}return window.btoa(t)}var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var b64pad="=";function hex2b64(e){var t;var n;var r="";for(t=0;t+3<=e.length;t+=3){n=parseInt(e.substring(t,t+3),16);r+=b64map.charAt(n>>6)+b64map.charAt(n&63)}if(t+1==e.length){n=parseInt(e.substring(t,t+1),16);r+=b64map.charAt(n<<2)}else if(t+2==e.length){n=parseInt(e.substring(t,t+2),16);r+=b64map.charAt(n>>2)+b64map.charAt((n&3)<<4)}while((r.length&3)>0){r+=b64pad}return r}if(!String.prototype.startsWith){Object.defineProperty(String.prototype,"startsWith",{enumerable:false,configurable:false,writable:false,value:function(e,t){t=t||0;return this.lastIndexOf(e,t)===t}})}function getQueryVariable(e,t){if(!t)t=window.location;var n=t.search.substring(1);var r=n.split("&");for(var o=0;o<r.length;o++){var i=r[o].split("=");if(decodeURIComponent(i[0])==e){return decodeURIComponent(i[1])}}}Object.fromArray=function(e){var t={};for(var n in e){var r=e[n];t[r]=r}return t};$.ajaxTransport("+binary",function(e,t,n){if(window.FormData&&(e.dataType&&e.dataType=="binary"||e.data&&(window.ArrayBuffer&&e.data instanceof ArrayBuffer||window.Blob&&e.data instanceof Blob))){return{send:function(t,n){var r=new XMLHttpRequest,o=e.url,i=e.type,s=e.async||true,c=e.responseType||"blob",a=e.data||null,l=e.username||null,u=e.password||null;r.addEventListener("load",function(){var t={};t[e.dataType]=r.response;n(r.status,r.statusText,t,r.getAllResponseHeaders())});r.open(i,o,s,l,u);for(var d in t){r.setRequestHeader(d,t[d])}r.responseType=c;r.send(a)},abort:function(){n.abort()}}}});function throttleTimeout(e,t,n,r){if(!e)e={items:[]};e.items.push(t);if(!e.timeout){e.timeout=setTimeout(function(){delete e.timeout;r(e.items);e.items=[]},n)}return e}function copyTextToClipboard(e){var t=document.createElement("textarea");t.style.position="fixed";t.style.top=0;t.style.left=0;t.style.width="2em";t.style.height="2em";t.style.padding=0;t.style.border="none";t.style.outline="none";t.style.boxShadow="none";t.style.background="transparent";t.value=e;document.body.appendChild(t);t.select();try{var n=document.execCommand("copy")}catch(r){console.log("Oops, unable to copy")}document.body.removeChild(t)}function showNotification(e,t){console.log("notification:",e);if(!window.chrome||!window.chrome.notifications)return;var n=chrome.runtime.getManifest();var r=n.name;t=t||n.icons[128];chrome.notifications.create({type:"basic",iconUrl:t,title:r,message:e})}var blobFromUrl=function(){var e={};return function(t,n){if(e[t]){n(e[t]);return}var r=new XMLHttpRequest;r.open("GET",t,true);r.responseType="blob";r.onload=function(r){n(e[t]=window.URL.createObjectURL(this.response))};r.send()}}();function Success(){}(function(){function*e(){}var t=e();t.constructor.prototype.async=function(){var e=this;var t=e.next();if(t.done)return;function n(){t=e.throw(new Error(arguments));o()}function r(){var n=arguments[0];t=e.next(n);o()}function o(o){var i;var s;if(t.done)return;if(!t.value){t=e.next(r);return}if(t.value.constructor==Promise){t.value.then(r).catch(n);return}if(t.value==Error){i=true;t=e.next(n)}else if(t.value==Success){s=true;t=e.next(r)}else{throw new Error("Unexpected yield value for callback. Only Error and Success allowed.")}if(!t.value)throw new Error("Double yield callbacks must explicitly define both Error and Success");if(t.value==Error&&i)throw new Error("Error callback already defined");else if(t.value==Success&&s)throw new Error("Success callback already defined");else if(t.value!=Error&&t.value!=Success)throw new Error("Unexpected yield value for callback. Only Error and Success allowed.");if(i)t=e.next(r);else t=e.next(n)}o()}})();function spewSocket(e){e.read(function(t){console.log(ab2str(t));spewSocket(e)})}function getAuthToken(e,t){if(!window.chrome||!window.chrome.identity){console.error("no auth token implemented");process.nextTick(t);return}chrome.identity.getAuthToken({interactive:e,scopes:["https://www.googleapis.com/auth/userinfo.profile","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/chromewebstore.readonly"]},function(e){if(!e)console.error("unable to get authToken",chrome.runtime.lastError);t(e)})}window.isElectron=function(){return navigator.userAgent.indexOf("Electron")!=-1};if(!isElectron()){window.sharedGlobals=window}(function(){var e=console.log;var t=console.error;var n="";function r(e){try{for(var t in e){if(e[t]&&e[t].constructor!=String)e[t]=JSON.stringify(e[t])}n+=e.join(" ")+"\n"}catch(r){}}console.error=function(){t.apply(console,arguments);r(Array.prototype.slice.call(arguments))};console.log=function(){e.apply(console,arguments);r(Array.prototype.slice.call(arguments))};sharedGlobals.getConsoleLog=function(e){e(n)};function o(e){return new Promise(function(t,n){if(!e.getConsoleLog){t("getConsoleLog not found");return}e.getConsoleLog(function(e){t({content:e})})})}window.gistConsoleLog=function(e,t){chrome.runtime.getBackgroundPage(function(n){o(n).then(function(t){e["background.txt"]=t;var n=chrome.app.window.getAll();var r=n.map(function(t){return o(t.contentWindow).then(function(n){e["window-"+t.id+".txt"]=n})});return Promise.all(r)}).then(function(){var n={description:chrome.runtime.getManifest().name+" console log","public":false,files:e};fetch("https://api.github.com/gists",{method:"POST",body:JSON.stringify(n)}).then(function(e){e.json().then(function(e){t(e.html_url)})})})})}})();(function(){function e(e){this.buffer=new ArrayBuffer(e);this.dataView=new DataView(this.buffer);this.uint8array=new Uint8Array(this.buffer);this.littleEndian=false;this.position=0;this.limit=e;this.capacity=e}e.prototype.flip=function(){this.limit=this.position;this.position=0};e.prototype.asUint8Array=function(){return this.uint8array.subarray(this.position,this.limit)};function t(t,n){var r=n*8;var o=t+r;var i="get"+o;var s="set"+o;var c="put"+o;e.prototype[i]=function(){if(this.position+n>this.limit)throw new Error("Not enough room in byte buffer");var e=this.dataView[i](this.position,this.littleEndian);this.position+=n;return e};e.prototype[c]=function(e){if(this.position+n>this.limit)throw new Error("Not enough room in byte buffer");if(e==null||e==undefined||e==NaN||e.constructor!=Number)throw new Error("no value provided");this.dataView[s](this.position,e,this.littleEndian);this.position+=n;return this}}var n={Int:[1,2,4],Uint:[1,2,4],Float:[4,8]};for(var r in n){var o=n[r];for(var i in o){var i=o[i];t(r,i)}}e.prototype.put=function(e){if(e.constructor==Number)return this.putInt8(e);if(e.constructor==String)e=str2ab(e);if(e.constructor==ArrayBuffer)e=new Uint8Array(e);if(this.position+e.byteLength>this.limit)throw new Error("Not enough room in byte buffer");this.uint8array.set(e,this.position);this.position+=e.byteLength;return this};e.prototype.putByte=e.prototype.putInt8;e.prototype.putShort=e.prototype.putInt16;e.prototype.putInt=e.prototype.putInt32;e.prototype.putFloat=e.prototype.putFloat32;e.prototype.putDouble=e.prototype.putFloat64;window.ByteBuffer=e})();if(window.chrome&&window.chrome.sockets){chrome.sockets.tcp.onReceive.addListener(function(e){var t=Socket.readers[e.socketId];if(t==null)return;t.dataReceived(new Uint8Array(e.data))});chrome.sockets.tcp.onReceiveError.addListener(function(e){var t=Socket.readers[e.socketId];if(t==null)return;t.destroy();t.dataReceived(null)});chrome.sockets.tcpServer.onAccept.addListener(function(e){chrome.sockets.tcp.setPaused(e.clientSocketId,false);var t=Server.listeners[e.socketId];if(t==null)return;t(new Socket({socketId:e.clientSocketId}))})}(function(){function e(t,n){if(t.socketId){this.socketId=t.socketId;e.readers[this.socketId]=this}else if(window.chrome&&window.chrome.sockets){chrome.sockets.tcp.create(function(r){this.socketId=r.socketId;chrome.sockets.tcp.connect(this.socketId,t.host,t.port,function(t){if(!t){e.readers[r.socketId]=this;n(this)}else{chrome.runtime.lastError;this.destroy();n(null)}}.bind(this))}.bind(this))}else{var r;if(!t.ns){this.ns=new require("net").Socket();this.ns.connect({port:t.port,host:t.host},function(){r=true;n(this)}.bind(this))}else{this.ns=t.ns;r=true}this.ns.on("close",function(){this.destroy();if(!r)n(null)}.bind(this));this.ns.on("data",function(e){this.dataReceived(e)}.bind(this))}}e.readers={};e.connect=function(t,n){return new e(t,n)};e.pump=function(e,t,n){if(!e||!t){console.error("Socket.pump called with null socket",e,t);n();return}var r=function(){e.read(o)}.bind(e);var o=function(e){var n=e.buffer;if(e.byteOffset||e.length!=n.byteLength){n=n.slice(e.byteOffset,e.byteOffset+e.length)}t.write(n,r)}.bind(t);e.read(o);e.onClose=n};e.stream=function(t,n,r){e.pump(t,n,function(){if(n)n.destroy();if(r){var e=r;r=null;e()}});e.pump(n,t,function(){if(t)t.destroy();if(r){var e=r;r=null;e()}})};e.eat=function(e){function t(){e.read(t)}t()};e.prototype.read=function(){if(this.pendingCallback){throw new Error("double callback")}if(this.closed&&!this.pending){var e=this.onClose;if(e){delete this.onClose;e()}return}var t=0;if(arguments[t].constructor.name=="Number"){this.pendingLength=arguments[t++]}else{this.pendingLength=0}var e=arguments[t];if(!this.pending||this.paused){this.pendingCallback=e;return}if(!this.pendingLength){this.pendingLength=this.buffered()}else if(this.pendingLength>this.buffered()){this.pendingCallback=e;return}var n;var r=0;while(r<this.pendingLength){var o=this.pending.shift();this.bufferedLength-=o.length;if(!this.pending.length)delete this.pending;var i=o;var s=Math.min(i.byteLength,this.pendingLength-r);if(s!=i.byteLength){var c=i.subarray(0,s);var a=i.subarray(s);this.unshift(a);i=c}if(!n&&i.byteLength!=this.pendingLength)n=new Uint8Array(this.pendingLength);if(n){n.set(i,r)}else{n=i}r+=i.byteLength}e(n)};e.prototype.write=function(e,t){if(this.pendingWrite)console.error("write is already in progress!");if(t==null){console.error("write callback is null?");t=function(){}}this.pendingWrite=t;if(window.chrome&&window.chrome.sockets){chrome.sockets.tcp.send(this.socketId,e,function(n){chrome.runtime.lastError;if(!n||n.resultCode){delete this.pendingWrite;return}if(n.bytesSent<e.byteLength){this.write(e.slice(n.bytesSent),t)}else{delete this.pendingWrite;t()}}.bind(this))}else{if(!this.ns)return;if(!e.byteLength){require("process").nextTick(function(){delete this.pendingWrite;t()}.bind(this));return}this.ns.write(Buffer.from(e),function(){delete this.pendingWrite;t()}.bind(this))}};e.prototype.destroy=function(e,t){if(window.chrome&&window.chrome.sockets){chrome.sockets.tcp.close(this.socketId,function(){chrome.runtime.lastError})}else{this.dataReceived(null);if(this.ns){this.ns.destroy();delete this.ns}}};e.prototype.unshift=function(e){if(e.byteLength==0)return;if(!this.pending)this.pending=[e];else this.pending.unshift(e);if(!this.bufferedLength)this.bufferedLength=0;this.bufferedLength+=e.length};e.prototype.dataReceived=function(e){if(e){if(e.asUint8Array)e=e.asUint8Array();if(e.constructor==ArrayBuffer)e=new Uint8Array(e)}if(e&&e.length){var t=new Uint8Array(e);if(!this.pending)this.pending=[t];else this.pending.push(t)}if(e==null){this.closed=true}else{if(!this.bufferedLength)this.bufferedLength=0;this.bufferedLength+=e.length}if(this.paused||!this.pending||!this.pending.length){var n=this.onClose;if(this.closed&&n){delete this.onClose;n()}return}var r=this.pendingLength;var n=this.pendingCallback;if(n){delete this.pendingCallback;this.read(r,n)}};e.prototype.buffered=function(){return this.bufferedLength};e.prototype.pause=function(){if(this.paused){return}this.paused=true;this.onPause()};e.prototype.resume=function(){if(!this.paused){return}this.paused=false;this.onResume()};e.prototype.onResume=function(){chrome.sockets.tcp.setPaused(this.socketId,false,function(){})};e.prototype.onPause=function(){chrome.sockets.tcp.setPaused(this.socketId,true,function(){})};function t(){}t.listeners={};t.prototype.__proto__=e.prototype;t.prototype.destroy=function(){if(window.chrome&&window.chrome.sockets){chrome.sockets.tcpServer.close(this.socketId,function(){chrome.runtime.lastError})}else{if(this.ns){this.ns.close();delete this.ns}}};t.prototype.listen=function(n,r,o){var i;var s;if(n.constructor.name=="Number"){i=n;s="0.0.0.0"}else{s=n.address;i=n.port}if(window.chrome&&window.chrome.sockets){chrome.sockets.tcpServer.create(function(e){this.socketId=e.socketId;t.listeners[this.socketId]=r;chrome.sockets.tcpServer.listen(e.socketId,s,i,function(e){chrome.runtime.lastError;if(e){this.destroy();if(o){o(e)}return}chrome.sockets.tcpServer.getInfo(this.socketId,function(t){this.localAddress=t.localAddress;this.localPort=t.localPort;if(o){o(e)}}.bind(this))}.bind(this))}.bind(this))}else{this.ns=require("net").createServer(function(t){r(new e({ns:t}))}.bind(this));this.ns.on("close",function(){this.destroy()}.bind(this));this.ns.on("error",function(e){if(o)o(e)}.bind(this));this.ns.on("listening",function(){var e=this.ns.address();this.localAddress=e.address;this.localPort=e.port;if(o)o()}.bind(this));this.ns.listen({port:i,host:s})}};window.Socket=e;window.Server=t})();(function(){function e(){}e.prototype.listen=function(e,t,n){this.socket=new Server;this.requestCallback=t;this.socket.listen(e,this.onSocket.bind(this),n)};e.prototype.onSocket=function(e){new n(this,e,this.requestCallback)};e.prototype.destroy=function(){this.socket.destroy()};function t(e){this.request=e;this.statusLine="HTTP/1.1 200 OK";this.headers={Date:(new Date).toUTCString()}}t.prototype.code=function(e){this.statusLine="HTTP/1.1 "+e+" "+HttpResponseCodes[e]};t.prototype.write=function(e,t){if(e.constructor.name==Object.prototype.constructor.name){e=JSON.stringify(e)}if(e.constructor.name==String.prototype.constructor.name){e=str2ab(e)}if(!this.hasWritten){this.hasWritten=true;if(!this.headers["Content-Length"]&&this.headers["Connection"]!="close"){this.headers["Content-Length"]=e.byteLength}var n=[this.statusLine];for(var r in this.headers){n.push(r+": "+this.headers[r])}var o=n.join("\r\n")+"\r\n\r\n";this.request.socket.write(str2ab(o),function(){this.write(e,t)}.bind(this));return}this.request.socket.write(e,t)};t.prototype.end=function(){if(this.headers["Connection"]=="close")this.request.socket.destroy();else this.request.server.onSocket(this.request.socket);this.request.socket=null};function n(e,n,r){this.server=e;this.socket=n;this.headers={};this.parseRequest(function(){r(this,new t(this))}.bind(this))}n.prototype.parseRequest=function(e){var t=function(){readLine(this.socket,function(n){n=n.trim();if(!n.length){var r=this.headers["content-length"];if(r){r=Number.parseInt(r);this.socket.read(r,function(t){this.body=t;if(this.headers["content-type"]==="application/json"){this.body=JSON.parse(ab2str(this.body))}e()}.bind(this));return}e();return}if(!this.statusLine){this.statusLine=n;var o=n.split(" ");if(o.length>2){o=o[1].split("?");this.path=o[0];this.queries={};if(o.length>1){var i=this.query=o[1];var s=i.split("&");for(var c=0;c<s.length;c++){var a=s[c].split("=");var l=a[0];var u;if(a.length>1)u=a[1];this.queries[l]=u}}}}else{var o=n.split(":",2);if(o.length==2){this.headers[o[0].toLowerCase()]=o[1].trim()}}t()}.bind(this))}.bind(this);t()};window.HttpRequestParser=n;window.HttpServer=e;window.HttpResponseCodes={200:"OK",202:"Accepted",206:"Partial Content",101:"Switching Protocols",301:"Moved Permanently",302:"Found",402:"Payment Required",404:"Not Found"}})();function DummySocket(e){if(e){this.dataReceived(e);this.dataReceived(null)}}DummySocket.prototype.write=function(e,t){throw new Error("write not supported on dummy socket")};DummySocket.prototype.destroy=function(){this.dataReceived(null)};DummySocket.prototype.buffered=Socket.prototype.buffered;DummySocket.prototype.unshift=Socket.prototype.unshift;DummySocket.prototype.dataReceived=Socket.prototype.dataReceived;DummySocket.prototype.read=Socket.prototype.read;DummySocket.prototype.pause=Socket.prototype.pause;DummySocket.prototype.resume=Socket.prototype.resume;DummySocket.prototype.buffered=Socket.prototype.buffered;DummySocket.prototype.onPause=function(){};DummySocket.prototype.onResume=function(){};function FetchSocket(e,t){this.promise=fetch(e).then(function(e){this.connected=true;this.response=e;this.reader=this.response.body.getReader();this.reader.closed.then(function(){if(this.onClose)this.dataReceived(null)}.bind(this));this.onResume();t(this)}.bind(this),function(e){t(null,e)})}FetchSocket.connect=function(e,t){new FetchSocket(e,t)};FetchSocket.prototype.write=function(e,t){throw new Error("write not supported on fetch socket")};FetchSocket.prototype.destroy=function(){if(this.promise&&this.promise.cancel)this.promise.cancel()};FetchSocket.prototype.unshift=Socket.prototype.unshift;FetchSocket.prototype.dataReceived=Socket.prototype.dataReceived;FetchSocket.prototype.read=Socket.prototype.read;FetchSocket.prototype.pause=Socket.prototype.pause;FetchSocket.prototype.resume=Socket.prototype.resume;FetchSocket.prototype.buffered=Socket.prototype.buffered;FetchSocket.prototype.onPause=function(){};FetchSocket.prototype.onResume=function(){this.reader.read().then(function(e){if(!e.value)return;this.dataReceived(e.value);if(this.paused){return}this.onResume()}.bind(this))};(function(){function e(e,t){this.conn=e;this.dc=t;this.gotEof=false;t.onmessage=function(e){var t=new Uint8Array(e.data);var n=t[t.byteLength-1]==1;this.dataReceived(t.subarray(0,t.byteLength-1));if(n){this.gotEof=true;this.destroy()}}.bind(this);t.onclose=t.onerror=this.destroy.bind(this);this.needsBufferShim=true||parseInt(/Chrome\/(\d\d)/.exec(navigator.userAgent)[1])<46}e.prototype.buffered=Socket.prototype.buffered;e.prototype.unshift=Socket.prototype.unshift;e.prototype.dataReceived=Socket.prototype.dataReceived;e.prototype.read=Socket.prototype.read;e.prototype.pause=Socket.prototype.pause;e.prototype.resume=Socket.prototype.resume;e.prototype.buffered=Socket.prototype.buffered;e.prototype.writeable=function(){var e=this.writeCallback;if(e){delete this.writeCallback;e()}};e.prototype.write=function(e,t){if(!this.dc||this.dc.readyState!="open"){this.destroy();return}this.writeCallback=t;var n=new Uint8Array(e.byteLength+1);n.set(new Uint8Array(e));this.dc.send(n.buffer);if(this.reentrantWrite)return;try{this.reentrantWrite=true;while(this.writeCallback&&(this.dc.bufferedAmount==0||this.needsBufferShim)){this.writeable()}}finally{this.reentrantWrite=false}};e.prototype.destroy=function(){this.dataReceived(null);if(this.dc==null)return;var e=this.dc;this.dc=null;e.onclose=null;e.onerror=null;if(e.readyState=="open"){try{e.send(new Uint8Array([1]));if(this.gotEof)this.conn.recycleChannel(e);else this.conn.waitForEof(e)}catch(t){}}};function t(e,t,n){this.manager=e;this.pc=t;this.key=n;this.pc.oniceconnectionstatechange=function(){if(this.pc.iceConnectionState!="new"&&this.pc.iceConnectionState!="checking"){delete e.gcmRtcConnections[n]}if(this.pc.iceConnectionState=="disconnected"||this.pc.iceConnectionState=="closed"){this.destroy()}}.bind(this)}t.prototype.waitForCommand=function(t){t.onmessage=function(n){if(n.data.byteLength==1)return;this.removeChannel(t);var r=ab2str(n.data);var o=new e(this,t);this.openSocket(r,o)}.bind(this)};t.prototype.compactChannels=function(){if(this.inboundChannels&&!this.inboundChannels.length)this.inboundChannels=null;if(this.outboundChannels&&!this.outboundChannels.length)this.outboundChannels=null};t.prototype.getAppropriateChannels=function(e,t){var n;if(e.inbound){if(!this.inboundChannels&&t)this.inboundChannels=[];n=this.inboundChannels}else{if(!this.outboundChannels&&t)this.outboundChannels=[];n=this.outboundChannels}return n};t.prototype.removeChannel=function(e){t;channels=this.getAppropriateChannels(e);if(!channels)return;var t=channels.indexOf(e);if(t==-1)return;channels.splice(t,1);this.compactChannels()};t.prototype.waitForEof=function(e){e.onmessage=function(t){var n=new Uint8Array(t.data);var r=n[n.byteLength-1]==1;if(r)this.recycleChannel(e)}.bind(this)};t.prototype.recycleChannel=function(e){var t=this.getAppropriateChannels(e,true);t.push(e);e.onclose=e.onerror=function(){this.removeChannel(e)}.bind(this);this.waitForCommand(e)};t.prototype.addCandidates=function(e){for(var t in e.candidates){this.pc.addIceCandidate(new RTCIceCandidate(e.candidates[t]))}};t.prototype.setupPinger=function(e){var t;function n(){e.send(str2ab("ping"));t=setTimeout(n,1e3)}e.onmessage=function(e){};e.onclose=e.onerror=function(){clearTimeout(t);this.destroy()}.bind(this);n()};t.prototype.listenSockets=function(){this.pc.ondatachannel=function(e){e.channel.inbound=true;this.waitForCommand(e.channel)}.bind(this)};t.prototype.prepareChannel=function(e){var t=this.pc.createDataChannel(e||"gcm",{reliable:true,ordered:true});t.binaryType="arraybuffer";return t};t.prototype.newSocket=function(t,n){if(this.pc.signalingState=="closed"){n();return}if(this.outboundChannels){var r=this.outboundChannels.shift();this.compactChannels();r.send(str2ab(t));var o=new e(this,r);n(o,this);return}var r=this.prepareChannel("gcm");r.onopen=function(){r.send(str2ab(t));var o=new e(this,r);n(o,this)}.bind(this)};t.prototype.destroy=function(){delete this.manager.gcmRtcConnections[this.key];if(this.pc.signalingState!="closed"){this.pc.close()}var e=this.onClose;if(e){delete this.onClose;e()}};function n(e,t,n){this.senders=e;this.registrationId=t;this.rtcc=n;this.gcmRtcConnections={};this.gcmRtcListeners={}}n.prototype.onMessage=function(e){var t=JSON.parse(e.message);var r=e.type;var o=e.senderId;var i=e.src;var s=e.srcPort;var c=e.dstPort;if(r=="offer"){var a=this.gcmRtcListeners[c];if(!a)console.log("not listening on "+c);else a.listener.incoming(o,i,s,c,t,a.listenCallback);return}else if(r=="answer"){var l=n.getKey(i,s,c);var u=this.gcmRtcConnections[l];if(!u){console.log("pending connection not found");return}u.manager.incoming(o,i,s,c,t);return}else if(n.onUnknownMessage){n.onUnknownMessage(e)}else{console.log("unknown message "+r)}};n.hasLoadedChannels=false;n.start=function(e,t,r){console.log("starting GtcRtcManger");if(window.chrome&&window.chrome.gcm){var o=Object.keys(e);chrome.gcm.register(o,function(o){chrome.runtime.lastError;if(!o){r();return}var i=new n(e,o,t);chrome.gcm.onMessage.addListener(function(e){i.onMessage(e.data)});r(i)})}else{function i(){n.hasLoadedChannels=true;var o=new n(e,null,t);function i(e){return function(){var t=arguments;o.ensureChannel().then(function(){e.apply(o,t)})}}o.listen=i(o.listen);o.connect=i(o.connect);o.ensureChannel().then(function(){r(o)})}if(n.hasLoadedChannels){i()}else{$.getScript("https://vysor-1026.appspot.com/_ah/channel/jsapi",i)}}};n.prototype.ensureChannel=function(){var e=this;if(this.channelPromise){return this.channelPromise}return this.channelPromise=new Promise(function(t,n){$.ajax({type:"GET",url:"https://vysor-1026.appspot.com/listen",success:function(n){var r=new goog.appengine.Channel(n.token);var o={onopen:function(){var r="web:"+n.channel;e.registrationId=r;if(e.onRegistrationIdChanged)e.onRegistrationIdChanged(r);t()},onmessage:function(t){e.onMessage(JSON.parse(t.data))},onerror:function(){console.error("gcm onerror",arguments);e.channelPromise=null},onclose:function(){console.error("gcm onclose",arguments);e.channelPromise=null;e.gcmRtcConnections={};if(!Object.keys(e.gcmRtcListeners).length){console.log("not reconnecting, no listeners");return}console.error("reconnecting gcm");e.reconnectTimeout=throttleTimeout(e.reconnectTimeout,null,5*60*1e3,function(){e.ensureChannel()})}};var i=r.open(o)}})})};n.prototype.sendGcm=function(e,t,n,r,o,i){if(!e)e=this.defaultSenderId;if(t.startsWith("web:")){$.ajax({type:"POST",url:"https://vysor-1026.appspot.com/send",data:JSON.stringify({channel:t.substring(4),data:{senderId:e,src:this.registrationId,srcPort:r,dstPort:n,type:o,message:JSON.stringify(i)}}),contentType:"application/json",dataType:"json",success:function(){}})}else{$.ajax({type:"POST",url:"https://gcm-http.googleapis.com/gcm/send",headers:{Authorization:"key="+this.senders[e]},data:JSON.stringify({to:t,data:{senderId:e,src:this.registrationId,srcPort:r,dstPort:n,type:o,message:JSON.stringify(i)}}),contentType:"application/json",dataType:"json",error:function(){console.log("gcm error",arguments)},success:function(){console.log("gcm",arguments)}})}};n.getKey=function(e,t,n){return n+":"+t+":"+e};n.prototype.setupPeerConnection=function(e,r,o,i,s,c){var a=window.RTCPeerConnection||window.webkitRTCPeerConnection;var l=new a(this.rtcc);var u;var d=function(t){var n=[];for(var a in t){a=t[a];n.push(a);if(JSON.stringify(n).length>3200){this.sendGcm(r,o,i,s,e,{desc:c(),candidates:n});n=[]}}if(n.length>0){this.sendGcm(r,o,i,s,e,{desc:c(),candidates:n})}}.bind(this);l.onicecandidate=function(e){if(e.candidate==null)return;console.log(e.candidate);u=throttleTimeout(u,e.candidate,500,d)}.bind(this);var f=n.getKey(o,i,s);var h=new t(this,l,f);l.onsignalingstatechange=function(e){if(l.signalingState=="stable"){if(this.gcmRtcConnections[f]==h){}}else if(l.signalingState=="closed"){h.destroy()}}.bind(this);this.gcmRtcConnections[f]=h;return h};n.gcmPortCount=0;n.prototype.connect=function(e,t){var r=e.senderId;var o=e.registrationId;var i=e.port;var s=n.gcmPortCount++;var c;var a=this.setupPeerConnection("offer",r,o,i,s,function(){return c});var l=a.pc;function u(e){l.createOffer(e).then(function(e){c=e;l.setLocalDescription(e)})}if(!e.audio){var d=a.prepareChannel("pinger");d.onopen=function(){console.log("got rtc pinger");a.setupPinger(d);t(a)};a.listenSockets();u({})}else{navigator.webkitGetUserMedia({audio:true,video:false},function(e){l.addStream(e);l.onaddstream=function(e){console.log("got the remote stream");t(a,e)};u({offerToReceiveAudio:true,offerToReceiveVideo:false,voiceActivityDetection:false})},function(){console.error("audio fail",arguments);u({offerToReceiveAudio:true,offerToReceiveVideo:false,voiceActivityDetection:false})})}};n.prototype.isListening=function(e){return this.gcmRtcListeners[e]!=null};n.prototype.stopListen=function(e){delete this.gcmRtcListeners[e]};n.prototype.listen=function(e,t){if(this.gcmRtcListeners[e]){console.log("already listening on gcm port "+e);return}this.gcmRtcListeners[e]={listener:this,listenCallback:t}};n.prototype.incoming=function(e,t,r,o,i,s){var c=n.getKey(t,r,o);var a=this.gcmRtcConnections[c];if(!a){var l;a=this.setupPeerConnection("answer",e,t,r,o,function(){return l});a.remoteDesc=new RTCSessionDescription(i.desc);var u=a.pc;u.ondatachannel=function(e){console.log("got rtc pinger");this.setupPinger(e.channel);s(a);this.listenSockets()}.bind(a);u.setRemoteDescription(a.remoteDesc,function(){u.createAnswer().then(function(e){l=e;u.setLocalDescription(e)},function(){console.error("answer error",arguments)})})}else if(!a.remoteDesc){a.remoteDesc=new RTCSessionDescription(i.desc);var u=a.pc;u.setRemoteDescription(a.remoteDesc)}else{}a.addCandidates(i)};window.GcmRtcSocket=e;window.GcmRtcManager=n})();(function(){function e(e,t){this.handle=e;this.iface=t;this.type="usb";for(var n in t.endpoints){n=t.endpoints[n];if(n.type=="bulk"){this.zero_mask=n.maximumPacketSize-1;if(n.direction=="in"){this.in=n}else{this.out=n}}}}e.prototype.destroy=function(){chrome.usb.releaseInterface(this.handle,this.iface.interfaceNumber,function(){chrome.runtime.lastError;chrome.usb.closeDevice(this.handle,function(){chrome.runtime.lastError})}.bind(this))};e.prototype.write=function(e,t){if(this.writing){if(!this.pendingWrites)this.pendingWrites=[];this.pendingWrites.push({data:e,callback:t});return}var n={direction:"out",endpoint:this.out.address,data:e};this.writing=true;chrome.usb.bulkTransfer(this.handle,n,function(e){chrome.runtime.lastError;this.writing=false;t(e);if(!this.pendingWrites)return;var n=this.pendingWrites.shift();if(!this.pendingWrites.length)this.pendingWrites=null;this.write(n.data,n.callback)}.bind(this))};e.prototype.read=function(e,t){var n={direction:"in",endpoint:this.in.address,length:e};chrome.usb.bulkTransfer(this.handle,n,function(e){chrome.runtime.lastError;t(e)})};function t(e){this.socket=e;this.zero_mask=(1<<30)-1;this.type="tcp";e.onClose=function(){var e=this.currentRead;if(e){delete this.currentRead;e({resultCode:-1})}}.bind(this)}t.prototype.destroy=function(){this.socket.destroy()};t.prototype.write=function(e,t){if(this.writing){if(!this.pendingWrites)this.pendingWrites=[];this.pendingWrites.push({data:e,callback:t});return}this.writing=true;this.socket.write(e,function(){this.writing=false;t({resultCode:0});if(!this.pendingWrites)return;var e=this.pendingWrites.shift();if(!this.pendingWrites.length)this.pendingWrites=null;this.write(e.data,e.callback)}.bind(this))};t.prototype.read=function(e,t){this.currentRead=t;this.socket.read(e,function(e){delete this.currentRead;t({resultCode:0,data:e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength)})})};function n(e,t){this.onConnected=t;this.transport=e;this.currentSocketId=0;this.sockets={};this.forwards={};this.maxPayload=n.MAX_PAYLOAD}n.prototype.fatal=function(e){console.log("fatal error",JSON.stringify(e));var t=this.onConnected;if(t){delete this.onConnected;t()}else if(this.onError){this.onError();delete this.onError}this.destroy()};n.prototype.destroy=function(){for(var e in this.sockets){e=this.sockets[e];e.dataReceived(null)}if(this.forwards){$.each(this.forwards,function(e,t){t.destroy()})}this.transport.destroy()};n.kCommandSYNC=1129208147,n.kCommandCNXN=1314410051,n.kCommandOPEN=1313165391,n.kCommandOKAY=1497451343,n.kCommandCLSE=1163086915,n.kCommandWRTE=1163154007,n.kCommandAUTH=1213486401;n.kAuthToken=1;n.kAuthSignature=2;n.kAuthRSAPublicKey=3;n.ADB_PROTOCOL_VERSION=16777216;n.ADB_VERSION=36;n.MAX_PAYLOAD=4096;n.checksum=function(e){e=new Uint8Array(e);var t=0;for(var n=0;n<e.byteLength;n++){t+=e[n]}return t&4294967295};n.prototype.sendMessage=function(e,t,r,o,i){if(!o){o=""}if(o.constructor.name=="String"){o=str2ab(o)}var s=true;if(!o.byteLength){s=false}if(e==n.kCommandAUTH&&t==n.kAuthSignature){s=false}if(e==n.kCommandWRTE){s=false}var c=o.byteLength;if(s){c++}if(s){
    var a=new ArrayBuffer(o.byteLength+1);var l=new Uint8Array(a);l.set(new Uint8Array(o));l[a.byteLength-1]=0;o=a}var u=new ArrayBuffer(24);var l=new DataView(u);l.setUint32(0,e,true);l.setUint32(4,t,true);l.setUint32(8,r,true);l.setUint32(12,c,true);l.setUint32(16,n.checksum(o),true);l.setUint32(20,e^4294967295,true);this.transport.write(u,function(e){if(e.resultCode){this.fatal(e)}if(!o.byteLength&&i){i()}}.bind(this));if(o.byteLength){this.transport.write(o,function(e){if(e.resultCode){this.fatal(e)}if(i){i()}}.bind(this))}};n.prototype.getKey=function(e){chrome.storage.local.get("adbkey",function(t){var n=t.adbkey;var r=new JSEncrypt({default_key_size:2048});if(!n){n=r.getPrivateKeyB64();r.setPrivateKey(n);chrome.storage.local.set({adbkey:n})}else{r.setPrivateKey(n)}e(r)})};n.prototype._convertToMinCrypt=function(e){var t=2048;var n=t/8/4;var r=BigInteger.ONE.shiftLeft(32);var o=e.n.clone();var i=BigInteger.ONE.shiftLeft(1).pow(t);var s=i.multiply(i).mod(o);var c=new Uint32Array(3+n*2);c[0]=n;c[1]=r.subtract(o.modInverse(r)).intValue();var a=n+2;for(var l=2,u=2+n;l<a;++l,++u){c[l]=o.mod(r).intValue();o=o.divide(r);c[u]=s.mod(r).intValue();s=s.divide(r)}c[c.length-1]=e.e;var d="";var f=new Uint8Array(c.buffer);for(var l=0;l<f.length;++l){var h=f[l].toString(16);if(h.length==1){d+="0"}d+=h}return hex2b64(d)+" adb@chrome"};n.prototype.sign=function(e,t){if(e==null){throw"AuthManager is not initialized"}var n=2048/8;var r=new Uint8Array(n);r[0]=0;r[1]=1;var o=[0,48,33,48,9,6,5,43,14,3,2,26,5,0,4,20];var i=n-o.length-t.byteLength;for(var s=2;s<i;s++){r[s]=255}r.set(new Uint8Array(o),i);i+=o.length;r.set(new Uint8Array(t),i);var c=new BigInteger(Array.apply([],r));return new Uint8Array(e.doPrivate(c).toByteArray()).buffer};function r(e){var t={};if(e.constructor.name!="String")e=ab2str(e);var n=e.replace("device::","").split(";");for(var r in n){r=n[r];var o=r.split("=");if(o.length==2){t[o[0]]=o[1]}}return t}n.parseConnectionPayload=r;n.prototype.handleUnknown=function(e,t){console.log("no idea what this socket is.");this.sendMessage(n.kCommandCLSE,e,t)};n.prototype.handleMessage=function(e,t){var o=e.getUint32(0,true);var i=e.getUint32(4,true);var s=e.getUint32(8,true);var c=e.getUint32(12,true);var a=e.getUint32(16,true);switch(o){case n.kCommandOPEN:if(this.onOpenSocket)this.onOpenSocket(t,i);break;case n.kCommandAUTH:console.log("auth:",this);this.getKey(function(e){if(this.sentSignature){var r=this._convertToMinCrypt(e.getKey());this.sendMessage(n.kCommandAUTH,n.kAuthRSAPublicKey,0,r);showNotification('Check your Android device and click "Allow USB Debugging".')}else{this.sentSignature=true;var o=this.sign(e.getKey(),t);this.sendMessage(n.kCommandAUTH,n.kAuthSignature,0,o,function(){})}}.bind(this));break;case n.kCommandOKAY:var l=i;var u=s;var d=this.sockets[u];if(!d){this.handleUnknown(u,l);return}var f=d.onConnected;if(f){delete d.onConnected;d.remoteId=l;f(d)}var h=d.pendingWrite;if(h){f=d.wrote;delete d.wrote;delete d.pendingWrite;d.write(h,f);return}f=d.wrote;if(f){delete d.wrote;f()}break;case n.kCommandCNXN:this.rawProperties=ab2str(t);this.properties=r(t);var f=this.onConnected;if(f){delete this.onConnected;f(this)}break;case n.kCommandWRTE:var l=i;var u=s;var d=this.sockets[u];if(!d){this.handleUnknown(u,l);return}if(!d.paused){this.sendMessage(n.kCommandOKAY,d.localId,d.remoteId)}d.dataReceived(new Uint8Array(t));break;case n.kCommandCLSE:var l=i;var u=s;var d=this.sockets[u];if(!d){console.log("asked to close unknown socket?");return}delete this.sockets[u];d.destroy();var f=d.onConnected;if(f){delete d.onConnected;f()}break;default:console.log("unknown command: ",o.toString(16),i,s,t);break}};n.prototype.onReceiveMessage=function(e){if(e.resultCode){this.fatal(e);return}var t=new DataView(e.data);var r=t.getUint32(12,true);if(!r){try{this.handleMessage(t,null)}finally{this.receiveMessages()}return}this.transport.read(r,function(e){if(e.resultCode){this.fatal(e);return}var r=e.data;if(n.checksum(r)!=t.getUint32(16,true)){this.receiveMessages();return}try{this.handleMessage(t,r)}finally{this.receiveMessages()}}.bind(this))};n.prototype.receiveMessages=function(){this.transport.read(24,this.onReceiveMessage.bind(this))};n.prototype.forwardPort=function(e){var t=new Server;t.listen({port:e.fromPort,address:"127.0.0.1"},function(t){this.newSocket(e.to,function(e){if(e)Socket.stream(t,e);else t.destroy()}.bind(this))}.bind(this),function(){this.forwards[e.fromPort]=t}.bind(this))};n.prototype.newAdbSocket=function(e,t){var n;if(this.createSocket)n=this.createSocket(e,t);else n=new o(this,e,t);return n};n.prototype.newSocket=function(e,t){var r=++this.currentSocketId;this.sockets[r]=this.newAdbSocket(r,t);this.sendMessage(n.kCommandOPEN,r,0,e)};function o(e,t,n){if(!n){n=function(){}}this.device=e;this.localId=t;this.onConnected=n}o.prototype.write=function(e,t){if(this.pendingWrite||this.wrote){console.log("bad adb socket state, already writing");throw new Error("bad adb socket state, already writing")}var r=Math.min(this.device.transport.zero_mask,this.device.maxPayload);if(r<e.byteLength){this.pendingWrite=e.slice(r);e=e.slice(0,r)}else{this.pendingWrite=null}this.wrote=t;this.device.sendMessage(n.kCommandWRTE,this.localId,this.remoteId,e)};o.prototype.destroy=function(){this.device.sendMessage(n.kCommandCLSE,this.localId,this.remoteId);this.dataReceived(null)};o.prototype.buffered=Socket.prototype.buffered;o.prototype.dataReceived=Socket.prototype.dataReceived;o.prototype.read=Socket.prototype.read;o.prototype.pause=Socket.prototype.pause;o.prototype.resume=Socket.prototype.resume;o.prototype.unshift=Socket.prototype.unshift;o.prototype.onPause=function(){};o.prototype.onResume=function(){this.device.sendMessage(n.kCommandOKAY,this.localId,this.remoteId)};function i(t,r,o){console.log("connecting");var i=new n(new e(t,r),o);console.log("sending CNXN");i.sendMessage(n.kCommandCNXN,n.ADB_PROTOCOL_VERSION,n.MAX_PAYLOAD,"host::");console.log("starting receive loop");i.receiveMessages()}function s(e){var e=e||{};var t=e.port||5037;var n=e.start!==false;this.currentSocketId=0;this.pendingDevices={};this.port=t;this.adbDevices={};this.clients={};if(n){this.start()}}function c(){return(new Date).getTime()}s.prototype.start=function(){if(this.server){console.log("ADB Server started while already started");return}this.clients={};this.adbDevices={};this.pendingDevices={};this.refreshing={};var e=new Server;e.listen({port:this.port,address:"127.0.0.1"},function(e){var t=new a(this,e);var n=++this.currentSocketId;this.clients[n]=t;e.onClose=function(){delete this.clients[n]}.bind(this);t.receiveHeader()}.bind(this),function(t){if(t){console.log("adb server failed to listen: "+t);return}console.log("ADB Server started");this.server=e;this.refresh()}.bind(this))};s.prototype.isRunning=function(){return this.server!=null};s.prototype.kill=function(){this.server.destroy();this.server=null;this.refreshing={};for(var e in this.clients){e=this.clients[e];e.socket.destroy()}this.clients={};for(var t in this.adbDevices){t=this.adbDevices[t];t.destroy()}this.adbDevices={};this.pendingDevices={}};s.prototype.selectDevice=function(e){chrome.usb.getUserSelectedDevices({filters:[{interfaceClass:255,interfaceSubclass:66,interfaceProtocol:1}]},function(t){for(var n in t){n=t[n];this.refreshDevice(n,e)}}.bind(this))};s.prototype.withAdbDevice=function(e,t){e.onError=function(){delete this.adbDevices[e.serialno];this.internalOnDevicesChanged()}.bind(this);var n=function(n){e.serialno=n.trim();this.adbDevices[e.serialno]=e;console.log("found device: "+e.serialno);this.internalOnDevicesChanged();t(e)}.bind(this);if(e.serialno){n(e.serialno);return}e.newSocket("shell:getprop ro.serialno",function(e){readString(e,function(e){n(e)}.bind(this))}.bind(this))};s.prototype.tryDevice=function(e,t,n){var r=this.adbDevices;var o=this.pendingDevices;var s=this;function c(r){var c=r.interfaceNumber;if(o[c]){return false}o[c]=e;console.log("claiming:",JSON.stringify(e),JSON.stringify(r));chrome.usb.claimInterface(e,r.interfaceNumber,function(){console.log("claimed:",JSON.stringify(chrome.runtime.lastError));i(e,r,function(e){if(!e){delete o[c];n();return}e.serialno=t;s.withAdbDevice(e,function(e){delete o[c];n(e)})})});return true}chrome.usb.listInterfaces(e,function(t){if(!t){console.log("unable list interfaces",JSON.stringify(chrome.runtime.lastError));if(n)n();return}console.log("got interfaces",JSON.stringify(t));var r=false;for(var o in t){o=t[o];if(o.interfaceClass==255&&o.interfaceSubclass==66&&o.interfaceProtocol==1){r|=c(o)}}if(!r){chrome.usb.closeDevice(e)}})};s.prototype.refreshDevice=function(e,t){chrome.usb.openDevice(e,function(n){if(!n){console.log("unable to open device",JSON.stringify(chrome.runtime.lastError));if(t)t();return}this.start();this.tryDevice(n,e.serialNumber,function(n){if(n){n.usbDevice=e}t(n)})}.bind(this))};s.prototype.refresh=function(){if(!this.server){console.log("adb server refresh requested while server killed");return}var e=c();if(this.server.lastRefresh&&this.server.lastRefresh>e-1e4){return}this.server.lastRefresh=e;var t=chrome.runtime.getManifest().permissions.pop().usbDevices;$(t).each(function(e,t){var n=t.vendorId+"&"+t.productId;if(this.refreshing[n]){return}this.refreshing[n]=true;chrome.usb.findDevices({productId:t.productId,vendorId:t.vendorId},function(e){var r=e.length;if(!r){delete this.refreshing[n];return}console.log("found:",t,e);for(var o in e){console.log("trying:",e[o]);this.tryDevice(e[o],e[o].serialNumber,function(){r--;if(!r){delete this.refreshing[n]}}.bind(this))}}.bind(this))}.bind(this))};s.prototype.internalOnDevicesChanged=function(){for(var e in this.clients){e=this.clients[e];if(!e.tracking)continue;var t=e.getDevicesString();if(!t.length)t="0000\n";e.socket.write(str2ab(t),function(){})}};s.prototype.stop=function(){this.server.destroy()};function a(e,t){this.server=e;this.socket=t}a.prototype.resolveTransport=function(e,t){if(t){var n=this.server.adbDevices[t];if(!n)return"device not found";return n}var r=Object.keys(this.server.adbDevices);if(r>1){return"more than one device"}if(r==0){return"no devices connected"}for(var o in this.server.adbDevices){return this.server.adbDevices[o]}};a.prototype.write=function(e,t,n){if(!t){t="OKAY"}e=str2ab(e);var r=e.byteLength;var o=make4Len16(r);o=str2ab(t+o);var i=appendBuffer(new Uint8Array(o),new Uint8Array(e)).buffer;if(!n){n=function(){this.socket.destroy()}.bind(this)}this.socket.write(i,n)};a.prototype.getDevicesString=function(e){var e=e||{};var t=e.longformDevices;var n="";for(var r in this.server.adbDevices){r=this.server.adbDevices[r];n+=r.serialno+"\tdevice";if(t){if(r.transport.type=="usb")n+=" usb:"+r.transport.iface.interfaceNumber;else n+=" tpcip:"+"something";n+=" product:"+r.properties["ro.product.name"];n+=" model:"+r.properties["ro.product.model"];n+=" device:"+r.properties["ro.product.device"]}n+="\n"}return n};a.prototype.writeDevices=function(e,t){this.write(this.getDevicesString(e),null,t)};a.prototype.handlePayload=function(e){e=ab2str(e);var r=e.split(":");var o=e;var i;if(r[0]=="host-serial"){r[0]="host";i=r.splice(1,1)[0];if(Number.isInteger(parseInt(r[1]))){i+=":"+r.splice(1,1)[0]}}if(r.length>=2)o=r[0]+":"+r[1];switch(o){case"host:version":this.write(make4Len16(n.ADB_VERSION));break;case"host:devices-l":case"host:devices":var s=e=="host:devices-l";this.server.refresh();this.writeDevices({longformDevices:s});break;case"host:features":var a=this.resolveTransport(e,i);if(a.constructor.name=="String"){this.write(a,"FAIL");break}var l=a.properties.features;if(!l)l="";this.write(make4Len16(l));break;case"host:transport-usb":case"host:transport-any":var a=this.resolveTransport(e,i);if(a.constructor.name=="String"){this.write(a,"FAIL");break}this.transport=a;this.socket.write(str2ab("OKAY"),function(){});break;case"host:kill":this.server.kill();break;case"host:connect":if(r.length<3){this.write("need more arguments for connect <host>[:<port>]","FAIL");break}var u=r[2];var d=5555;if(r.length>3)d=Number.parseInt(r[3]);Socket.connect({host:u,port:d},function(e,r){if(!e){console.error("connect failed");this.write("unable to connect to "+u+" "+d+": "+r,"FAIL");return this}var o=new n(new t(e),function(e){this.server.withAdbDevice(e,function(){var e="connected to "+u+":"+d;console.log(e);this.write(e)}.bind(this))}.bind(this));o.serialno=u+":"+d;e.onClose=function(){o.fatal("socket closed")}.bind(this);o.sendMessage(n.kCommandCNXN,n.ADB_PROTOCOL_VERSION,n.MAX_PAYLOAD,"host::");o.receiveMessages()}.bind(this));break;case"host:track-devices":this.tracking=c();this.writeDevices({},function(){});break;case"host:forward":var f=r.join(":").substring(o.length+1).split(";");var h=f[0].split(":");var p=parseInt(h[1]);var a=this.resolveTransport(e,i);if(a.constructor.name=="String"){this.write(a,"FAIL");break}a.forwardPort({fromPort:p,to:f[1]});this.socket.write(str2ab("OKAYOKAY"),function(){}.bind(this));break;default:if(this.transport){var a=this.transport;a.newSocket(e,function(e){if(!e){this.socket.write(str2ab("OKAY"),function(){this.socket.destroy()}.bind(this));return}this.socket.write(str2ab("OKAY"),function(){});Socket.stream(e,this.socket)}.bind(this));return}var v="host:transport:";if(e.startsWith(v)){var i=e.substr(v.length);var g=this.server.adbDevices[i];if(!g){this.write("device not found","FAIL");return}this.transport=g;this.socket.write(str2ab("OKAY"),function(){});break}console.log("unknown request: "+e);this.write("unknown command: "+e,"FAIL");var m=chrome.runtime.getManifest().name;chrome.notifications.create({type:"basic",iconUrl:"/icon.png",title:m,message:m+"'s adb server encountered an unknown adb command.\nYou may want to close "+m+" and start your adb binary manually."});break}this.receiveHeader()};a.prototype.receivePayload=function(e){var t=parseInt(ab2str(e),16);this.socket.read(t,this.handlePayload.bind(this))};a.prototype.receiveHeader=function(){this.socket.read(4,this.receivePayload.bind(this))};window.AdbDevice=n;window.AdbServer=s;window.AdbTcpTransport=t})();(function(){var e={};e.sendHostCommand=function(e,t){Socket.connect({host:"127.0.0.1",port:5037},function(n){if(!n){t();return}var r=e;e=make4Len16(e.length)+e;n.read(4,function(e){var o=ab2str(e);if(o!="OKAY"){console.error("error in response to adb host command",r,o);n.destroy();t();return}n.read(4,function(e){var r=ab2str(e);e=parseInt(r,16);if(e==0||r=="OKAY"){t(n,new ArrayBuffer(0));return}n.read(e,function(e){t(n,e)})})});n.write(str2ab(e),function(){})})};e.devices=function(t){var n={};function r(e){var t=e;e=e.replace("\t"," ");var r=e.indexOf(" ");if(r==-1)return;var o=e.substring(0,r);e=e.substring(r).trim();var i;while(i!=e){i=e;e=e.replace("  "," ")}var s={};var c=e.indexOf(" ");if(c==-1)c=e.length;var a=e.substring(0,c);e=e.substring(c+1);while(e.length){r=e.indexOf(":");if(r==-1)break;var l=e.substring(0,r);var u=e.substring(r+1);var d=u.indexOf(" ");var f=u.indexOf(":");var h;if(d==-1||f==-1){h=u;e=""}else{while(d!=-1&&d<f){h=u.substring(0,d);e=u.substring(d+1);d=u.indexOf(" ",d+1)}}s[l]=h}var p;if(!s["model"])p=o;else p=s["model"].replace("_"," ");n[o]={serialno:o,name:p,status:a,properties:t}}e.sendHostCommand("host:devices-l",function(e,o){if(!e){t();return}e.destroy();o=ab2str(o);console.log("ADB devices:",o);o=o.trim();var i=o.split("\n");for(var s in i){s=i[s];r(s)}t(n)})};e.killServer=function(t){e.sendHostCommand("host:kill-server",function(e,n){if(!e){t();return}e.destroy();n=ab2str(n);if(t)t()})};e.sendClientCommand=function(e,t){var n=e.command;var r=e.serialno;Socket.connect({host:"127.0.0.1",port:5037},function(e){if(!e){t();return}e.read(4,function(r){var o=ab2str(r);if(o!="OKAY"){e.destroy();t(null);return}var i=n;i=make4Len16(i.length)+i;e.read(4,function(n){var r=ab2str(n);if(r!="OKAY"){e.destroy();t(null);return}t(e)});e.write(str2ab(i),function(){})});var o="host:transport:"+r;o=make4Len16(o.length)+o;e.write(str2ab(o),function(){})})};e.shell=function(t,n){var r=t.command;var o=t.serialno;e.getOrCreateSockFactory(t).newSocket("shell:"+r,function(e){if(!e){n();return}readString(e,function(e){n(e)})})};e.forward=function(t,n){var r="host-serial:"+t.serialno+":forward:"+t.from+";"+t.to;e.sendHostCommand(r,function(e,t){if(e)e.destroy();n(e,t)})};function t(){}t.MKID=function(e,t,n,r){return e.charCodeAt(0)|t.charCodeAt(0)<<8|n.charCodeAt(0)<<16|r.charCodeAt(0)<<24};t.ID_RECV=t.MKID("R","E","C","V");t.ID_SEND=t.MKID("S","E","N","D");t.ID_DONE=t.MKID("D","O","N","E");t.ID_DATA=t.MKID("D","A","T","A");t.DATA_MAX=64*1024;e.pull=function(n,r){var o=n.file;var i=n.serialno;var s=n.fileEntry;var c=n.socket;if(!c){(function(){var e;c={write:function(t,n){if(!e){s.createWriter(function(r){e=r;c.write(t,n)});return}e.onwriteend=n;e.write(new Blob([t]))}}})()}var a=new DummySocket;Socket.pump(a,c,function(){r(s)});e.getOrCreateSockFactory(n).newSocket("sync:",function(e){if(!e){r();return}function n(t){e.read(t,function(e){a.dataReceived(e);i()})}function i(){e.read(8,function(o){var i=new DataView(o.buffer,o.byteOffset,o.byteLength);var s=i.getUint32(0,true);if(s==t.ID_DATA){var c=i.getUint32(4,true);n(c);return}e.destroy();if(s==t.ID_DONE){a.dataReceived(null);return}r()})}var s=new ArrayBuffer(8);var c=new DataView(s);c.setUint32(0,t.ID_RECV,true);c.setUint32(4,o.length,true);e.write(s,function(){e.write(str2ab(o),function(){i()})})})};e.createSocketFactory=function(t){return{newSocket:function(n,r){e.sendClientCommand({serialno:t,command:n},r)}}};e.getOrCreateSockFactory=function(t){return t.socketFactory||e.createSocketFactory(t.serialno)};e.push=function(n,r){var o=n.file;var i=n.serialno;var s=n.socket;e.getOrCreateSockFactory(n).newSocket("sync:",function(e){if(!e){r();return}var n=new ArrayBuffer(8);var i=new DataView(n);var c=o+",0644";i.setUint32(0,t.ID_SEND,true);i.setUint32(4,c.length,true);e.write(n,function(){e.write(str2ab(c),function(){var n;var o=true;s.onClose=function(){var n=new ArrayBuffer(8);var o=new DataView(n);o.setUint32(0,t.ID_DONE,true);o.setUint32(4,0,true);e.write(n,function(){e.read(8,function(){r()})})};function i(){s.read(function(e){if(e.byteLength>t.DATA_MAX){var n=e.subarray(t.DATA_MAX);e=e.subarray(0,t.DATA_MAX);s.unshift(n)}c(e)})}function c(n){var r=new ArrayBuffer(8);var o=new DataView(r);o.setUint32(0,t.ID_DATA,true);o.setUint32(4,n.byteLength,true);e.write(r,function(){var t=n.buffer;if(n.byteOffset||n.length!=t.byteLength){t=t.slice(n.byteOffset,n.byteOffset+n.byteLength)}e.write(t,function(){i()})})}i()})})})};window.Adb=e})();(function(){function e(e,t){this.transport=e;this.sockets={};this.currentSocketId=0;this.maxPayload=t||AdbDevice.MAX_PAYLOAD}e.prototype.start=function(e){var t=str2ab(e,undefined,true);this.sendMessage(AdbDevice.kCommandCNXN,AdbDevice.ADB_PROTOCOL_VERSION,this.maxPayload,t);this.receiveMessages()};e.prototype.fatal=function(e){console.log("fatal error",e);var t=this.onClose;if(t){delete this.onClose;t()}};e.prototype.sendMessage=AdbDevice.prototype.sendMessage;e.prototype.receiveMessages=AdbDevice.prototype.receiveMessages;e.prototype.onReceiveMessage=AdbDevice.prototype.onReceiveMessage;e.prototype.handleMessage=AdbDevice.prototype.handleMessage;e.prototype.handleUnknown=AdbDevice.prototype.handleUnknown;e.prototype.newAdbSocket=AdbDevice.prototype.newAdbSocket;e.prototype.destroy=AdbDevice.prototype.destroy;e.prototype.onOpenSocket=function(e,t){if(this.openSocket){var n=++this.currentSocketId;var r=this.newAdbSocket(n);r.remoteId=t;this.sockets[n]=r;this.sendMessage(AdbDevice.kCommandOKAY,n,t);this.openSocket(ab2str(e),r)}};window.AdbDaemon=e})();(function(){function e(e,t,n){$.ajax({url:e,dataType:"binary",responseType:"arraybuffer",success:function(e){var r=new Uint8Array(e);var o=new DummySocket(r);var i="/data/local/tmp/apk"+(new Date).getTime()+".apk";Adb.push({serialno:t,file:i,socket:o},function(){Adb.shell({command:"pm install -r "+i,serialno:t},n)})},error:function(e){console.error("error fetching apk",e);n()}})}function t(e,t,n){Adb.shell({command:"pm path "+t,serialno:e},function(e){if(e==""||!e){n(null);return}var t=e.match(/package:\/.*?[\r\n]/);if(!t||!t.length){n(null);return}e=t[0];e=e.replace("package:","").trim();n(e)})}function n(e,t,n,r,o){if(!o)o=Adb.shell;Adb.shell({command:"ls -l /system/bin/app_process*",serialno:e},function(i){var s="/system/bin/app_process";if(i&&i.indexOf("app_process32")!=-1){s+="32"}o({command:'sh -c "CLASSPATH='+t+" "+s+" /system/bin "+n+'"',serialno:e},r)})}window.AdbUtils={runMain:n,installApk:e,getApkPath:t}})();(function(){var e=function(e){this.authorization=e};e.prototype.shorten=function(e,t){$.ajax({type:"POST",url:"https://www.googleapis.com/urlshortener/v1/url?key="+this.authorization,data:JSON.stringify({longUrl:e}),contentType:"application/json",dataType:"json",success:function(e){t(e.id)}})};window.Googl=e})();function verifySignature(e,t,n,r,o){r=base64ToArrayBuffer(r);n=str2ab(n);window.crypto.subtle.importKey("jwk",{kty:"RSA",e:e,n:t,alg:"RS1"},{name:"RSASSA-PKCS1-v1_5",hash:{name:"SHA-1"}},true,["verify"]).then(function(e){window.crypto.subtle.verify({name:"RSASSA-PKCS1-v1_5",hash:{name:"SHA-1"}},e,r,n).then(function(e){if(!e){o("invalid signature");return}o()}).catch(function(e){o("failure to verify",e)})}).catch(function(e){o("key import failed",e)})}(function(){function e(){this.licensed=true;this.licenseCached=true}e.prototype.refresh=function(e,t){this.refreshInternal(e,t).async()};e.prototype.refreshInternal=function*(e,t){var n;var r=function(){nextTick(function(){if(this.isLicensed()){var e=chrome.app.window.getAll().filter(function(e){return e&&e.id=="purchase"});var t;if(e&&e.length);t=e[0];if(t!=null){t.close();showNotification("Vysor subscription is active. Thank you for your support!")}}}.bind(this));if(this.globalRefresh)this.globalRefresh();else console.error("no global refresh?");if(n)return;n=true;if(e)e(this.isLicensed())}.bind(this);var o=false;var i=false;var s=false;var c=false;if(!window.chrome||!window.chrome.runtime||!window.chrome.runtime.connect)s=true;var a;var l;var u;var d=function(e,t){if(!t.licensed)return false;if(e!=t.email){console.log("email mismatch");return false}console.log("enterprise license retrieved");return true}.bind(this);var f=function(e,t){if(t.sandbox!=o){console.log("sandbox mismatch");return false}if(e!=t.buyer_id){console.log("id mismatch");return false}if(t.seller_id!="koushd@gmail.com"){console.log("seller mismatch");return false}var n=false;if(t.subscriptions){$.each(t.subscriptions,function(e,t){console.log("subscription found",t);if(!t.remote_plan_id.startsWith("vysor")){console.log("skipping non-vysor subscription");return}if(t.subscription_active){console.log("clockwork subscription retrieved");n=true}}.bind(this))}$.each(t.orders,function(e,t){console.log("purchase found",t);if(!t.product_id.startsWith("vysor")){console.log("skipping non-vysor purchase");return}if(t.is_purchased){console.log("clockwork license retrieved");n=true}}.bind(this));return n}.bind(this);var h=function(e){$.each(e,function(e,t){console.log("subscription status",t);if(t.state=="ACTIVE"){console.log("chrome license retrieved");this.licensed=true}}.bind(this))}.bind(this);var p=function*(){if(c){console.log("skipping enterprise");return}if(u&&!t){console.log("Skipping enterprise license server check.");console.log("Use Retrieve License from the purchase page to force refresh.");return}console.log("checking chrome enterprise licenses");var e=yield getAuthToken(false,yield);if(!e){chrome.runtime.lastError;console.error("No auth token for enterprise licensing");return}try{var n=yield chrome.identity.getProfileUserInfo(yield);if(!S){console.log("unable to retrieve user info for enterprise");return}var o=n.id;var i=n.email;try{var n=yield $.ajax({url:"https://billing.vysor.io/license",headers:{Authorization:"Bearer "+e},dataType:"json",success:yield Success,error:yield Error});var s=JSON.parse(n.signed_data);yield chrome.storage.local.set({cachedEnterpriseLicense:n},yield);var a=d(i,s);if(!a){console.log("No enterprise license found on server");return}this.licensed=true;this.licenseCached=true;r()}catch(l){yield chrome.identity.removeCachedAuthToken({token:e},yield);console.error("Error communicating with vysor enterprise",l)}}catch(l){yield chrome.identity.removeCachedAuthToken({token:e},yield);console.error("Unable to get email for enterprise",l)}}.bind(this);var v=function*(){if(i){console.log("skipping clockwork");return}if(l&&!t){console.log("Skipping clockwork license server check.");console.log("Use Retrieve License from the purchase page to force refresh.");return}console.log("checking clockwork purchases");var e=yield getAuthToken(false,yield);if(!e){chrome.runtime.lastError;console.error("No auth token for clockwork billing");return}try{var n=yield chrome.identity.getProfileUserInfo(yield);if(!S){console.log("unable to retrieve user info for clockwork");return}var s=n.id;var c="https://billing.clockworkmod.com/api/v1/purchase/koushd@gmail.com/"+s+"?sandbox="+o+"&nonce="+Date.now()+"&buyer_email="+n.email;try{var n=yield $.ajax({url:c,dataType:"json",error:yield Error,success:yield Success});var a=JSON.parse(n.signed_data);yield chrome.storage.local.set({cachedClockworkLicense:n},yield);var u=f(s,a);if(!u){console.log("no clockwork license found on server");return}this.licensed=true;this.licenseCached=true;r()}catch(d){console.error("error requesting purchases",d)}}catch(d){yield chrome.identity.removeCachedAuthToken({token:e},yield);console.error("Unable to get buyer id for clockworkbilling",d)}}.bind(this);var g=function*(){if(s)return;console.log("checking chrome store purchases");var e;try{e=yield google.payments.inapp.getPurchases({parameters:{env:"prod"},success:yield Success,failure:yield Error})}catch(n){console.error("Failed to query license from chrome store.",n);if(!t){console.log("Skipping Chrome license server fallback check.");console.log("Use Retrieve License from the purchase page to force refresh.");return}console.log("Falling back to server proxied query.");try{yield this.cacheLicense(false,yield);yield*w()}catch(n){console.error("failed to do fallback server check",n)}return}h(e.response.details);if(!this.isLicensed()){console.log("no chrome license found on server");return}r();console.log("Caching Vysor license.");yield this.cacheLicense(false,yield);if(this.isLicenseCached())r()}.bind(this);var m=4;var y=m/2;var w=function*(){if(s)return;console.log("checking cached chrome license");var e=yield chrome.storage.local.get("cachedLicense",yield);if(!e){console.error("storage access failed?",chrome.runtime.lastError);return}if(!e.cachedLicense){console.log("no cached chrome license found");return}if(!S){console.log("unable to retrieve user info for cache");return}var t=yield verifySignature("AQAB","vMGBBmLcMO4lOmg-YAHq2DjZKHTaW-xs9KPNXU_zKJ7ZhFhWH3I6skF9ZO8lKeXOSwVEIW4HVMa7m16S6WTrUw",e.cachedLicense.signed_data,e.cachedLicense.signature,yield);if(t){console.error("error verifying cached signature",t);return}var n=JSON.parse(e.cachedLicense.signed_data);a=false;var o=Date.now();$.each(n.payments,function(e,t){if(t.state=="ACTIVE"){a=true;o=Math.min(o,t.createdTime)}}.bind(this));if(n.date>Date.now()){console.log("cached license date from future?");return}var i=new Date-new Date(o);var c=i/1e3/60/60/24;var l;if(c<14)l=4;else l=Math.min(30,4+(c-14)/7);var u=l/2;if(n.date+l*24*60*60*1e3<Date.now()){console.log("cached license is expired.");return}if(S.id!=n.userinfo.id){console.log("id mismatch");return}h(n.payments);if(!this.isLicensed()){console.log("no chrome license found in cache");return}console.log("cached license is valid for "+(n.date+l*24*60*60*1e3-Date.now())/(60*60*1e3)+" hours");this.licenseCached=true;r();if(n.date+u*24*60*60*1e3<Date.now()){console.log("Refreshing cached license");try{yield this.cacheLicense(false,yield)}catch(t){console.warn("Failed to re-cache license.",t)}}}.bind(this);var b=function*(){if(i)return;console.log("Checking cached Clockwork license.");var e=yield chrome.storage.local.get("cachedClockworkLicense",yield);if(!e){console.error("storage access failed?",chrome.runtime.lastError);return}if(!e.cachedClockworkLicense){console.log("Cached Clockwork payload not found.");return}if(!S){console.error("Unable to retrieve user info for cached Clockwork license.");return}var t=S.id;var n=yield verifySignature("AQAB","vMGBBmLcMO4lOmg-YAHq2DjZKHTaW-xs9KPNXU_zKJ7ZhFhWH3I6skF9ZO8lKeXOSwVEIW4HVMa7m16S6WTrUw",e.cachedClockworkLicense.signed_data,e.cachedClockworkLicense.signature,yield);if(n){console.error("Error verifying cached clockwork signature",n);return}var o=JSON.parse(e.cachedClockworkLicense.signed_data);var s=f(t,o);if(!s){console.log("No Clockwork license found in cache.");l=true;return}if(o.timestamp+m*24*60*60*1e3<Date.now()){console.log("Cached Clockwork license is expired. Requires server check.");return}if(o.timestamp>Date.now()){console.error("Cached Clockwork license date from future?");return}this.licensed=true;console.log("Cached Clockwork license is valid for "+(o.timestamp+m*24*60*60*1e3-Date.now())/(60*60*1e3)+" hours");this.licenseCached=true;r();if(o.timestamp+y*24*60*60*1e3<Date.now()){l=false;yield*v()}}.bind(this);var k=function*(){if(c)return;console.log("Checking cached enterprise license.");var e=yield chrome.storage.local.get("cachedEnterpriseLicense",yield);if(!e){console.error("storage access failed?",chrome.runtime.lastError);return}if(!e.cachedEnterpriseLicense){console.log("Cached Enterprise payload not found.");return}if(!S){console.error("Unable to retrieve user info for cached Clockwork license.");return}var t=yield verifySignature("AQAB","hDuGsIhbjLYXteQX3F3KNriQHwUSZurS5voCkdpA1733A65pqtGOrk9g_yLiF94_vSK0VmL-4stq7WAYEbn6nw",e.cachedEnterpriseLicense.signed_data,e.cachedEnterpriseLicense.signature,yield);if(t){console.error("Error verifying cached enterprise signature",t);return}var n=JSON.parse(e.cachedEnterpriseLicense.signed_data);var o=d(S.email,n);if(!o){u=true;console.log("No Enterprise license found in cache.");return}if(n.timestamp+m*24*60*60*1e3<Date.now()){console.log("Cached Enterprise license is expired. Requires server check.");return}if(n.timestamp>Date.now()){console.error("Cached Enterprise license date from future?");return}this.licensed=true;console.log("Cached Enterprise license is valid for "+(n.timestamp+m*24*60*60*1e3-Date.now())/(60*60*1e3)+" hours");this.licenseCached=true;r();if(n.timestamp+y*24*60*60*1e3<Date.now()){u=false;yield*p()}}.bind(this);if(this.isLicensed()){r();return}console.log("starting license check");var S=yield chrome.identity.getProfileUserInfo(yield);if(!S)console.log("unable to retrieve user info");else console.log("user info",S);yield*k();if(this.isLicensed())return;yield*b();if(this.isLicensed())return;yield*w();if(this.isLicensed())return;yield*p();if(this.isLicensed())return;yield*v();if(this.isLicensed())return;yield*g();if(this.isLicensed())return;r()};e.prototype.cacheLicense=function(e,t){console.log("caching chrome license");getAuthToken(e,function(n){if(!n){chrome.runtime.lastError;if(e)showNotification("Unable to get auth token: "+chrome.runtime.lastError);console.error("Unable to get auth token while caching license",chrome.runtime.lastError);if(t)t(chrome.runtime.lastError);return}$.ajax({type:"post",url:"https://billing.clockworkmod.com/api/v1/verify/google/koushd@gmail.com",data:{token:n,item:chrome.runtime.id,version:chrome.runtime.getManifest().version},dataType:"json",success:function(e){console.log("chrome license cached");this.licenseCached=true;chrome.storage.local.set({cachedLicense:e},t)}.bind(this),error:function(e,r){console.error("unable to cache license");chrome.identity.removeCachedAuthToken({token:n},function(){if(t)t(r)})}})}.bind(this))};e.prototype.isLicensed=function(){return this.licensed};e.prototype.isLicenseCached=function(){return this.licenseCached};e.prototype.startPurchase=function(){chrome.app.window.create("purchase.html",{id:"purchase",innerBounds:{minWidth:800,
    minHeight:860}},function(e){this.refresh();e.contentWindow.refreshLicenseManager=function(e){chrome.storage.local.remove(["cachedLicense","cachedClockworkLicense","cachedEnterpriseLicense"],function(){this.refresh(e,true)}.bind(this))}.bind(this)}.bind(this))};window.LicenseManager=e})();function GcmDevice(e,t,n){this.adbSocketFactory=e;this.conn=n;this.conn.openSocket=this.openSocket.bind(this);var r=t.properties.substring(t.properties.indexOf("product")).replace(/ /g,";").replace("device","ro.product.device").replace("model","ro.product.model").replace("product","ro.product.name").replace(/:/g,"=");this.properties="device::"+r+";"}GcmDevice.prototype.openSocket=function(e,t){if(this.onOpenSocket&&this.onOpenSocket(e,t))return;if(e=="properties"){var n=this.properties;t.write(str2ab(n),function(){console.log("sent properties",n);t.destroy()});return}this.adbSocketFactory.newSocket(e,function(n){if(!n){console.log("unable to execute adb proxy command?",e);t.destroy();return}Socket.stream(n,t,function(){})})};function getWhitelist(e){chrome.storage.local.get("whitelist",function(t){var n={};if(!t.whitelist||t.whitelist.constructor.name!="Array"){e(n);return}$.each(t.whitelist,function(e,t){n[t]=true});e(n)})}function saveWhitelist(e,t){chrome.storage.local.set({whitelist:Object.keys(e)},t)}function addToWhitelist(e,t){getWhitelist(function(n){n[e]=true;saveWhitelist(n,t)})}function clearWhitelist(){chrome.storage.local.remove("whitelist")}function isWhitelisted(e,t){chrome.storage.local.get(["whitelist","serverMode"],function(n){if(n.serverMode==1){t(true);return}if(n.serverMode!=2){var r={};if(!n.whitelist||n.whitelist.constructor.name!="Array"){t(false,true);return}t(n.whitelist.indexOf(e)!=-1,true);return}getAuthToken(false,function(n){if(!n){console.error("unable to get token for vysor enterprise whitelist check");t(false);return}$.ajax({type:"get",url:"https://billing.vysor.io/whitelist",headers:{Authorization:"Bearer "+n},data:{email:e},error:function(){console.error("failure checking vysor enterprise whitelist",arguments);t(false)},success:function(n){if(!n.whitelist)console.error("access denied to",e,n);t(n.whitelist,false)}})})})}function getVysorWhitelistStatus(e){chrome.storage.local.get(["whitelist","serverMode"],function(t){if(t.serverMode==1){e("Any user can access this server.");return}if(t.serverMode==2){e("Your Vysor Enterprise users can access this server.");return}var n;if(!t.whitelist||t.whitelist.constructor.name!="Array")n=0;else n=t.whitelist.length;e(n+" user(s) can access this server.")})}function getDefaultDeviceSettings(){var e={showSoftKeys:true,pinTitleBar:true,alwaysOnTop:false,bitrate:0,resolution:0,decoder:0,displaySettings:commonDisplaySettings[0],dimDisplay:false};return e}function sanitizeDeviceSettings(e){if(!e)return null;if(e.friendlyName&&!e.friendlyName.length)delete e.friendlyName;return e}function loadAllDeviceSettings(e){if(window.chrome&&window.chrome.storage){chrome.storage.local.get("device-settings",function(t){e(t["device-settings"]||{})})}else{e({})}}function loadDeviceSettings(e,t){if(!e)e="web";var n=getDefaultDeviceSettings();if(e=="inkwire"){n.pinTitleBar=false;n.showSoftKeys=false}loadAllDeviceSettings(function(r){t(sanitizeDeviceSettings(r[e]||n))})}function saveDeviceSettings(e,t,n){sanitizeDeviceSettings(t);if(!window.chrome||!window.chrome.storage){if(n)n();return}if(!e||e.indexOf("127.0.0.1")!=-1){if(n)n();return}loadAllDeviceSettings(function(r){r[e]=t;chrome.storage.local.set({"device-settings":r},n)})}function populateDisplaySettings(){for(var e in commonDisplaySettings){var t=commonDisplaySettings[e];var n=new Option;$(n).html(t.name);$("#display-settings").append(n)}}function applyDeviceSettings(e){$("#new-display-name").prop("value",e.friendlyName||null);$("#softkeys-check").prop("checked",e.showSoftKeys?true:false).change();$("#pin-title-check").prop("checked",e.pinTitleBar?true:false).change();$("#always-on-top-check").prop("checked",e.alwaysOnTop?true:false).change();$("#bitrate").prop("selectedIndex",e.bitrate||0);$("#decoder").prop("selectedIndex",e.decoder||0);$("#resolution").prop("selectedIndex",e.resolution||0);var t=e.displaySettings&&e.displaySettings.name;var n=0;for(var r in commonDisplaySettings){var o=commonDisplaySettings[r];if(o.name==t){n=r;break}}$("#display-settings").prop("selectedIndex",n);$("#dim-display").prop("checked",e.dimDisplay?true:false)}var commonDisplaySettings=[{name:"Default Settings",size:"reset",density:"reset"},{name:"Resizable (96dpi)",size:"reset",density:"96",freeSize:true},{name:"Resizable (144dpi)",size:"reset",density:"144",freeSize:true},{name:"1080p (96dpi)",size:"1920x1080",density:"96"},{name:"4K (144dpi)",size:"3840x2160",density:"144"},{name:"Galaxy Nexus",size:"720x1280",density:"320"},{name:"Nexus 4",size:"768x1280",density:"320"},{name:"Nexus 5",size:"1080x1920",density:"480"},{name:"Nexus 6",size:"1440x2560",density:"560"},{name:"Nexus 6p",size:"1440x2560",density:"560"},{name:"Nexus 7 (2012)",size:"800x1280",density:"213"},{name:"Nexus 7 (2013)",size:"1200x1920",density:"320"},{name:"Nexus 9",size:"1536x2048",density:"320"}];(function(){console.log("Vysor version",chrome.runtime.getManifest().version);console.log(navigator.userAgent);console.log("Electron",isElectron());var e=new AdbServer({start:false});var t;var n;var r={};var o={};var i={};var s;var c=analytics.getService("vysor_app");var a=c.getTracker("UA-4956323-6");if(isElectron()){var l=a;a={sendEvent:l.sendEvent.bind(l),sendAppView:l.sendAppView.bind(l)}}var u=new LicenseManager;var d="Chrome GCM Service is unavailable. Try restarting Chrome?";var f=new HttpServer;function h(e){e.contentWindow.licenseManager={isLicensed:u.isLicensed(),isLicenseCached:u.isLicenseCached(),cacheLicense:u.cacheLicense.bind(u),refresh:u.refresh.bind(u),startPurchase:u.startPurchase.bind(u)};if(e.contentWindow.refreshLicense)e.contentWindow.refreshLicense()}u.globalRefresh=function(){console.log("license global refresh");var e=chrome.app.window.getAll();for(var t in e){t=e[t];h(t)}};chrome.identity.onSignInChanged.addListener(function(){console.log("onSignInChanged, refreshing license");u.refresh(null,true)});chrome.storage.local.get("keyboard",function(e){t=e.keyboard});chrome.storage.local.get("vysorHttp",function(e){if(!e){console.error("unable to start vysor httpServer, no dict");return}var t=e.vysorHttp||{};t.password=t.password||Math.round(Math.random()*(1<<30)).toString(16);var n={"/device/(.*?)/screenshot.jpg":function(e,t,n){var r=n[1];var o=chrome.app.window.get(r);if(!o){console.error("device window",r,"not found");t.code(404);t.write("",function(){t.end()});return}var i=o.contentWindow.password;var s=Adb.createSocketFactory(r);s.newSocket("tcp:53516",function(e){if(!e){console.error("no socket",r,"for screenshot");t.code(404);t.write("",function(){t.end()});return}t.headers["Connection"]="close";t.headers["Cache-Control"]="no-cache";var n=new HttpRequestParser(null,e,function(){var e=n.body.buffer.slice(n.body.byteOffset,n.body.byteOffset+n.body.byteLength);t.write(e,function(){t.end()})});e.write(str2ab("GET /screenshot.jpg?password="+i+" HTTP/1.1\r\nConnection: close\r\n\r\n"),function(e){})})},"/device/(.*?)/sdcard-vysor/(.*)":function(e,t,n){var r=n[1];var o=n[2];t.headers["Connection"]="close";t.headers["Cache-Control"]="no-cache";t.headers["Content-Type"]="application/binary";Adb.pull({file:"/sdcard/vysor/"+o,serialno:r,socket:t},function(){t.end()})},"/device/(.*?)/video.flv":function(e,t,n){var r=n[1];var o=chrome.app.window.get(r);if(!u.isLicensed()){console.error("ignoring request, not licensed");t.code(402);t.write("This feature is only available in Vysor Pro",function(){t.end()});return}if(!o){console.error("device window",r,"not found");t.code(404);t.write("",function(){t.end()});return}if(!o.contentWindow.siphonFlv){console.error("siphonFlv",r,"not found");t.code(404);t.write("",function(){t.end()});return}var i=new DummySocket;t.headers["Connection"]="close";t.headers["Content-Type"]="video/x-flv";Socket.pump(i,t,function(){console.log("flv source closed")});o.contentWindow.siphonFlv(i)}};function r(){f.listen({port:t.port||0,address:"127.0.0.1"},function(e,t){console.log("http request",e.path);var r;var o;for(var i in n){r=e.path.match(i);o=n[i];if(r)break}if(!r){t.code(404);t.write("",function(){});return}o(e,t,r)},function(e){if(e){console.error("http server failed to listen",e);if(t.port){console.log("trying port 0");t.port=0;r()}return}t.port=f.socket.localPort;console.log("vysor http port: "+t.port);chrome.storage.local.set({vysorHttp:t})})}r()});u.refresh();function p(e){if(!s)return;var t=s.contentWindow.showModal;if(t)t(e)}function v(e,t){if(!s)return;var n=s.contentWindow.shortModal;if(n)n(e,t)}function g(){v(null,d)}function m(){if(!s||!s.contentWindow.updateVysorShareServer)return;s.contentWindow.updateVysorShareServer(n)}function y(e,t){console.log(e,"status",t);var n=chrome.app.window.get(e);if(!n||!n.contentWindow.updateWindowStatusText)return;n.contentWindow.updateWindowStatusText(t)}function w(e,t){y(e,"Installing Vysor APK...");AdbUtils.installApk("/Vysor-release.apk",e,t)}function b(e,n,r){y(e,"Connecting...");function o(o){var i=Math.round(Math.random()*(1<<30)).toString(16);var s="echo -n "+i+" > /data/local/tmp/vysor.pwd ; chmod 600 /data/local/tmp/vysor.pwd";AdbUtils.runMain(e,o,"com.koushikdutta.vysor.Main password="+i+" keyboard="+t,function(t){Adb.shell({serialno:e,command:'sh -c "'+s+'"'},function(e){Socket.eat(t);r(n,i)})},function(e,t){e.command="shell:"+e.command;Adb.sendClientCommand(e,t)})}function i(t){y(e,"Connecting...");AdbUtils.getApkPath(e,"com.koushikdutta.vysor",function(n){if(!n){t();return}AdbUtils.runMain(e,n,"com.koushikdutta.vysor.ProtocolVersionMain",function(e){var r=e.match(/vysor-io-.*?[\r\n]/);if(!r||!r.length){t(null);return}e=r[0];if(e)e=e.trim();console.log("protocol version: "+e);if(e!="vysor-io-44")t(null);else t(n)})})}i(function(t){if(!t){console.log("installing apk");w(e,function(t){i(function(n){if(!n){if(!t)t="";showNotification("Error installing APK:\n"+t.trim());k(e);return}o(n)})});return}o(t)})}function k(e){var t=e;if(r[e]&&r[e].id)t=r[e].id;var n=chrome.app.window.get(t);if(n)n.close()}var S=53516;function C(e,t){if(true){b(e,null,t);return}var n=S++;Adb.forward({from:"tcp:"+n,to:"tcp:53516",serialno:e},function(){b(e,n,t)})}function A(t,n,o,i){if(isElectron()){console.log("adb client socket factory path");t.contentWindow.adbSocketFactoryFactory={type:"adb-client",arguments:{serialno:n}}}else if(r[n]){console.log("vysor socket fast path");t.contentWindow.adbSocketFactory=r[n]}else if(e.isRunning()){console.log("adb server socket path");t.contentWindow.adbSocketFactory=e.adbDevices[n]}else{console.log("adb client socket path");t.contentWindow.adbSocketFactory=Adb.createSocketFactory(n)}h(t);t.contentWindow.openList=N;t.contentWindow.password=i;t.contentWindow.port=o;if(f&&f.socket)t.contentWindow.httpPort=f.socket.localPort;t.contentWindow.device=r[n]||J[n];t.contentWindow.tracker=a}function D(){setTimeout(function(){if(!chrome.app.window.getAll().length){chrome.runtime.reload()}},5e3)}function L(e,t,n){x();var o=e;if(r[e]&&r[e].id)o=r[e].id;var i=chrome.app.window.get(o);if(i){i.show();if(t){C(e,function(t,n){A(i,e,t,n);i.contentWindow.connectionReady()})}if(n)n(i);return}chrome.app.window.create("screen.html",{id:o,innerBounds:{width:576,height:1024}},function(t){var r;t.onClosed.addListener(r=function(){t.onClosed.removeListener(r);D();if(t.contentWindow.h264Socket){console.log("cleaning up h264 socket");t.contentWindow.h264Socket.destroy();t.contentWindow.h264Socket=null}if(t.contentWindow.inputWebSocket){console.log("cleaning up input websocket");t.contentWindow.inputWebSocket.close();t.contentWindow.inputWebSocket=null}});A(t,e,null,null);t.contentWindow.onload=function(){if(n)n(t);if(!J[e]){console.log("Vysor requested for",e,"which is not available yet");return}C(e,function(n,r){A(t,e,n,r);t.contentWindow.connectionReady()})}})}function I(){n=null;if(V)V.stopListen("share");m()}function O(e){var t=i[e];if(!t)return;t.gcmConn.destroy()}function T(e,t,n){var r=i[e];if(!r||!r.devices[t])return;if(r.gcmConn.gcmConns[t])r.gcmConn.gcmConns[t].destroy();var o;var s=r.gcmConn.gcmConns[t]={id:t,farm:true,newSocket:function(e,n){if(o)return;r.gcmConn.newSocket(t+":"+e,n)},destroy:function(){o=true;if(r.gcmConn.gcmConns[t]==s)delete r.gcmConn.gcmConns[t];delete J[s.serialno];r.gcmConn.newSocket("close:"+t,function(e){if(e)e.destroy()});var e=s.onClose;if(e){delete s.onClose;e()}re()}};P(function(e){e(s)},n);re()}var R;function E(e,t,n){function r(e){if(n)n(null,e)}e=new URL(e);var o=e.hash.replace("#","");function s(e){if(!V){r(d);return}V.connect({senderId:"64148182473",registrationId:e.registration,port:"share"},function(s){a.sendEvent("connected-device-farm");var c=i[o];var l;if(c){c.gcmConn.destroy()}var u=i[o]={info:e,gcmConn:s};s.gcmConns={};function d(){s.newSocket("devices:",function(e){readString(e,function(e){var t=JSON.parse(e);var n=t.devices;var r=t.sharedDevices;if(!u.devices){u.devices=n}else{$.each(Object.keys(n),function(e,t){delete u.devices[t]});$.each(Object.keys(u.devices),function(e,t){var n=s.gcmConns[t];if(n)n.destroy()});u.devices=n}u.sharedDevices=r;re()})})}s.openSocket=function(e,o){if(e.startsWith("challenge:")){console.log("received challenge",e);var i=e.split(":")[1];$.ajax({type:"post",url:"https://billing.vysor.io/verifyauth",headers:{Authorization:"Bearer "+t},data:{nonce:i},dataType:"json",success:function(e){R=JSON.parse(e.signed_data);console.log("sending challenge response",e);writeLine(o,e,function(){readLine(o,function(e){o.destroy();if(e=="ok"){d();if(n)n(u.info);return}r("Access denied: "+e)})})},error:function(e,t){r("Unable to verify identity.");o.destroy()}})}else if(e.startsWith("close:")){o.destroy();var c=e.split(":")[1];var a=s.gcmConns[c];if(!a){console.log("can't close unknown subconn");return}a.destroy()}else if(e.startsWith("tracker:")){console.log("got tracker socket");l=o;function f(){l.read(function(){d();f()})}f()}else{console.log("got unknown socket request",e);o.destroy()}};s.onClose=function(){if(i[o]==u)delete i[o];$.each(Object.keys(s.gcmConns),function(e,t){var n=s.gcmConns[t];if(n)n.destroy()})};console.log("Connection to device farm established",s)})}$.ajax({url:"https://billing.vysor.io/gcm/"+o,dataType:"json",success:s,error:function(e,t){showNotification("Unable to find server: "+t)}})}function U(e,t){function i(e){if(t)t(null,e);else showNotification(e)}function s(){if(t)t(n)}I();getAuthToken(e,function(e){if(!e){i("Unable to get Auth Token.");return}if(!V){i(d);return}function t(){console.log("registering vysor share server");$.ajax({type:"post",url:"https://billing.vysor.io/gcm",headers:{Authorization:"Bearer "+e},data:{registration:V.registrationId},dataType:"json",success:function(e){console.log("vysor share server",e);chrome.storage.local.set({lastDeviceFarmRegistrationId:V.registrationId});n="https://vysor.clockworkmod.com/server#"+e.id;s(n)}.bind(this),error:function(e,t){I();i("Unable to register server: "+t)}})}chrome.storage.local.get("lastDeviceFarmRegistrationId",function(e){if(e&&e.lastDeviceFarmRegistrationId==V.registrationId){console.log("device farm registration unchanged, not registering with server.");return}t()});var c;var a=[];function l(){c=throttleTimeout(c,null,500,function(){$.each(a,function(e,t){if(!t.trackerSocket)return;t.trackerSocket.write(str2ab("0000\n"),function(){})});re()})}var u;V.listen("share",function(e){var t;var n;var i;var s={};var c=Math.round(Math.random()*(1<<30)).toString(16)+Math.round(Math.random()*(1<<30)).toString(16);e.onClose=function(){var t=a.indexOf(e);if(t!=-1)a.splice(t,1);if(e.trackerSocket){e.trackerSocket.destroy();delete e.trackerSocket}$.each(Object.keys(s),function(e,t){var n=s[t];n.destroy()})};e.newSocket("challenge:"+c,function(r){if(!r){console.error("challenge socket failed");e.destroy();return}readLine(r,function(o){console.log("received challenge response",o);var s=JSON.parse(o);function l(e){e=e||"fail";console.log("Remote user failed to authorize",e);writeLine(r,e,function(){r.destroy()})}verifySignature("AQAB","hDuGsIhbjLYXteQX3F3KNriQHwUSZurS5voCkdpA1733A65pqtGOrk9g_yLiF94_vSK0VmL-4stq7WAYEbn6nw",s.signed_data,s.signature,function(o){if(o){l("Identify signature verification failed.");return}n=JSON.parse(s.signed_data);if(n.nonce!=c){l("Mismatched nonce in authentication.");return}function u(){function o(){a.push(e);t=true;writeLine(r,"ok",function(){r.destroy()});showNotification("Vysor is sharing Android devices with "+n.name,i);Adb.sendHostCommand("host:track-devices",function(t){if(!t){console.error("unable to track adb devices",chrome.runtime.lastError);return}e.newSocket("tracker:",function(n){if(!n){t.destroy();console.error("unable to open remote tracker");return}e.trackerSocket=n;Socket.stream(n,t)})})}isWhitelisted(n.email,function(e,t){if(e){o();return}if(!t){l("Denied by policy.");return}var r=chrome.runtime.getManifest().name;chrome.notifications.create({type:"basic",iconUrl:i,title:r,message:n.name+" is requesting access to Vysor shared Android devices.",buttons:[{title:"Allow"},{title:"Deny"}]},function(e){var t;var r=function(n){if(n!=e)return;chrome.notifications.onClosed.removeListener(r);chrome.notifications.onButtonClicked.removeListener(i);if(!t)l("Denied by user.")};var i=function(r,i){if(r!=e)return;chrome.notifications.clear(r);t=true;if(i==0){addToWhitelist(n.email,function(){m()});o()}else{l("Denied by user.")}};chrome.notifications.onClosed.addListener(r);chrome.notifications.onButtonClicked.addListener(i)})})}if(n.picture){blobFromUrl(n.picture,function(e){i=e;u()})}else{i="/icon.png";u()}})})});e.openSocket=function(i,c){if(!t){c.destroy();return}if(i=="devices:"){u=throttleTimeout(u,c,500,function(e){loadAllDeviceSettings(function(t){Adb.devices(function(n){if(!n)n={};$.each(Object.keys(n),function(e,o){if(r[o])delete n[o];sanitizeDeviceSettings(t[o]);if(t[o]&&t[o].friendlyName)n[o].name=t[o].friendlyName});var i={};$.each(Object.keys(o),function(e,t){i[t]={userInfo:o[t].userInfo}});$(e).each(function(e,t){writeString(t,{devices:n,sharedDevices:i},function(){t.destroy()})})})})})}else if(i.startsWith("close:")){c.destroy();var a=i.split(":")[1];var d=s[a];if(d)d.destroy()}else{var f=i.indexOf(":");if(f==-1){console.error("unexpected command received by device farm server");c.destroy();return}var a=i.substring(0,f);if(!J[a]){f=i.indexOf(":",f+1);if(f==-1){c.destroy();return}a=i.substring(0,f);if(!J[a]){console.error("request for unknown device",a);return}}var d=s[a];if(!d){var h=Adb.createSocketFactory(a);d=s[a]=new GcmDevice(h,J[a],{});d.destroy=function(){try{e.newSocket("close:"+a,function(e){if(e)e.destroy()})}catch(t){}var r=o[a];if(r){if(r.userInfo==n)delete r.userInfo;if(r.gcmConn==this)delete r.gcmConn;if(!r.key&&!r.gcmConn)delete o[a]}var i=this.onClose;if(i){delete this.onClose;i()}l()}.bind(d)}var p=o[a];if(!p)p=o[a]={};if(p.gcmConn!=d){_(a);p.gcmConn=d;p.userInfo=n;o[a]=p}l();var v=i.substring(f+1);d.openSocket(v,c)}}})})}function W(e){t=e}function N(){if(s){s.focus();return}chrome.app.window.create("list.html",{id:"list",innerBounds:{width:768,height:768,minWidth:768,minHeight:768}},function(t){s=t;s.contentWindow.openList=N;h(s);s.contentWindow.disconnectSharedDevice=ee;s.contentWindow.toggleShare=te;s.contentWindow.unshareDevice=F;s.contentWindow.quietSerial=Z;s.contentWindow.openWindow=L;s.contentWindow.closeWindow=k;s.contentWindow.createDeviceFarmConnection=T;s.contentWindow.destroyDeviceFarmConnection=O;s.contentWindow.adbServer=e;s.contentWindow.tracker=a;s.contentWindow.startWireless=ne;s.contentWindow.startDeviceFarm=U;s.contentWindow.stopDeviceFarm=I;s.contentWindow.updateKeyboard=W;s.contentWindow.onload=function(){h(s);m();re()};s.onClosed.addListener(function(){s=null;D()})})}function P(t,n){e.start();var o=new Server;o.listen({port:0,address:"127.0.0.1"},function(e){o.destroy();var i=new AdbDaemon(new AdbTcpTransport(e));t(function(e){a.sendEvent("connected-shared-device");var t="127.0.0.1:"+o.localPort;e.serialno=t;if(!e.id)e.id=t;r[t]=e;console.log("connected gcm socket");e.openSocket=function(){console.log("got a new socket? this should not happen...");e.destroy()};i.onClose=e.onClose=function(){delete r[t];i.destroy();e.destroy()};e.onClose=function(){delete r[t];i.destroy();e.destroy();showNotification("Disconnected from shared Android device.")};i.openSocket=function(t,n){e.newSocket(t,function(e){Socket.stream(n,e,function(){})})};e.newSocket("properties",function(r){readString(r,function(r){var o=AdbDevice.parseConnectionPayload(r);e.name=e.name||o["ro.product.model"].replace("_"," ");i.start(r);console.log("got properties",r);n(t)})})})}.bind(this),function(e){if(e){console.log("adb daemon failed to listen: "+e);return}var t="127.0.0.1:"+o.localPort;r[t]={id:t,destroy:function(){}};var n="127.0.0.1:"+o.localPort;Adb.sendHostCommand("host:connect:"+n,function(e,t){if(!e){return}e.destroy();t=ab2str(t);console.log("adb connect result",t)})}.bind(this))}function M(e,t){showNotification("Vysor is connecting to a remote Android device");if(s)s.show();console.log("attempting to connect to shared device",e);if(!V){g();return}var n=new URL(e);var r=getQueryVariable("senderId",n);var o=getQueryVariable("registrationId",n);var i=getQueryVariable("channel",n);if(!r)r="64148182473";P(function(e){V.connect({senderId:r,registrationId:o,port:i},e)},t)}chrome.app.runtime.onLaunched.addListener(function(e){N();if(e&&e.id=="vysor_purchase"){u.refresh(null,true)}if(e&&e.id=="vysor_presentation"){M(e.url,function(e){L(e)})}if(e&&e.id=="vysor_device_farm"){console.log("device farm",e.url);if(s)s.show();N();showNotification("Vysor is connecting to shared Android devices");getAuthToken(true,function(t){if(!t){showNotification("Unable to get auth token");return}E(e.url,t,function(e,t){if(t){v("Vysor Share","Unable to connect to shared devices. "+t);return}v("Vysor Share","Connected to "+e.name+"'s remote devices.")})})}x()});function x(){chrome.runtime.requestUpdateCheck(function(e,t){console.log("update check",arguments);if(e=="update_available"){ge()}})}function _(e){var t=o[e];if(t&&t.gcmConn){var n=t.gcmConn;delete t.gcmConn;n.destroy()}}function F(e){_(e);delete o[e];re()}function B(e,t){function n(e){if(t)t(null,e)}var r=J[e];if(!V){n(d);return}var i=Math.round(Math.random()*(1<<30)).toString(16);if(!o[e])o[e]={};o[e].key=i;re();var s="https://vysor.clockworkmod.com/redirect/?registrationId="+encodeURIComponent(V.registrationId)+"&channel="+i;console.log(s);V.listen(i,function(t){a.sendEvent("shared-device");var n=o[e];if(!n||n.key!=i){t.destroy();console.log("device is no longer being shared.");return}if(n.gcmConn)n.gcmConn.destroy();n.gcmConn=t;n.userInfo={name:"Someone"};re();console.log("accepted gcm socket");var s=Adb.createSocketFactory(e);var c=new GcmDevice(s,r,t);c.onOpenSocket=function(t,n){if(t=="webstart"){b(e,null,function(e,t){writeLine(n,t,function(){console.log("sent password",t);n.destroy()})});return true}}});var c="https://tu3ph.app.goo.gl/?ad=0&apn=com.koushikdutta.inkwire&link="+encodeURIComponent(s);t(c)}var V;var K;function j(){if(K)return K;console.log("creating persistent gcm connection");return K=new Promise(function(e,t){GcmRtcManager.start({3505780036:"AIzaSyDt0GimPRhk8_d_4XjOYzQUn50UkvXhMtE",64148182473:"AIzaSyDd7k1v017osyYbIC92fyf-36s3pv0z73U"},{iceServers:[{url:"turn:n0.clockworkmod.com",username:"foo",credential:"bar"},{url:"turn:n1.clockworkmod.com",username:"foo",credential:"bar"}]},function(t){V=t;console.log("persistent gcm connection created",t!=null);if(!V){K=null;e();return}V.defaultSenderId="64148182473";e(V)})})}function q(e){return function(){var t=arguments;j().then(function(){e.apply(null,t)})}}E=q(E);U=q(U);B=q(B);M=q(M);chrome.storage.local.get("share-all-devices",function(e){if(e["share-all-devices"]){U(false,function(){m()})}});var H={};var z={};var J={};var Y;var G={};var X={};function Q(e){var t=X[e];clearTimeout(t);X[e]=setTimeout(function(){delete X[e]},1e4);delete G[e]}function Z(e){var t=G[e];clearTimeout(t);G[e]=setTimeout(function(){delete G[e]},1e4);delete X[e]}function ee(e){k(e);var t=r[e];if(t)t.destroy()}function te(e,t){if(o[e])F(e);else B(e,t);re()}function ne(e){var t=Adb.createSocketFactory(e);t.newSocket("shell:ifconfig wlan0",function(n){if(!n){console.log("error running tcpip:5555");return}readString(n,function(n){console.log("ifconfig result",n);var r=n.match("inet addr:(.*?) ");if(!r)r=n.match("wlan0: ip (.*?) ");if(!r){showNotification("Unable to switch to wireless mode. Is your Android connected to Wifi?");return}var o=r[1];var i=o+":5555";if(chrome.app.window.get(i)){H[e]=i;z[i]=e;L(i);return}function s(e){Adb.sendHostCommand("host:connect:"+i,function(t,n){if(!t){return}t.destroy();n=ab2str(n);if(n.indexOf("unable to connect")!=-1){showNotification("Unable to connect via wireless. Is your Android on the same network as your PC?");return}chrome.storage.local.set({lastConnectAddress:i});console.log("adb connect result",n);if(e)c()})}function c(){H[e]=i;z[i]=e;re();k(e);showNotification("Vysor is connected wirelessly. You may disconnect your device.");a.sendEvent("go-wireless");Z(i);L(i,true,function(e){Q(i);e.contentWindow.tryReconnect=function(){Q(i);s(false)}})}if(J[i]){c();return}Z(e);t.newSocket("tcpip:5555",function(e){if(!e){showNotification("Failure while switching to wireless mode.");return}readString(e,function(e){console.log("tcpip:5555 result",e);s(true)})})})})}function re(){if(!s||!s.contentWindow.refreshList)return;s.contentWindow.refreshList(J,r,R,i,o,z,H,V&&V.isListening("share"),Y,e.isRunning(),se)}var oe;function ie(){chrome.storage.local.get("connect-automatically",function(t){var n=t["connect-automatically"]!==false;Adb.devices(function(t){if(t){var o=[];var i;$.each(t,function(o,s){i=true;if(!J[o]){F(o);var c=t[o];var a=c.properties.indexOf("emulator")!=-1||c.properties.indexOf("vbox")!=-1;if(!a&&oe&&!G[o]){var l=o;if(r[o])l=r[o].id;if(chrome.app.window.get(l)||e.isRunning()||X[o]){L(o,true)}else if(n){if(!chrome.app.window.get(o)){var u=chrome.runtime.getManifest().name;chrome.notifications.create("never-start-automatically",{type:"basic",iconUrl:"/icon.png",title:u,message:"Vysor has connected to an Android device and is starting.",buttons:[{title:"Never Start Automatically"}]})}L(o,true)}}}});J=t}else{J={}}re();oe=true})})}var se;function ce(){if(isElectron()){var e=require("os").platform();var t=chrome.runtime.getAppDirectory();var n=require("path").join(t,"native",e,"adb");if(e=="win32")n+=".exe";else require("fs").chmodSync(n,"755");console.log("attempting to start built in adb binary",n);require("child_process").execFile(n,["start-server"]);return}if(se)return;if(!window.chrome||!window.chrome.runtime||!window.chrome.runtime.connectNative)return;se=chrome.runtime.connectNative("com.clockworkmod.adb");se.onDisconnect.addListener(function(){se=null});se.postMessage({command:"start-server"})}var ae;function le(){if(!ae)ce();ae=throttleTimeout(ae,null,1e4,ce)}var ue;var de;function fe(){de=throttleTimeout(de,null,300,function(){ie()})}function he(){if(ue)return;function t(e){e.read(function(n){fe();t(e)})}Adb.sendHostCommand("host:track-devices",function(n){if(ue){n.destroy();return}if(!n)return;console.log("Connected to ADB Server");if(e.isRunning())console.log("Using Vysor ADB");else console.log("Using Android SDK ADB");Y=true;n.onClose=function(){ue=null;Y=false;fe()};ue=n;t(n);fe()})}function pe(){he();re();if(!Y){le()}setTimeout(pe,1e3)}pe();fe();var ve;function ge(){ve=throttleTimeout(ve,null,1e4,function(){var e=chrome.runtime.getManifest().name;chrome.notifications.create("reload",{type:"basic",iconUrl:"/icon.png",title:e,message:"There is an update available for Vysor.",buttons:[{title:"Reload"}]})})}chrome.runtime.onUpdateAvailable.addListener(function(){D()});chrome.notifications.onButtonClicked.addListener(function(e,t){if(e=="reload"){chrome.runtime.reload()}else if(e=="never-start-automatically"){chrome.storage.local.set({"connect-automatically":false});chrome.notifications.clear(e)}});chrome.notifications.onClicked.addListener(function(e,t){})})();

    这样就可以使用Vysor专业版了。

    展开全文
  • windows PC端远程控制android设备工具,VysorPro2.1.2 无广告破解版。
  • Vysor 最新安装使用教程

    万次阅读 2018-06-10 12:35:35
    Vysor 是一款 Chrome 应用,能够在 Chrome 里通过 USB 直接控制 Android 设备,无需 root。 安装步骤 官方网站 1 桌面端环境配置 1.1 进入官网,准备下载安装包 1.2 下载chorme 插件 注意 软件的类型...

    前言


    Vysor 是一款 Chrome 应用,能够在 Chrome 里通过 USB 直接控制 Android 设备,无需 root。

    下一篇文章为vysor的破解教程

    这里写图片描述

    安装步骤

    官方网站

    1 桌面端环境配置


    1.1 进入官网,准备下载安装包
    这里写图片描述

    1.2 下载chorme 插件
    注意
    软件的类型不要选错,因为后面会针对Chorme版本进行破解。
    这里写图片描述
    1.3 在chorme应用商店下载

    这里写图片描述
    注意
    需要越狱的朋友

    • 可自行搜索蓝灯(Lantern )等免费的VPN。
    • 离线安装下载Chorme插件

    1.4 安装完成之后,打开界面

    需要注意两点:

    • 使用USB接口连接安卓手机
    • windows 用户需要单独下载ADB Drivers [win10亲测可用], Mac机无需下载[亲测可直接使用]。

    这里写图片描述

    此时,桌面端环境已经配置完成。

    2 移动端环境配置


    2.1 手机通过USB连接电脑
    注意
    手机需要打开调式模式,如何打开调式模式,可自行百度搜索:手机打开调式模式
    根据对应的安卓版本号,找对应教程即可。

    这里写图片描述

    2.2 自动连接Vysor

    当我们打开调式模式,连接进入电脑之后,就会出现自动提示了。
    这里写图片描述

    注意
    如果没有出现该图标的话,将USB连接线重新插入电脑进行重连。

    2.3 开始使用

    如果进展顺利,就可以看见下面的加载界面
    这里写图片描述

    然后,就可以看见期待已久的手机界面了。
    这里写图片描述

    3 使用教程


    3.1 专业版功能(收费)
    这里写图片描述
    3.2 功能介绍
    这里写图片描述

    上面这些都是需要收费的,但是作为一个合格的程序员。怎么能满足使用低配版软件呢?下一篇,讲解Vysor破解教程。谢谢~~~

    这里写图片描述

    展开全文
  • Vysor(PC破解版)

    2020-07-30 23:31:57
    Vysor,PC版,在台式机器上,可以通过usb线控制安卓手机,实现鼠标控制。 用everything搜索uglify.js,将uglify.js覆盖Vysor目录下原有的uglify.js,实现破解。
  • vysor pc工具

    2020-07-30 23:31:54
    vysor 连接移动端设备,进行pc查看界面和操作。
  • vysor原理以及Android同屏方案

    千次阅读 2019-03-27 00:24:40
    vysor是一个免root实现电脑控制手机的chrome插件,目前也有几款类似的通过电脑控制手机的软件,不过都需要root权限,并且流畅度并不高。vysor没有多余的功能,流畅度也很高,刚接触到这款插件时我惊讶于它的流畅度...

    vysor是一个免root实现电脑控制手机的chrome插件,目前也有几款类似的通过电脑控制手机的软件,不过都需要root权限,并且流畅度并不高。vysor没有多余的功能,流畅度也很高,刚接触到这款插件时我惊讶于它的流畅度以及免root,就一直对它的实现原理很感兴趣。这款插件我用了大半年,最近在升级后我发现它居然开始收费了,终生版需要39.99美元,不过经过简单的分析后我很轻松的破解了它的pro版,在分析的过程中发现它的原理并不复杂,所以就打算自己也实现一个类似的软件。

    截屏常见的方案

    在介绍vysor的原理前我先简单介绍一下目前公开的截屏方案。

    • View.getDrawingCache()

    这是最常见的应用内截屏方法,这个函数的原理就是通过view的Cache来获取一个bitmap对象,然后保存成图片文件,这种截屏方式非常的简单,但是局限行也很明显,首先它只能截取应用内部的界面,甚至连状态栏都不能截取到。其次是对某些view的兼容性也不好,比如webview内的内容也无法截取。

    • 读取/dev/graphics/fb0

    因为Android是基于linux内核,所以我们也能在android中找到framebuffer这个设备,我们可以通过读取/dev/graphics/fb0这个帧缓存文件中的数据来获取屏幕上的内容,但是这个文件是system权限的,所以只有通过root才能读取到其中的内容,并且直接通过framebuffer读取出来的画面还需要转换成rgb才能正常显示。下面是通过adb读取这个文件内容的效果。

    • 反射调用SurfaceControl.screenshot()/Surface.screenshot()

    SurfaceControl.screenshot()(低版本是Surface.screenshot())是系统内部提供的截屏函数,但是这个函数是@hide的,所以无法直接调用,需要反射调用。我尝试反射调用这个函数,但是函数返回的是null,后面发现SurfaceControl这个类也是隐藏的,所以从用户代码中无法获取这个类。也有一些方法能够调用到这个函数,比如重新编译一套sdk,或者在源码环境下编译apk,但是这种方案兼容性太差,只能在特定ROM下成功运行。

    • screencap -p xxx.png/screenshot xxx.png

    这两个是在shell下调用的命令,通过adb shell可以直接截图,但是在代码里调用则需要系统权限,所以无法调用。可以看到要实现类似vysor的同步操作,可以使用这两个命令来截取屏幕然后传到电脑显示,但是我自己实现后发现这种方式非常的卡,因为这两个命令不能压缩图片,所以导致获取和生成图片的时间非常长。

    • MediaProjection,VirtualDisplay (>=5.0)

    在5.0以后,google开放了截屏的接口,可以通过”虚拟屏幕”来录制和截取屏幕,不过因为这种方式会弹出确认对话框,并且只在5.0上有效,所以我没有对这种方案做深入的研究。

    可以看到,上述方案中并没有解决方案能够做到兼容性和效率都非常完美,但是我在接触到vysor后发现它不但画面清晰,流畅,而且不需要root。那么它是用了什么黑科技呢?下面我们反编译它的代码来研究一下它的实现机制。

    vysor原理

    反编译vysor的apk后可以发现它的代码并不多,通过分析后我发现它的核心代码在Main这个类中。

    首先来看Main函数的main方法,这个方法比较长,这里直接贴出源码。

    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
    
    public static void main(String[] args) throws Exception {
            if (args.length > 0) {
                commandLinePassword = args[0];
                Log.i(LOGTAG, "Received command line password: " + commandLinePassword);
            }
            Looper.prepare();
            looper = Looper.myLooper();
            AsyncServer server = new AsyncServer();
            AsyncHttpServer httpServer = new AsyncHttpServer() {
                protected boolean onRequest(AsyncHttpServerRequest request, AsyncHttpServerResponse response) {
                    Log.i(Main.LOGTAG, request.getHeaders().toString());
                    return super.onRequest(request, response);
                }
            };
            String str = "getInstance";
            Object[] objArr = new Object[0];
            InputManager im = (InputManager) InputManager.class.getDeclaredMethod(r20, new Class[0]).invoke(null, objArr);
            str = "obtain";
            MotionEvent.class.getDeclaredMethod(r20, new Class[0]).setAccessible(true);
            str = "injectInputEvent";
            Method injectInputEventMethod = InputManager.class.getMethod(r20, new Class[]{InputEvent.class, Integer.TYPE});
            KeyCharacterMap kcm = KeyCharacterMap.load(-1);
            Class cls = Class.forName("android.os.ServiceManager");
            Method getServiceMethod = cls.getDeclaredMethod("getService", new Class[]{String.class});
            IClipboard clipboard = IClipboard.Stub.asInterface((IBinder) getServiceMethod.invoke(null, new Object[]{"clipboard"}));
            clipboard.addPrimaryClipChangedListener(new AnonymousClass3(clipboard), null);
            IPowerManager pm = IPowerManager.Stub.asInterface((IBinder) getServiceMethod.invoke(null, new Object[]{"power"}));
            IWindowManager wm = IWindowManager.Stub.asInterface((IBinder) getServiceMethod.invoke(null, new Object[]{"window"}));
            IRotationWatcher watcher = new Stub() {
                public void onRotationChanged(int rotation) throws RemoteException {
                    if (Main.webSocket != null) {
                        Point displaySize = SurfaceControlVirtualDisplayFactory.getCurrentDisplaySize();
                        JSONObject json = new JSONObject();
                        try {
                            json.put("type", "displaySize");
                            json.put("screenWidth", displaySize.x);
                            json.put("screenHeight", displaySize.y);
                            json.put("nav", Main.hasNavBar());
                            Main.webSocket.send(json.toString());
                        } catch (JSONException e) {
                        }
                    }
                }
            };
            wm.watchRotation(watcher);
            httpServer.get("/screenshot.jpg", new AnonymousClass5(wm));
            httpServer.websocket("/input", "mirror-protocol", new AnonymousClass6(watcher, im, injectInputEventMethod, pm, wm, kcm));
            httpServer.get("/h264", new AnonymousClass7(im, injectInputEventMethod, pm, wm));
            Log.i(LOGTAG, "Server starting");
            AsyncServerSocket rawSocket = server.listen(null, 53517, new AnonymousClass8(wm));
            if (httpServer.listen(server, 53516) == null || rawSocket == null) {
                System.out.println("No server socket?");
                Log.e(LOGTAG, "No server socket?");
                throw new AssertionError("No server socket?");
            }
            System.out.println("Started");
            Log.i(LOGTAG, "Waiting for exit");
            Looper.loop();
            Log.i(LOGTAG, "Looper done");
            server.stop();
            if (current != null) {
                current.stop();
                current = null;
            }
            Log.i(LOGTAG, "Done!");
            System.exit(0);
        }
    

     

    这个软件koushikdutta是由开发的,这个团队以前发布过一个非常流行的开源网络库:async。在这个项目中也用到了这个开源库。main函数主要是新建了一个httpserver然后开放了几个接口,通过screenshot.jpg获取截图,通过socket input接口来发送点击信息,通过h264这个接口来获取实时的屏幕视频流。每一个接口都有对应的响应函数,这里我们主要研究截图,所以就看screenshot这个接口。h264这个接口传输的是实时的视频流,所以就流畅性来说应该会更好,它也是通过virtualdisplay来实现的有兴趣的读者可以自行研究。

    接下来我们来看screenshot对应的响应函数AnonymousClass5的实现代码。

    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
    
    * renamed from: com.koushikdutta.vysor.Main.5 */
        static class AnonymousClass5 implements HttpServerRequestCallback {
            final /* synthetic */ IWindowManager val$wm;
    
            AnonymousClass5(IWindowManager iWindowManager) {
                this.val$wm = iWindowManager;
            }
    
            public void onRequest(AsyncHttpServerRequest request, AsyncHttpServerResponse response) {
                if (Main.checkPassword(request.getQuery().getString("password"))) {
                    Log.i(Main.LOGTAG, "screenshot authentication success");
                    try {
                        Bitmap bitmap = EncoderFeeder.screenshot(this.val$wm);
                        ByteArrayOutputStream bout = new ByteArrayOutputStream();
                        bitmap.compress(CompressFormat.JPEG, 100, bout);
                        bout.flush();
                        response.send("image/jpeg", bout.toByteArray());
                        return;
                    } catch (Exception e) {
                        response.code(500);
                        response.send(e.toString());
                        return;
                    }
                }
                Log.i(Main.LOGTAG, "screenshot authentication failed");
                response.code(401);
                response.send("Not Authorized.");
            }
        }
    

     

    这个类传入了一个wm类,这个类是用来监听屏幕旋转的,这里不用管它。另外在vysor开始运行时,会随机生成一个验证码,只有验证通过才能进行连接,所以这里有一个验证的过程,这里也不过管。可以看到这个类定义的响应函数的代码非常简单,就是通过EncoderFeeder.screenshot()函数来过去截图的bitmap,然后返回给请求端。那么EncoderFeeder.screenshot这个函数是怎样实现截图的呢?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    public static Bitmap screenshot(IWindowManager wm) throws Exception {
            String surfaceClassName;
            Point size = SurfaceControlVirtualDisplayFactory.getCurrentDisplaySize(false);
            if (VERSION.SDK_INT <= 17) {
                surfaceClassName = "android.view.Surface";
            } else {
                surfaceClassName = "android.view.SurfaceControl";
            }
            Bitmap b = (Bitmap) Class.forName(surfaceClassName).getDeclaredMethod("screenshot", new Class[]{Integer.TYPE, Integer.TYPE}).invoke(null, new Object[]{Integer.valueOf(size.x), Integer.valueOf(size.y)});
            int rotation = wm.getRotation();
            if (rotation == 0) {
                return b;
            }
            Matrix m = new Matrix();
            if (rotation == 1) {
                m.postRotate(-90.0f);
            } else if (rotation == 2) {
                m.postRotate(-180.0f);
            } else if (rotation == 3) {
                m.postRotate(-270.0f);
            }
            return Bitmap.createBitmap(b, 0, 0, size.x, size.y, m, false);
        }
    

    这里的截图的核心代码也是反射调用Surface/SurfaceControl的screenshot方法。但是我们前面已经了解到,这个类只有在系统权限下才能获取到,那么vysor又是怎么调用到这个函数的呢?我们可以确认的是vysor不是通过重编译sdk和使用系统签名来完成的,因为那样只能对特定的rom适用。

    当时看到这里的代码后我也非常困惑,vysor是怎么调用到这个类的。我注意到了vysor的核心代码不是在某个Activity或者Service中而是在一个Main类中,按照一般的逻辑来说,这种实时传屏应该是放在Service中不断截屏然后发给服务端,所以我决定再看下它的服务端的代码。

    vysor的服务端是一个chrome插件,用javascript写成的,所以找到源码比java更加简单。虽然js经过混淆,但是很容易的可以通过一些工具来解密。然后就是分析它的代码了,终于被我找到了关键的代码。

    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
    
    function y(e, t, n) {
            m(e, "Connecting...");
    
            function o(o) {
                var i = Math.round(Math.random() * (1 << 30)).toString(16);
                var r = "echo -n " + i + " > /data/local/tmp/vysor.pwd ; chmod 600 /data/local/tmp/vysor.pwd";
                Adb.shell({
                    command: "ls -l /system/bin/app_process*",
                    serialno: e
                }, function(s) {
                    var c = "/system/bin/app_process";
                    if (s && s.indexOf("app_process32") != -1) {
                        c += "32"
                    }
                    Adb.sendClientCommand({
                        command: 'shell:sh -c "CLASSPATH=' + o + " " + c + " /system/bin com.koushikdutta.vysor.Main " + i + '"',
                        serialno: e
                    }, function(o) {
                        Adb.shell({
                            serialno: e,
                            command: 'sh -c "' + r + '"'
                        }, function(e) {
                            Socket.eat(o);
                            n(t, i)
                        })
                    })
                })
            }
    

    可以看到上面的代码是调用了adb shell命令来启动com.koushikdutta.vysor.Main类,并且上面获取了app_process这个程序。相信对android熟悉读者已经明白它的原理了。我简单解释一下。我们已经知道Surface/SurfaceControl这两个类是需要具有相应权限的程序才能调用到,用户进程无法获取到。adb shell可以调用screencap或者screenshot来截取屏幕,那就说明adb shell具有截屏的权限。Surface/SurfaceControl和screenshot/screencap它们内部的实现机制应该是相同的,所以也就是说adb shell是具有截屏权限的也就是能够调用到Surface/SurfaceControl。那么我们怎么通过adb shell来调用到这两个类呢,答案就是app_process。app_process可以直接运行一个普通的java类,详细的资料大家可以在网上找到。也就是说我们通过adb shell运行app_process,然后通过app_process来运行一个java类,在java类中就可以访问到Surface/SurfaceControl这两个类,是不是很巧妙?

    理论有了,下面我们来通过代码验证。这里我们可以直接使用vysor的代码。因为是测试用所以我没有添加其他功能。

    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
    
    public class Main {
    
    
        static Looper looper;
    
        public static void main(String[] args) {
    
            AsyncHttpServer httpServer = new AsyncHttpServer() {
                protected boolean onRequest(AsyncHttpServerRequest request, AsyncHttpServerResponse response) {
                    return super.onRequest(request, response);
                }
            };
    
            Looper.prepare();
            looper = Looper.myLooper();
            System.out.println("Andcast Main Entry!");
            AsyncServer server = new AsyncServer();
            httpServer.get("/screenshot.jpg", new AnonymousClass5());
            httpServer.listen(server, 53516);
    
            Looper.loop();
    
        }
    
        /* renamed from: com.koushikdutta.vysor.Main.5 */
        static class AnonymousClass5 implements HttpServerRequestCallback {
    
            public void onRequest(AsyncHttpServerRequest request, AsyncHttpServerResponse response) {
                    try {
                        Bitmap bitmap = ScreenShotFb.screenshot();
                        ByteArrayOutputStream bout = new ByteArrayOutputStream();
                        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bout);
                        bout.flush();
                        response.send("image/jpeg", bout.toByteArray());
                        return;
                    } catch (Exception e) {
                        response.code(500);
                        response.send(e.toString());
                        return;
                    }
            }
        }
    }
    

     

    编译成apk然后安装后,我们使用adb shell来运行这个类,主要方法如下,首先导出classpath,否则会提示找不到类。

    1
    
    export CLASSPATH=/data/app/com.zke1e.andcast-1/base.apk
    

     

    然后调用app_process来启动这个类。

    1
    
    exec app_process /system/bin com.zke1e.andcast.Main '$@'
    

     

    可以看到类已经成功运行了,正在监听请求。

    然后使用adb forward转发端口。

    1
    
    adb forward tcp:53516 tcp:53516
    

    最后在浏览器里访问,就可以获取截图了。

    当然只有简单的截图功能是不够,我们需要能够流畅实时的传输android的屏幕,并且能够在电脑上控制,经过两天的编写,我使用java实现了类似vysor的功能。从流畅度和清晰度上都和vysor差不多,后续还会考虑加入文件传输和声音传输等功能。最近计划编写一个java版的android反编译集成环境,类似android killer。因为android killer只能在windows上使用,而linux下没有类似的方面的软件。到时这个同步软件可以作为插件和反编译套件集成。最后放一张截图。

    更新

    经过一段时间的研究,最后实现了将传输的截图改成了h264码流,提高的流畅度和稳定性,然后将接受端放在了浏览器中,实现了可以在浏览器中对android手机进行控制,下面是截图。

     

    原文地址:http://zke1ev3n.me/2016/07/02/vysor原理以及Android同屏方案/

    展开全文
  • vysor_1_8_31.tar.zip

    2020-07-22 23:32:28
    vysor android 同屏操作软件 vysor android 同屏操作软件
  • Vysor

    2020-02-25 10:52:01
    1、Vysor 安装教程 2、Vysor 最新安装使用教程 3、官网 4、Vysor 使用
    展开全文
  • Vysor 安装教程

    千次阅读 2018-08-09 16:22:24
    在搜索框中输入 Vysor 有可能因为网络的原因搜索不到,可以直接访问Vysor插件地址进入如下界面 点击添加至 Chrome ,稍等片刻,插件就安装成功了,应用界面应用界面就会出Vysor 插上手机,打开usb调试,...
  • vysor 破解

    千次阅读 2019-07-10 15:39:39
    Vysor_2.1.2破解方法 1、进入安装目录一般是 ....\Vysor\app-2.1.2\resources\app\unpacked-crx;目录下找到 “uglify.js” 文件,打开查找“ k="Account Management" ”然后将 g=!1,b!=1 改成 g=1,b=1 2、防止...
  • Ubuntu 下安装 Vysor投屏软件

    千次阅读 2019-09-26 18:12:55
    ubuntu 下vysor 投屏其实是 谷歌的插件: 我们先下载crx 插件: https://www.crx4chrome.com/crx/15104/ 直接下载链接: ... 下载好后重命...
  • Vysor Pro 2.2.2 Windows

    2020-05-17 14:47:10
    上次分享了Vysor Pro 2.1.x版本 主要针对Mac平台,Windows也同理的 做安装开发的这个很好用,解放双手,一个鼠标即可操控安卓手机,不要经常拿着手机点了,其他软件使用体验不如这个 下面是软件截图 Vysor正常...
  • Vysor Pro巧妙破解

    千次阅读 2018-09-27 14:25:37
    用谷歌(Chrome)应用商店 搜索vysor下载应用即可; 打开vysor,用手机USB连接电脑,打开usb调式 链接成功界面如下: 破解 显示此界面属于连接成功,但是并不是高清而且功能太少,上网搜了搜教程,但是最近更新...
  • 5 理论上会自动弹出Vyson的窗口,如果没弹出,通过Chrome的扩展界面找到Vysor点下面的“启动” 6 在Vysor的设置里面,记得把速率改成4M,Resolution选Original,Decoder选software(hardware会挂,很不稳定) 7 这时...
  • 偶然发现了一个很实用的投屏软件VysorVysor是一个谷歌浏览器的插件,可以将手机的屏幕投屏到电脑上,也可以从电脑上来控制屏幕。下面来介绍一下安装的过程,是以Windows10家庭版和华为手机来做的演示 安装: 1....
  • Vysor:在电脑里控制你的安卓手机

    千次阅读 2015-10-15 20:09:17
    Vysor的开发背景 随着手机的普及,移动互联网在迅速取代着桌面互联网的地位,大量的用户习惯使用手机观看新闻、聊天、玩游戏,而你有没有想过使用手机上的软件而不用手机设备?今天给大家推荐的这款chrome插件,...
  • 1,下载vysor, 版本不能太老,如果比设备上已经安装的还老,会报一个[INSTALL_FAILED_VERSION_DOWNGRADE]的错误 2,点 chrome右上角三点- 》更多工具-》扩展程序 3,点“加载已解压的扩展程序” 4,选择你下载...
  • vysor1.8.3破解版

    2020-07-30 23:30:12
    手机投屏电脑神器,反向控制神器,大名鼎鼎的vysor,无需搬梯子,在电脑大屏幕上吃鸡就这么简单,vysor你值得拥有
  • Vysor2.0.8教程 破解篇

    万次阅读 热门讨论 2018-10-18 21:16:16
    在上一章节中,介绍了Vysor如何安装以及使用的教程,那么,就开始介绍一下如何破解Vysor。 注意 本文阅读前提是默认你以及阅读或了解过上一章节的基础上进行的。 1 找到chorme插件位置 1.1 寻找uglify.js...
1 2 3 4 5 ... 20
收藏数 645
精华内容 258
关键字:

vysor