const{Cc,Ci,Cu,CC}=require("chrome");const Services=require("Services");const protocol=require("devtools/server/protocol");const{method,RetVal}=protocol;const{Promise:promise}=Cu.import("resource://gre/modules/Promise.jsm",{});const{LongStringActor}=require("devtools/server/actors/string");const{DebuggerServer}=require("devtools/server/main");Cu.import("resource://gre/modules/PermissionsTable.jsm")
const APP_MAP={'{ec8030f7-c20a-464f-9b0e-13a3a9e97384}':'firefox','{3550f703-e582-4d05-9a08-453d09bdfdc6}':'thunderbird','{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}':'seamonkey','{718e30fb-e89b-41dd-9da7-e25a45638b28}':'sunbird','{3c2e2abc-06d4-11e1-ac3b-374f68613e61}':'b2g','{aa3c5121-dab2-40e2-81ca-7ea25febc110}':'mobile/android','{a23983c0-fd0e-11dc-95ff-0800200c9a66}':'mobile/xul'}
exports.register=function(handle){handle.addGlobalActor(DeviceActor,"deviceActor");};exports.unregister=function(handle){};let DeviceActor=protocol.ActorClass({typeName:"device",_desc:null,_getAppIniString:function(section,key){let inifile=Services.dirsvc.get("GreD",Ci.nsIFile);inifile.append("application.ini");if(!inifile.exists()){inifile=Services.dirsvc.get("CurProcD",Ci.nsIFile);inifile.append("application.ini");}
if(!inifile.exists()){return undefined;}
let iniParser=Cc["@mozilla.org/xpcom/ini-parser-factory;1"].getService(Ci.nsIINIParserFactory).createINIParser(inifile);try{return iniParser.getString(section,key);}catch(e){return undefined;}},_getSetting:function(name){let deferred=promise.defer();if("@mozilla.org/settingsService;1"in Cc){let settingsService=Cc["@mozilla.org/settingsService;1"].getService(Ci.nsISettingsService);let req=settingsService.createLock().get(name,{handle:(name,value)=>deferred.resolve(value),handleError:(error)=>deferred.reject(error),});}else{deferred.reject(new Error("No settings service"));}
return deferred.promise;},getDescription:method(function(){ let appInfo=Services.appinfo;let win=Services.wm.getMostRecentWindow(DebuggerServer.chromeWindowType);let utils=win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);desc={appid:appInfo.ID,apptype:APP_MAP[appInfo.ID],vendor:appInfo.vendor,name:appInfo.name,version:appInfo.version,appbuildid:appInfo.appBuildID,platformbuildid:appInfo.platformBuildID,platformversion:appInfo.platformVersion,geckobuildid:appInfo.platformBuildID,geckoversion:appInfo.platformVersion,changeset:this._getAppIniString("App","SourceStamp"),useragent:win.navigator.userAgent,locale:Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry).getSelectedLocale("global"),os:null,hardware:"unknown",processor:appInfo.XPCOMABI.split("-")[0],compiler:appInfo.XPCOMABI.split("-")[1],dpi:utils.displayDPI,brandName:null,channel:null,profile:null,width:win.screen.width,height:win.screen.height}; let profd=Services.dirsvc.get("ProfD",Ci.nsILocalFile);let profservice=Cc["@mozilla.org/toolkit/profile-service;1"].getService(Ci.nsIToolkitProfileService);var profiles=profservice.profiles;while(profiles.hasMoreElements()){let profile=profiles.getNext().QueryInterface(Ci.nsIToolkitProfile);if(profile.rootDir.path==profd.path){desc.profile=profile.name;break;}}
if(!desc.profile){desc.profile=profd.leafName;} 
try{desc.channel=Services.prefs.getCharPref('app.update.channel');}catch(e){}
if(desc.apptype=="b2g"){ desc.os="B2G";return this._getSetting('deviceinfo.hardware').then(value=>desc.hardware=value).then(()=>this._getSetting('deviceinfo.os')).then(value=>desc.version=value).then(()=>desc);} 
desc.os=appInfo.OS;let bundle=Services.strings.createBundle("chrome://branding/locale/brand.properties");if(bundle){desc.brandName=bundle.GetStringFromName("brandFullName");}
return desc;},{request:{},response:{value:RetVal("json")}}),getWallpaper:method(function(){let deferred=promise.defer();this._getSetting("wallpaper.image").then((blob)=>{let FileReader=CC("@mozilla.org/files/filereader;1");let reader=new FileReader();let conn=this.conn;reader.addEventListener("load",function(){let str=new LongStringActor(conn,reader.result);deferred.resolve(str);});reader.addEventListener("error",function(){deferred.reject(reader.error);});reader.readAsDataURL(blob);});return deferred.promise;},{request:{},response:{value:RetVal("longstring")}}),screenshotToDataURL:method(function(){let window=Services.wm.getMostRecentWindow(DebuggerServer.chromeWindowType);let canvas=window.document.createElementNS("http://www.w3.org/1999/xhtml","canvas");let width=window.innerWidth;let height=window.innerHeight;canvas.setAttribute('width',width);canvas.setAttribute('height',height);let context=canvas.getContext('2d');let flags=context.DRAWWINDOW_DRAW_CARET|context.DRAWWINDOW_DRAW_VIEW|context.DRAWWINDOW_USE_WIDGET_LAYERS;context.drawWindow(window,0,0,width,height,'rgb(255,255,255)',flags);let dataURL=canvas.toDataURL('image/png')
return new LongStringActor(this.conn,dataURL);},{request:{},response:{value:RetVal("longstring")}}),getRawPermissionsTable:method(function(){return{rawPermissionsTable:PermissionsTable,UNKNOWN_ACTION:Ci.nsIPermissionManager.UNKNOWN_ACTION,ALLOW_ACTION:Ci.nsIPermissionManager.ALLOW_ACTION,DENY_ACTION:Ci.nsIPermissionManager.DENY_ACTION,PROMPT_ACTION:Ci.nsIPermissionManager.PROMPT_ACTION};},{request:{},response:{value:RetVal("json")}})});let DeviceFront=protocol.FrontClass(DeviceActor,{initialize:function(client,form){protocol.Front.prototype.initialize.call(this,client);this.actorID=form.deviceActor;this.manage(this);},screenshotToBlob:function(){return this.screenshotToDataURL().then(longstr=>{return longstr.string().then(dataURL=>{let deferred=promise.defer();longstr.release().then(null,Cu.reportError);let req=Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);req.open("GET",dataURL,true);req.responseType="blob";req.onload=()=>{deferred.resolve(req.response);};req.onerror=()=>{deferred.reject(req.status);}
req.send();return deferred.promise;});});},});const _knownDeviceFronts=new WeakMap();exports.getDeviceFront=function(client,form){if(_knownDeviceFronts.has(client))
return _knownDeviceFronts.get(client);let front=new DeviceFront(client,form);_knownDeviceFronts.set(client,front);return front;}