User Tools

Site Tools


script_autosetupappfreeze

====== Differences ====== This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
script_autosetupappfreeze [2015/11/15 10:51]
cdfa
script_autosetupappfreeze [2017/07/21 08:57] (current)
cdfa 1.8.4
Line 1: Line 1:
 ====== About the script ====== ====== About the script ======
-  * Purpose : this script automatically sets up app freezing on long tap+  * Purpose : this script automatically sets up app freezing on any action you want.
   * Author : cdfa   * Author : cdfa
-  * Link: https://​plus.google.com/​+JaroslavGrochal/​posts/​BDKDMrTMfxt +  * Initial request: https://​plus.google.com/​+JaroslavGrochal/​posts/​BDKDMrTMfxt 
-  * Version1.4b3 +  * GitHubhttps://​github.com/​cdfa/​AutoSetupLongTapFreeze 
-  * Changelog: +  * Version1.8.4
-    - Added checking for null package name. +
-    - Fixed the "​cannot get property length of null" bug(Hopefully for reals this time)+
  
 ====== How to use the script ====== ====== How to use the script ======
  
-This script ​uses 3C toolbox: https://​play.google.com/​store/​apps/​details?​id=ccc71.at.free +Run script ​in any container to run setup freezing and unfreezing actions for all itemsThe action is configurable ​at the top of the script.
-If you know any other app that has a shortcut for freezing ​of apps i can make that work too if you want :).+
  
