diff --git a/core/shipped.json b/core/shipped.json
index 7d506c3401aefc9f14ff74e877cf01235ea13f05..b6f08a8b96ddeafad1f3e8eda1e365178fb8b971 100644
--- a/core/shipped.json
+++ b/core/shipped.json
@@ -31,5 +31,9 @@
     "user_ldap",
     "user_shibboleth",
     "windows_network_drive"
+  ],
+  "alwaysEnabled": [
+    "files",
+    "dav"
   ]
 }
diff --git a/lib/private/app.php b/lib/private/app.php
index 718adcd25c117aa187b45d0cc9b035c9a0294738..d7e62dfd852134df36092b059c8c997dab7d436f 100644
--- a/lib/private/app.php
+++ b/lib/private/app.php
@@ -61,7 +61,6 @@ class OC_App {
 	static private $appTypes = array();
 	static private $loadedApps = array();
 	static private $altLogin = array();
-	private static $shippedApps = null;
 	const officialApp = 200;
 
 	/**
@@ -223,18 +222,7 @@ class OC_App {
 	 * Check if an app that is installed is a shipped app or installed from the appstore.
 	 */
 	public static function isShipped($appId) {
-		if (is_null(self::$shippedApps)) {
-			$shippedJson = \OC::$SERVERROOT . '/core/shipped.json';
-			if (file_exists($shippedJson)) {
-				self::$shippedApps = json_decode(file_get_contents($shippedJson), true);
-				self::$shippedApps = self::$shippedApps['shippedApps'];
-			} else {
-				self::$shippedApps = ['files', 'encryption', 'files_external',
-					'files_sharing', 'files_trashbin', 'files_versions', 'provisioning_api',
-					'user_ldap', 'user_webdavauth'];
-			}
-		}
-		return in_array($appId, self::$shippedApps);
+		return \OC::$server->getAppManager()->isShipped($appId);
 	}
 
 	/**
@@ -285,9 +273,6 @@ class OC_App {
 	 * This function checks whether or not an app is enabled.
 	 */
 	public static function isEnabled($app) {
-		if ('files' == $app) {
-			return true;
-		}
 		return \OC::$server->getAppManager()->isEnabledForUser($app);
 	}
 
@@ -368,9 +353,6 @@ class OC_App {
 			$app = self::getInternalAppIdByOcs($app);
 		}
 
-		if($app === 'files') {
-			throw new \Exception("files can't be disabled.");
-		}
 		self::$enabledAppsCache = array(); // flush
 		// check if app is a shipped app or not. if not delete
 		\OC_Hook::emit('OC_App', 'pre_disable', array('app' => $app));
@@ -786,12 +768,9 @@ class OC_App {
 					if ($file[0] != '.' and is_dir($apps_dir['path'] . '/' . $file) and is_file($apps_dir['path'] . '/' . $file . '/appinfo/info.xml')) {
 
 						$apps[] = $file;
-
 					}
-
 				}
 			}
-
 		}
 
 		return $apps;
@@ -811,7 +790,8 @@ class OC_App {
 		//TODO which apps do we want to blacklist and how do we integrate
 		// blacklisting with the multi apps folder feature?
 
-		$blacklist = array('files'); //we don't want to show configuration for these
+		//we don't want to show configuration for these
+		$blacklist = \OC::$server->getAppManager()->getAlwaysEnabledApps();
 		$appList = array();
 		$l = \OC::$server->getL10N('core');
 
diff --git a/lib/private/app/appmanager.php b/lib/private/app/appmanager.php
index 8fb197e73ff61c70aac8cbe0cd1b1c7ccff72864..1f993d8538f52ecf61113fd57aea06137df6cf19 100644
--- a/lib/private/app/appmanager.php
+++ b/lib/private/app/appmanager.php
@@ -33,29 +33,28 @@ use OCP\IUser;
 use OCP\IUserSession;
 
 class AppManager implements IAppManager {
-	/**
-	 * @var \OCP\IUserSession
-	 */
+
+	/** @var \OCP\IUserSession */
 	private $userSession;
 
-	/**
-	 * @var \OCP\IAppConfig
-	 */
+	/** @var \OCP\IAppConfig */
 	private $appConfig;
 
-	/**
-	 * @var \OCP\IGroupManager
-	 */
+	/** @var \OCP\IGroupManager */
 	private $groupManager;
 
 	/** @var \OCP\ICacheFactory */
 	private $memCacheFactory;
 
-	/**
-	 * @var string[] $appId => $enabled
-	 */
+	/** @var string[] $appId => $enabled */
 	private $installedAppsCache;
 
+	/** @var string[] */
+	private $shippedApps;
+
+	/** @var string[] */
+	private $alwaysEnabled;
+
 	/**
 	 * @param \OCP\IUserSession $userSession
 	 * @param \OCP\IAppConfig $appConfig
@@ -117,6 +116,9 @@ class AppManager implements IAppManager {
 	 * @return bool
 	 */
 	public function isEnabledForUser($appId, $user = null) {
+		if ($this->isAlwaysEnabled($appId)) {
+			return true;
+		}
 		if (is_null($user)) {
 			$user = $this->userSession->getUser();
 		}
@@ -195,8 +197,8 @@ class AppManager implements IAppManager {
 	 * @throws \Exception if app can't be disabled
 	 */
 	public function disableApp($appId) {
-		if ($appId === 'files') {
-			throw new \Exception("files can't be disabled.");
+		if ($this->isAlwaysEnabled($appId)) {
+			throw new \Exception("$appId can't be disabled.");
 		}
 		unset($this->installedAppsCache[$appId]);
 		$this->appConfig->setValue($appId, 'enabled', 'no');
@@ -279,4 +281,36 @@ class AppManager implements IAppManager {
 		return $incompatibleApps;
 	}
 
+	/**
+	 * @inheritdoc
+	 */
+	public function isShipped($appId) {
+		$this->loadShippedJson();
+		return in_array($appId, $this->shippedApps);
+	}
+
+	private function isAlwaysEnabled($appId) {
+		$alwaysEnabled = $this->getAlwaysEnabledApps();
+		return in_array($appId, $alwaysEnabled);
+	}
+
+	private function loadShippedJson() {
+		if (is_null($this->shippedApps)) {
+			$shippedJson = \OC::$SERVERROOT . '/core/shipped.json';
+			if (!file_exists($shippedJson)) {
+				throw new \Exception("File not found: $shippedJson");
+			}
+			$content = json_decode(file_get_contents($shippedJson), true);
+			$this->shippedApps = $content['shippedApps'];
+			$this->alwaysEnabled = $content['alwaysEnabled'];
+		}
+	}
+
+	/**
+	 * @inheritdoc
+	 */
+	public function getAlwaysEnabledApps() {
+		$this->loadShippedJson();
+		return $this->alwaysEnabled;
+	}
 }
diff --git a/lib/public/app/iappmanager.php b/lib/public/app/iappmanager.php
index d8f261660c11b4d4243bdb391f554bd05bed855e..09b6bd3f2b9d65dd11192c03127ed0459f99d494 100644
--- a/lib/public/app/iappmanager.php
+++ b/lib/public/app/iappmanager.php
@@ -98,4 +98,17 @@ interface IAppManager {
 	 * @since 8.1.0
 	 */
 	public function clearAppsCache();
+
+	/**
+	 * @param string $appId
+	 * @return boolean
+	 * @since 9.0.0
+	 */
+	public function isShipped($appId);
+
+	/**
+	 * @return string[]
+	 * @since 9.0.0
+	 */
+	public function getAlwaysEnabledApps();
 }