diff --git a/README.md b/README.md index beabd272cb4aa1cc6429d8cff1599fe4d450768f..542c44d7227dd6fd6a4a0a7dbbc147c5624dde9e 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,30 @@ The fields `device` and `channel` are mandatory and `incremental` is an optional - The contents should be read as: Upgrades from major version 9 to major version 9 and to major version 10 are allowed. Upgrades from major version 10 to major version 10 and to major version 11 are allowed. - Current version is always available as an upgrade (if a more recent build is found), even if file is not available (for backwards compatibility too). +## How to set incremental rollout percentage in build config file + +- You can specify incremental rollout rules by adding values in `config.json` file. You can add the file only if you want percentage incremental rollout for a build. +- The format of file name will be : `.zip.config.json` + +```shell +$ cd builds/full/test/guacamoleb/ +$ tree +. +├── e.x.xx-xxyyzz-guacamoleb.zip # the full ROM zip file +└── e.x.xx-xxyyzz-guacamoleb.zip.config.json # the ROM build.config.json file +``` + +- E.g. : Suppose builds for "guacamoleb" devices are stored at "/mnt/rom/builds/full/test/guacamoleb". The file "/mnt/rom/builds/full/test/guacamoleb/e.x.xx-xxyyzz-guacamoleb.zip.config.json" should then have contents like: +```json + { + "rollout": { + "percentage": 20 + } + } +``` +- The `percentage` value must be between 0 to 100. Do not add `%` sign after the value. +- The `config.json` file is not mandatory. In case it does not exist, a build will consider a 100% rollout percentage. + ### ONLY for LineageOS 15.x and newer If you are willing to use this project on top of your LineageOS 15.x ( or newer ) ROM builds, you may have noticed that the file named `build.prop` have been removed inside your ZIP file, and has been instead integrated within your `system.new.dat` file, which is basically an ext4 image ( you can find out more here: https://source.android.com/devices/tech/ota/block ). diff --git a/src/CmOta.php b/src/CmOta.php index 8df8c54b2b3f8db3b2ec8bcd2f103aa663d037a9..d04591ff76dbaa7a71ab98bcaaf7a6893cb4d623 100644 --- a/src/CmOta.php +++ b/src/CmOta.php @@ -110,25 +110,26 @@ // LineageOS new API Flight::route('/api/v1/@deviceType/@romType(/@incrementalVersion)', function ( $deviceType, $romType, $incrementalVersion ){ - Flight::builds()->setPostData( - array( - 'params' => array( - 'device' => $deviceType, - 'channels' => array( - $romType, - ), - 'source_incremental' => $incrementalVersion, - ), - ) - ); - - $ret = array( - 'id' => null, - 'response' => Flight::builds()->get(), - 'error' => null - ); - - Flight::json($ret); + Flight::builds()->setPostData( + array( + 'params' => array( + 'device' => $deviceType, + 'channels' => array( + $romType, + ), + 'source_incremental' => $incrementalVersion, + ), + ) + ); + + $ret = array( + 'id' => null, + 'response' => Flight::builds()->get(), + 'error' => null + ); + + Flight::json($ret); + }); } diff --git a/src/Helpers/Build.php b/src/Helpers/Build.php index a2e8e70ea142c4d53cf6ad55c603c3c412d9fe4d..f3061a5796d3c76c5d759f39de998d6715844af5 100644 --- a/src/Helpers/Build.php +++ b/src/Helpers/Build.php @@ -38,6 +38,7 @@ private $incremental = ''; private $filePath = ''; private $buildProp = ''; + private $confProp = ''; private $uid = null; private $size = ''; private $logger = null; @@ -82,6 +83,7 @@ // - builds/CURRENT_ZIP_FILE.zip/system/build.prop // - builds/CURRENT_ZIP_FILE.zip.prop ( which must exist ) $this->buildProp = explode("\n", @file_get_contents($this->getPropFilePath())); + $this->confProp = $this->getConfProp(); // Try to fetch build.prop values. In some cases, we can provide a fallback, in other a null value will be given $this->timestamp = intval($this->getBuildPropValue('ro.build.date.utc') ?? filemtime($this->filePath)); $this->incremental = $this->getBuildPropValue('ro.build.version.incremental') ?? ''; @@ -510,4 +512,48 @@ { return is_callable($func) && false === stripos(ini_get('disable_functions'), $func); } - } + + /** + * Check if the current build is valid with multiple conditions + * @param type $params The params dictionary inside the current POST request + * @return boolean True if valid, False if not. + */ + public function includeInResults($params) + { + return $this->isValid($params) && $this->checkRollout(); + } + + /** + * Return the correct config file path (depending of version) + * @return string + */ + private function getConfigFilePath() + { + return file_exists($this->filePath . '.config.json') ? $this->filePath . '.config.json' : ''; + } + + /** + * Return the all values from config file path + * @return JSON if valid otherwise null + */ + private function getConfProp(){ + $configFilePath = $this->getConfigFilePath(); + return ($configFilePath) ? json_decode( file_get_contents($configFilePath) , true) : array(); + } + + /** + * Return if rollout successful or not for a build + * @return boolean + */ + public function checkRollout() + { + $rolloutpercentage = isset($this->confProp['rollout']['percentage']) ? $this->confProp['rollout']['percentage'] : 100; + if ($rolloutpercentage >= 0 && $rolloutpercentage < 100) { + $rand_number = rand(0, 100); + if ($rand_number > $rolloutpercentage) { + return false; + } + } + return true; + } + } \ No newline at end of file diff --git a/src/Helpers/Builds.php b/src/Helpers/Builds.php index fb2ce2bbeeff8f5a92207eb647904d7bbfdeb089..4fa87802f5a0961cf333ecf8189e63b96c9ce03a 100644 --- a/src/Helpers/Builds.php +++ b/src/Helpers/Builds.php @@ -203,8 +203,8 @@ } else { $build = new Build($file, $dir, $this->logger); } - - if ($build->isValid($this->postData['params'])) { + + if ($build->includeInResults($this->postData['params'])) { array_push($this->builds, $build); if (!empty($this->postData['params']) && strcmp($this->postData['params']['source_incremental'], $build->getIncremental()) == 0) { $this->currentBuild = $build;