-After you've installed 3C toolbox ​,run the script from container and all items in that container ​which don't already have custom long tap eventhandler will now freeze on long tapRunning ​the script ​in that container again will revert ​the long tap eventHandler for the items in that container. Running ​the script ​from the lightning ​menu will do that for all containers.+You can setup autosync in the setup, or you can sync manually from the container menu => items => syncor you can run the script from any item in the container ​with "​sync"​ (without the ""​) as data, or from anywhere if you put the container id directly behind it, so like "​sync1"​. 
 + 
 +You can sync items separately from the item menu and choosing Sync, or sync all items in container ​also from the item menu. This can also be done when the items are in folder by longpressing the folder item. 
 + 
 +Run the script ​from the container again to uninstall (this won't clear events you manually set to sync the container). 
 + 
 +Please report all issues at the GitHub page. 
 + 
 +====== Changelog ====== 
 +1.8 
 +  * Updated to LL 14b7 
 +  * sync action is now in the items menu in the container ​menu as well 
 +  * uninstall everywhere function is lost for now, because i cannot distinguish between ​the menu from the menu of a container anymore. Please suggest new triggers if you want this functionality back. 
 + 
 +1.8.1 
 +  * workaround ​for double comfirm crash in LL14 
 + 
 +1.8.1.1 
 +  * Added item description to the toast message that is displayed if the item doesn'​t launch an app 
 + 
 +1.8.1.2 
 +  * Made the changes in 1.8.1.1 actually work 
 + 
 +1.8.1.3 
 +  * Toasts message that says the item doesn'​t launch an app now only shows when you're actually trying to freeze that item and not anymore on each sync. 
 + 
 +1.8.2 
 +  * The double confirm crash got fixed, so the workaround was removed 
 +  * Only commands that need root are executed as root 
 + 
 +1.8.3 
 +  * Added freezeing/​unfreezing ​all item from menu 
 +  * Added long press folder to freeze/​unfreeze all items in it 
 + 
 +1.8.4 
 +  * Ask to unfreeze and run an item if it is frozen instead of saying that the app is not installed
  
 ====== Script code ====== ====== Script code ======
 <sxh javascript>​ <sxh javascript>​
 var blackList = ["​net.pierrox.lightning_launcher_extreme"​] var blackList = ["​net.pierrox.lightning_launcher_extreme"​]
-var whiteList = [];+  , whiteList = [] 
 +  // for Sources see: http://​www.lightninglauncher.com/​scripting/​reference/​api/​reference/​net/​pierrox/​lightning_launcher/​script/​api/​Event.html 
 +  // for Events see http://​www.lightninglauncher.com/​scripting/​reference/​api/​reference/​net/​pierrox/​lightning_launcher/​script/​api/​PropertySet.html 
 +  , freezeSource = "​I_LONG_CLICK"​ 
 +  , freezeEvent = "​i.longTap";​ 
 + 
 +bindClass("​android.widget.Toast"​);​ 
 +bindClass("​android.content.pm.PackageManager"​);​ 
 +bindClass("​java.lang.Thread"​);​ 
 +bindClass("​android.os.Handler"​);​ 
 +bindClass("​android.os.Looper"​);​ 
 +bindClass('​java.io.BufferedReader'​);​ 
 +bindClass('​java.io.InputStreamReader'​);​ 
 +bindClass('​java.io.DataOutputStream'​);​ 
 +bindClass('​java.lang.StringBuffer'​);​ 
 +bindClass('​java.lang.Runtime'​);
  
-LL.bindClass("​android.app.AlertDialog"​); +var script = getCurrentScript() 
-LL.bindClass("​android.content.DialogInterface"​); +  , screen = getActiveScreen() 
-LL.bindClass("​android.widget.Toast"​); +  , context = screen.getContext() 
-LL.bindClass("​android.content.pm.PackageManager"​);+  , threads = [] 
 +  , GUIHandler = new Handler() 
 +  , frozenApps;
  
-function ​loanEventHandler(ob, name, action, data){ +function ​setEventHandlerRestorably(ob, name, action, data){ 
-  var prop = ob.getProperties(); +  var prop = ob.getProperties() 
-  ​var ​ed = prop.edit(); +    , ​ed = prop.edit() 
-  ​var ​evHa = prop.getEventHandler(name);​+    , ​evHa = prop.getEventHandler(name);​
   evHa = [evHa.getAction(),​ evHa.getData()];​   evHa = [evHa.getAction(),​ evHa.getData()];​
-  ob.setTag("​old "​+name+"​ evHa", JSON.stringify(evHa));​ 
   ed.setEventHandler(name,​ action, data);   ed.setEventHandler(name,​ action, data);
   ed.commit();​   ed.commit();​
 +  ob.setTag("​old " + name + " evHa", JSON.stringify(evHa));​
 } }
  
-function ​returnEventHandler(ob, name){ +function ​restoreEventHandler(ob, name){ 
-  ​var ed = ob.getProperties().edit(); +  ​if(ob){ 
-  var evHa = JSON.parse(ob.getTag("​old "​+name+"​ evHa"​));​ +    var evHa = JSON.parse(ob.getTag("​old " + name + " evHa"​));​ 
-  ed.setEventHandler(name,​ evHa[0], evHa[1]); +    ​if(evHa){ 
-  ed.commit();​ +      var ed = ob.getProperties().edit();​ 
-  ​script.setTag("​name",​ null); +      ​ed.setEventHandler(name,​ evHa[0], evHa[1]); 
-} +      ed.commit();​ 
- +      ob.setTag("​name",​ null); 
-function customConfirmDialog(title,​onPositiveFunction)+    }else
- var builder=new AlertDialog.Builder(context);​ +      ​throw ​new Error("No eventhandler backup for " + name + " on " + ob + "​found!") 
- builder.setCancelable(true);​ +    ​} 
- builder.setTitle(title);​ +  ​}else{ 
- builder.setNegativeButton("Cancel",new DialogInterface.OnClickListener(){onClick:​function(dialog,​id){dialog.dismiss();​}}); +    throw new Error("Cannot restore " + name + "of null!") 
- builder.setPositiveButton("Confirm",new DialogInterface.OnClickListener(){onClick:​function(dialog,​id){dialog.dismiss();​setTimeout(onPositiveFunction,​0);​}}); +  ​}
- builder.show();​+
 } }
  
 function uninstall(c){ function uninstall(c){
-  if(c!=null){ +  if(c && c.getTag("​longTapFreeze"​)){ 
-    c.setTag("​longTapFreeze",​false);​ +    c.setTag("​longTapFreeze",​ false); 
-    ​returnEventHandler(c,"i.longTap"); +    ​restoreEventHandler(c,​ freezeEvent);​ 
-    ​var frozenItIds = JSON.parse(c.getTag("​frozenItIds")); +    restoreEventHandler(c,​ '​i.tap'​);​ 
-    ​if(frozenItIds!=null){ +    restoreEventHandler(c, "i.menu"); 
-      ​for(var i=0;​i<​frozenItIds.length;​i++){ +    ​restoreEventHandler(c,​ "​menu"​);​ 
-        ​var it = c.getItemById(frozenItIds[i]); +    if(c.getTag("​autosync"​) ​=== "​true"​) restoreEventHandler(c,​ "​resumed"​); 
-        if(it!=null){ +    ​c.getAllItems().forEach(function(it){ 
-          ​it.getProperties().edit().setInteger("s.iconColorFilter",0xffffffff).commit(); +      ​if(isFrozen(it)
-          ​it.setTag("​frozen",​false); +        ​unfreezeEffect(it); 
-        }+    }); 
 +    var cs screen.getAllContainersById(c.getId()); 
 +    ​cs.forEach(function(c){ 
 +      var opener; 
 +      if((opener = c.getOpener()) && opener.getType() === "Folder")
 +        if(isFrozen(opener)
 +          ​unfreezeEffect(opener);
       }       }
-      c.setTag("​frozenItIds",​null); +    });
-    }+
   }   }
 } }
  
-var e = LL.getEvent();​ +/** 
-var it = e.getItem(); + * Checks if an object is an array
-var script = LL.getCurrentScript();​ + * @param object 
-var context = LL.getContext();​ + * @returns {boolean} 
-if(it==null){ + */ 
-  ​var c = e.getContainer();​ +function isArray(object){ 
-  var cIds = JSON.parse(script.getTag("​cIds"​)); +  ​return Object.prototype.toString.call(object) === '[object Array]'
-  if(cIds==null)cIds=[]; +} 
-  ​if(c!=null){ + 
-    cId = c.getId(); +/** 
-    ​if(cIds==null) cIds=[]; + * If this function is executed in a thread that is the main GUI thread, execute func, or else execute func in the main GUI thread. (Android doesn'​t like it when you change the GUI outside of the main GUI thread) 
-    if(c.getTag("​longTapFreeze"​)=="​true"​){ + * @param func {function} 
-      ​customConfirmDialog("​Are you sure you want to uninstall?", ​function(){ + */ 
-        ​uninstall(c); +function ​handleGUIEdit(func){ 
-        cIds.splice(cIds.indexOf(c.getId()),1); +  if(Looper.getMainLooper().getThread() === Thread.currentThread()){ 
-        ​script.setTag("​cIds",​ JSON.stringify(cIds)); +    func(); 
-        Toast.makeText(context,​ "​Uninstalled!",​ Toast.LENGTH_SHORT).show(); +  ​}else{ 
-      }); +    GUIHandler.post(func); 
-    }else+  
-      ​customConfirmDialog("​Are you sure you want to install?", ​function(){ +} 
-        ​cIds.push(c.getId()); + 
-        ​c.setTag("​longTapFreeze",​true); +/** 
-        ​loanEventHandler(c"i.longTap",​ EventHandler.RUN_SCRIPT, script.getId()); + * Starts a new background thread with func. 
-        ​script.setTag("​cIds",​ JSON.stringify(cIds)); + * @param func {function} - The function the thread executes. 
-        ​Toast.makeText(context, "​Installed!",​ Toast.LENGTH_SHORT).show();+ */ 
 +function ​startNewBackgroundThread(func){ 
 +  var thread = new Thread(function(){ 
 +    func(); 
 +    // if a looper was initialized in funcmake sure the thread can die by stopping the thread when the Looper idles. 
 +    if(threads[Thread.currentThread().getId()].prepared === true){ 
 +      ​Looper.myLooper().getQueue().addIdleHandler(function(){ 
 +        ​Looper.myLooper().quitSafely();
       });       });
 +      Looper.loop();​
     }     }
 +  });
 +  thread.setUncaughtExceptionHandler(function(th,​ ex){
 +    handleGUIEdit(function(){
 +      alert(ex.getMessage());​
 +    })
 +  });
 +  threads[thread.getId()] = {};
 +  thread.start();​
 +}
 +
 +//​noinspection JSValidateJSDoc
 +/**
 + * Gets a handler for the current thread and initializes a looper if necessary.
 + * @returns {Handler}
 + */
 +function getHandler(){
 +  if(Looper.getMainLooper().getThread() === Thread.currentThread()){
 +    return GUIHandler;
   }else{   }else{
-    ​customConfirmDialog("Are you sure you want to uninstall from every container?",​ function(){ +    ​var threadId = Thread.currentThread().getId(); 
-      for(var ​i=0;i<cIds.length;i++){ +    if(threads[threadId].prepared !== true){ 
-        ​uninstall(LL.getContainerById(cIds[i]));+      ​Looper.prepare();​ 
 +      threads[threadId].prepared = true; 
 +    } 
 +    return new Handler();​ 
 +  } 
 +
 + 
 +/** 
 + * This callback will be called when the executing of the command(s) is finished 
 + * 
 + * @callback finishedCallback 
 + * @param {string[]} An array of the lines the command(s) returned 
 + */ 
 +/** 
 + * This callback will be called when a command is executed. 
 + * 
 + * @callback executedCallback 
 + */ 
 +/** 
 + * Runs a command in the terminal 
 + * @param cmds {string|string[]} - The command or array of commmands to be executed. 
 + * @param [asRoot=false] {boolean} - If the command(s) should be executed as root or not. 
 + * @param [newThread=true] {boolean} - If the executing of commands should happen in a new thread or not. (useful ​for root commands) 
 + * @param [callback] {finishedCallback} - The callback that handles the output. 
 + * @param [onExecuted] {executedCallback} - A callback that will be called when a command is executed. useful for multiple commands that take some time) 
 + * @returns {string[]||string[][]} - (only if asRoot == false && newThread == false) Returns an array of the lines written in the terminal or an array of arrays if multiple commands were executed. 
 + */ 
 +function runCmd(cmds,​ asRoot, newThread, callback, onExecuted){ 
 +  ​var handler ​getHandler() 
 +    , output, process, reader, writer; 
 + 
 +  // set optional arguments 
 +  if(newThread !== false) 
 +    newThread = true; 
 + 
 +  /** 
 +   * Helper function for executing the command(s)Gets its parameters from the parent function. 
 +   * @returns {string[]||string[][]} - (only if asRoot == false && newThread == false) Returns an array of the lines written in the terminal or an array of arrays if multiple commands were executed. 
 +   */ 
 +  function execCmd(){ 
 +    /** 
 +     * Checks if the command is a string and if not alerts the user. 
 +     * @param cmd {string} 
 +     * @returns {boolean} 
 +     */ 
 +    function checkCmd(cmd){ 
 +      if(typeof(cmd) === "​string"​){ 
 +        return true; 
 +      }else 
 +        handleGUIEdit(function(){ 
 +          alert(cmd ​" is not a string!"​);​ 
 +        }); 
 +      return false; 
 +    } 
 + 
 +    //​noinspection JSValidateJSDoc 
 +    /** 
 +     * Actually executes command. 
 +     * @param cmd {string} 
 +     * @param writer {DataOutputStream} - The writer to write the command to. 
 +     * @returns {boolean} If the command was actually written or not. 
 +     */ 
 +    function exec(cmd, writer){ 
 +      if(checkCmd(cmd)){ 
 +        ​writer.writeBytes(cmd + "​\n"​);​ 
 +        writer.flush()
 +        return true;
       }       }
-      ​script.setTag("​cIds"​,null); +      ​return false; 
-      ​Toast.makeText(context, "Uninstalled everywhere!", ​Toast.LENGTH_SHORT).show(); +    } 
-    })+ 
 +    //​noinspection JSValidateJSDoc 
 +    /** 
 +     * Read the output from the reader. 
 +     * @param reader {BufferedReader} 
 +     * @returns {Array} An array of lines that were outputted by the 
 +     */ 
 +    function readOutput(reader){ 
 +      var tmpoutput = []; 
 +      while((tmp = reader.readLine()) !== null
 +        output.push(tmp); 
 + 
 +      ​return output.length === 1 ? output[0] : output; 
 +    } 
 + 
 +    /** 
 +     * Executes the callback and if the callback is not a function alerts the user. 
 +     * @param callback 
 +     * @param output {Array} - The argument that is passed to the callback 
 +     */ 
 +    function handleCallback(callbackoutput){ 
 +      if(typeof callback === "function"​){ 
 +        handler.post(function(){ 
 +          callback(output);​ 
 +        }); 
 +      }else if(callback){ 
 +        handleGUIEdit(function(){ 
 +          alert(callback + " is not a function!"); 
 +        }); 
 +      } 
 +    } 
 + 
 +    try{ 
 +      if(asRoot){ 
 +        process = Runtime.getRuntime().exec("​su"​);​ 
 +        reader = new BufferedReader(new InputStreamReader(process.getInputStream()));​ 
 +        writer = new DataOutputStream(process.getOutputStream());​ 
 + 
 +        if(isArray(cmds)){ 
 +          output = []; 
 +          cmds.forEach(function(cmd){ 
 +            if(exec(cmdwriter)){ 
 +              handleCallback(onExecuted);​ 
 +            } 
 +          }); 
 + 
 +          exec("​exit",​ writer); 
 +          writer.close()
 + 
 +          output = readOutput(reader);​ 
 +          handleCallback(callback,​ output); 
 +        }else{ 
 +          var succes = exec(cmds, writer); 
 + 
 +          exec("​exit",​ writer); 
 +          writer.close(); 
 + 
 +          if(succes){ 
 +            output = readOutput(reader);​ 
 +            handleCallback(onExecuted);​ 
 +            handleCallback(callback,​ output); 
 +          } 
 +        } 
 + 
 +        reader.close();​ 
 +        process.waitFor();​ 
 +      }else{ 
 +        if(isArray(cmds)){ 
 +          var outputs = []; 
 +          cmds.forEach(function(cmd){ 
 +            if(checkCmd(cmd)){ 
 +              process = Runtime.getRuntime().exec(cmd);​ 
 +              reader = new BufferedReader(new InputStreamReader(process.getInputStream()));​ 
 +              output = readOutput(reader);​ 
 +              reader.close();​ 
 +              outputs.push(output);​ 
 +              handleCallback(onExecuted);​ 
 +              handleCallback(callback,​ output); 
 +            } 
 +          }); 
 +          process.waitFor();​ 
 +          return outputs; 
 +        }else{ 
 +          process = Runtime.getRuntime().exec(cmds);​ 
 +          reader = new BufferedReader(new InputStreamReader(process.getInputStream()));​ 
 +          output = readOutput(reader);​ 
 +          reader.close();​ 
 +          process.waitFor();​ 
 +          handleCallback(onExecuted);​ 
 +          handleCallback(callback,​ output); 
 +          return output; 
 +        } 
 +      } 
 +    }catch(err)
 +      handleGUIEdit(function(){ 
 +        alert("​At line " + err.lineNumber + ": " + err); 
 +      }); 
 +    }
   }   }
-}else{ + 
-  ​var c = it.getParent(); +  ​if(asRoot && isArray(callback)
-  var frozenItIds = JSON.parse(c.getTag("frozenItIds"​)); +    throw new Error("​Multiple callbacks are not possible in su mode. Use onExecuteds instead."); 
-  if(frozenItIds==null)frozenItIds=[]+ 
-  var onBlackList = false+  if(newThread){ 
-  ​var iTapEvHa = it.getProperties().getEventHandler("​i.tap"​);+    startNewBackgroundThread(function(){ 
 +      execCmd(); 
 +    })
 +  ​}else{ 
 +    return execCmd()
 +  } 
 +
 + 
 +function getPackageName(it){
   try{   try{
-    ​var pkgName = it.getIntent().getComponent().getPackageName();​+    ​return ​it.getIntent().getComponent().getPackageName();​
   }catch(e){   }catch(e){
-    ​Toast.makeText(context,​ "This item doesn'​t launch an app!", Toast.LENGTH_SHORT).show();+    ​return null;
   }   }
-  if(pkgName!=null){ +
-    for(var i=0;i<blackList.length;i++){ + 
-      ​if(pkgName==blackList[i]){ +function isFreezable(pkgName){ 
-        onBlackList=true+  if(!pkgName) 
-        ​Toast.makeText(context,​ "on blacklist!",​ Toast.LENGTH_SHORT).show(); +    return false; 
-        ​break;​ + 
-      } +  ​var onWhiteList,​ 
-    }+    onBlackList ​= blackList.some(function(pkg){ 
 +      ​return pkg === pkgName
 +    }); 
 + 
 +  ​if(whiteList.length === 0){
     onWhiteList = true;     onWhiteList = true;
-    ​if(whiteList.length!=0){ +  }else{ 
-      ​onWhiteList ​= false +    onWhiteList = whiteList.some(function(pkg){ 
-      for(var i=0;i<whiteList.length;​i++){ +      return pkg === pkgName; 
-        if(pkgName==whiteList[i]){ +    }); 
-          ​onWhiteList=true; +  } 
-          ​break+ 
-        }+  return !onBlackList && onWhiteList;​ 
 +
 + 
 +function freezeChecks(it,​ allGood, giveFeedback){ 
 +  var pkgName = getPackageName(it) 
 +    , freezeAble = isFreezable(pkgName);​ 
 +  ​if(pkgName && freezeAble){ 
 +    allGood(pkgName);​ 
 +  }else if(giveFeedback !== false){ 
 +    if(!pkgName) 
 +      Toast.makeText(context,​ it + " doesn'​t launch an app!", Toast.LENGTH_SHORT).show();​ 
 +    else if(!freezeAble) 
 +      Toast.makeText(context,​ "​Cannot freeze/​unfreeze! (Probably because of black- or whitelist",​ Toast.LENGTH_SHORT).show();​ 
 +  } 
 +
 + 
 +function freeze(it, callback){ 
 +  if(it.getType() === "​Folder"​){ 
 +    freezeContainer(it.getContainer());​ 
 +  }else{ 
 +    freezeChecks(it,​ function(pkgName){ 
 +      runCmd("​pm disable " + pkgName, true, true, null, function(){ 
 +        freezeEffect(it);​ 
 +        if(typeof callback === '​function'​) 
 +          callback();​ 
 +      }); 
 +    }); 
 +  } 
 +
 + 
 +function unfreeze(it,​ callback){ 
 +  if(it.getType() === "​Folder"​){ 
 +    unfreezeContainer(it.getContainer());​ 
 +  }else{ 
 +    freezeChecks(it,​ function(pkgName){ 
 +      runCmd("​pm enable " + pkgName, true, true, null, function(){ 
 +        unfreezeEffect(it);​ 
 +        if(typeof callback === '​function'​) 
 +          callback();​ 
 +      }); 
 +    }); 
 +  } 
 +
 + 
 +function freezeEffect(it){ 
 +  it.getProperties().edit().setInteger("​s.iconColorFilter",​ 0x00ffffff).commit();​ 
 +  it.setTag("​frozen",​ true); 
 +
 + 
 +function unfreezeEffect(it){ 
 +  it.getProperties().edit().setInteger("​s.iconColorFilter",​ 0xffffffff).commit();​ 
 +  it.setTag("​frozen",​ false); 
 +
 + 
 +function batchFreezeAction(items,​ action, callback){ 
 +  var frozenStateChecker,​ cmd, effect; 
 +  if(action === "​freeze"​){ 
 +    frozenStateChecker = function(it){ return !isFrozen(it);​ }; 
 +    cmd = "pm disable "; 
 +    effect = function(it){ freezeEffect(it);​ } 
 +  }else if(action === "​unfreeze"​){ 
 +    frozenStateChecker = function(it){ return isFrozen(it);​ }; 
 +    cmd = "pm enable "; 
 +    effect = function(it){ unfreezeEffect(it);​ } 
 +  } 
 + 
 +  var freezableItems = [] 
 +    , cmds = []; 
 + 
 +  items.forEach(function(it){ 
 +    if(frozenStateChecker(it)){ 
 +      freezeChecks(it,​ function(pkgName){ 
 +        freezableItems.push(it);​ 
 +        cmds.push(cmd + pkgName); 
 +      }, false); 
 +    } 
 +  }); 
 + 
 +  if(cmds.length !== 0){ 
 +    var counter = 0; 
 +    runCmd(cmds,​ true, true, function(){ 
 +      ​callback();​ 
 +    }, function(){ 
 +      effect(freezableItems[counter]);​ 
 +      counter++;​ 
 +    }); 
 +  } 
 +
 + 
 +function containerFreezeAction(c,​ effect){ 
 +  var cs screen.getAllContainersById(c.getId());​ 
 +  cs.forEach(function(c){ 
 +    var opener; 
 +    if((opener = c.getOpener()) && opener.getType() === "​Folder"​) 
 +      effect(opener);​ 
 +  }); 
 +
 + 
 +function freezeContainer(c){ 
 +  batchFreezeAction(c.getAllItems(),​ "​freeze",​ function(){ 
 +    containerFreezeAction(c,​ freezeEffect);​ 
 +  }); 
 +
 + 
 +function unfreezeContainer(c){ 
 +  batchFreezeAction(c.getAllItems(),​ "​unfreeze",​ function(){ 
 +    containerFreezeAction(c,​ unfreezeEffect);​ 
 +  }); 
 +
 + 
 +function isFrozen(it){ 
 +  return it.getTag("​frozen"​) === '​true';​ 
 +
 + 
 +function getFrozenApps(){ 
 +  if(typeof frozenApps === '​undefined'​){ 
 +    frozenApps = []; 
 +    var pkgs = runCmd("​pm list packages -d", ​false, false); 
 +    pkgs.forEach(function(pkg,​ i){ 
 +      ​frozenApps[i] = pkg.split(":"​)[1];​ 
 +    }); 
 +  } 
 +  return frozenApps;​ 
 +
 + 
 +function syncContainer(c){ 
 +  startNewBackgroundThread(function(){ 
 +    var items = c.getItems();​ 
 +    ​for(var i = 0; i < items.length; i++){ 
 +      ​syncItem(items.getAt(i));​ 
 +    } 
 +  }); 
 +
 + 
 +function syncItem(it){ 
 +  var frozenApps = getFrozenApps();​ 
 +  ​if(it.getType() ​=== "​Shortcut"​){ 
 +    var pkgName = getPackageName(it);​ 
 +    if(pkgName && isFreezable(pkgName)){ 
 +      var isFrozen = it.getTag("​frozen"​) =='true'; 
 +      var matched = frozenApps.some(function(pkg){ 
 +        return pkg === pkgName; 
 +      }); 
 +      if(!isFrozen && matched){ 
 +        handleGUIEdit(function(){ 
 +          ​freezeEffect(it)
 +        }); 
 +      }else if(isFrozen && !matched){ 
 +        handleGUIEdit(function(){ 
 +          unfreezeEffect(it);​ 
 +        });
       }       }
     }     }
-    ​var pm context.getPackageManager(); +  } 
-    ​try { +
-      pm.getPackageInfo"​ccc71.at.free" ​PackageManager.GET_ACTIVITIES); + 
-      var toolboxInstalled = true; +if(typeof getEvent !== "​undefined"​){ 
-      var sentToPkg ​= "ccc71.at.free"; +  ​var 
-    } catch (e) +    , e getEvent() 
-      try +    ​, it = e.getItem(
-        ​pm.getPackageInfo("​ccc71.at",​ PackageManager.GET_ACTIVITIES); +    ​data = e.getData(); 
-        var toolboxInstalled = true; +  ​if(data){ 
-        ​var sentToPkg = "ccc71.at"+    ​if(data === "sync"){ 
-      } catch (e+      if(c = e.getContainer()){ 
-        var toolboxInstalled = false;+        ​syncContainer(c); 
 +      ​}else{ 
 +        ​throw new Error("Could not find a way to determine the container to sync. Run the script from an item in the container or from the container itself or add the container id directly afrer '​sync'​.")
       }       }
 +    }else if(data.substring(0,​ 4) === "​sync"​){
 +      var cId = data.substring(4,​ data.length);​
 +      c = screen.getContainerById(cId);​
 +      if(!c) throw new Error("​Could not find container with id:" + cId);
 +      syncContainer(c);​
     }     }
-    ​if(!onBlackList && onWhiteList && toolboxInstalled){ +  }else{ 
-      ​LL.runAction(EventHandler.LAUNCH_SHORTCUT,​ "#​Intent;action=ccc71.at.freeze;​launchFlags=0x34000000;​component="​+sentToPkg+"/​ccc71.at.activities.tweaks.at_tweaker_activity;​S.ccc71.at.packagename="​+pkgName+";​end"​); +    ​if(!it){ 
-      if(it.getTag("​frozen"​)=="​true"​){ +      ​c = e.getContainer(); 
-        ​it.getProperties().edit().setInteger("s.iconColorFilter",0xffffffff).commit(); +      cId c.getId(); 
-        it.setTag("frozen",false)+      if(c.getTag("​longTapFreeze"​) ​=== "​true"​){ 
-        frozenItIds.splice(frozenItIds.indexOf(it.getId()),1);+        ​if(confirm("Are you sure you want to uninstall?")){ 
 +          uninstall(c); 
 +          Toast.makeText(context, ​"Uninstalled!", ​Toast.LENGTH_SHORT).show(); 
 +        }
       }else{       }else{
-        ​it.getProperties().edit().setInteger("s.iconColorFilter",0x00ffffff).commit(); +        ​if(confirm("​Are you sure you want to install?"​)){ 
-        it.setTag("​frozen",​true);​ +          c.setTag("​longTapFreeze",​ true)
-        ​frozenItIds.push(it.getId());+          setEventHandlerRestorably(c,​ freezeEvent,​ EventHandler.RUN_SCRIPT, script.getId()); 
 +          setEventHandlerRestorably(c,​ 'i.tap', EventHandler.RUN_SCRIPT,​ script.getId()); 
 +          setEventHandlerRestorably(c, ​"i.menu", ​EventHandler.RUN_SCRIPT,​ script.getId()); 
 +          setEventHandlerRestorably(c,​ "​menu",​ EventHandler.RUN_SCRIPT, script.getId()); 
 +          ​if(confirm("​Do you want to enable autosync?"​)){ 
 +            setEventHandlerRestorably(c,​ "​resumed",​ EventHandler.RUN_SCRIPT,​ script.getId() + "/​sync"​);​ 
 +            syncContainer(c);​ 
 +            c.setTag("​autosync", true); 
 +          } 
 +          Toast.makeText(context,​ "​Installed!",​ Toast.LENGTH_SHORT).show(); 
 +        ​
 +      } 
 +    }else{ 
 +      var src = e.getSource();​ 
 +      if(src === freezeSource){ 
 +        if(isFrozen(it)){ 
 +          unfreeze(it);​ 
 +        }else{ 
 +          freeze(it);​ 
 +        } 
 +      }else if(src === '​I_CLICK'​){ 
 +        if( isFrozen(it) && confirm("​Unfreeze and run?"​)) 
 +          unfreeze(it,​ function(){ 
 +            ​it.launch()
 +          }); 
 +        else 
 +          it.launch();
       }       }
-      c.setTag("​frozenItIds",​ JSON.stringify(frozenItIds));​ 
     }     }
 +  }
 +}else if(menu){
 +  var mode = menu.getMode();​
 +  if(mode === Menu.MODE_ITEM_SUBMENU_ACTION || mode === Menu.MODE_ITEM_NO_EM){
 +    menu.addMainItem("​Sync frozen-state",​ function(){
 +      syncItem(item);​
 +      menu.close();​
 +    });
 +  }else if(mode === Menu.MODE_CONTAINER_SUBMENU_ITEMS){
 +    menu.addMainItem("​Sync frozen-state",​ function(){
 +      syncContainer(container);​
 +      menu.close();​
 +    });
 +    menu.addMainItem("​Freeze all items",​ function(){
 +      freezeContainer(container);​
 +      menu.close();​
 +    });
 +    menu.addMainItem("​Unfreeze all items",​ function(){
 +      unfreezeContainer(container);​
 +      menu.close();​
 +    });
   }   }
 } }
-delete(AlertDialog);​ 
 </​sxh>​ </​sxh>​
script_autosetupappfreeze.1447584672.txt.gz · Last modified: 2015/11/15 10:51 by cdfa