Clean up demo dir when leaving demo mode

Delete contents of demo dir when device is provisioned and demo_mode is
disabled

Bug: 28855287
Change-Id: I6e1826ec23a2ff92402fe079a9e7b565a2fe04d7
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index f6e8940..6af0678 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -324,6 +324,33 @@
     }
 
     /**
+     * Return preloads directory.
+     * <p>This directory may contain pre-loaded content such as
+     * {@link #getDataPreloadsDemoDirectory() demo videos} and
+     * {@link #getDataPreloadsAppsDirectory() APK files} .
+     * {@hide}
+     */
+    public static File getDataPreloadsDirectory() {
+        return new File(getDataDirectory(), "preloads");
+    }
+
+    /**
+     * @see #getDataPreloadsDirectory()
+     * {@hide}
+     */
+    public static File getDataPreloadsDemoDirectory() {
+        return new File(getDataPreloadsDirectory(), "demo");
+    }
+
+    /**
+     * @see #getDataPreloadsDirectory()
+     * {@hide}
+     */
+    public static File getDataPreloadsAppsDirectory() {
+        return new File(getDataPreloadsDirectory(), "apps");
+    }
+
+    /**
      * Return the primary shared/external storage directory. This directory may
      * not currently be accessible if it has been mounted by the user on their
      * computer, has been removed from the device, or some other problem has
diff --git a/services/core/java/com/android/server/am/RetailDemoModeService.java b/services/core/java/com/android/server/am/RetailDemoModeService.java
index bf2ba93..5929794 100644
--- a/services/core/java/com/android/server/am/RetailDemoModeService.java
+++ b/services/core/java/com/android/server/am/RetailDemoModeService.java
@@ -25,6 +25,8 @@
 import android.content.pm.UserInfo;
 import android.database.ContentObserver;
 import android.net.Uri;
+import android.os.Environment;
+import android.os.FileUtils;
 import android.os.Handler;
 import android.os.PowerManager;
 import android.os.ServiceManager;
@@ -33,10 +35,13 @@
 import android.provider.Settings;
 import android.util.Slog;
 
+import com.android.internal.os.BackgroundThread;
 import com.android.server.ServiceThread;
 import com.android.server.SystemService;
 import com.android.server.pm.UserManagerService;
 
+import java.io.File;
+
 public class RetailDemoModeService extends SystemService {
     private static final boolean DEBUG = false;
 
@@ -111,19 +116,47 @@
 
     private void registerSettingsChangeObserver() {
         final Uri deviceDemoModeUri = Settings.Global.getUriFor(Settings.Global.DEVICE_DEMO_MODE);
+        final Uri deviceProvisionedUri = Settings.Global.getUriFor(
+                Settings.Global.DEVICE_PROVISIONED);
         final ContentResolver cr = getContext().getContentResolver();
         final ContentObserver deviceDemoModeSettingObserver = new ContentObserver(mHandler) {
             @Override
             public void onChange(boolean selfChange, Uri uri, int userId) {
+                boolean deviceInDemoMode = UserManager.isDeviceInDemoMode(getContext());
                 if (deviceDemoModeUri.equals(uri)) {
-                    if (UserManager.isDeviceInDemoMode(getContext())) {
+                    if (deviceInDemoMode) {
                         createAndSwitchToDemoUser();
                     }
                 }
+                // If device is provisioned and left demo mode - run the cleanup in demo folder
+                if (!deviceInDemoMode && isDeviceProvisioned()) {
+                    // Run on the bg thread to not block the fg thread
+                    BackgroundThread.getHandler().post(new Runnable() {
+                        @Override
+                        public void run() {
+                            if (!deleteDemoFolderContents()) {
+                                Slog.w(TAG, "Failed to delete demo folder contents");
+                            }
+                        }
+                    });
+                }
             }
         };
         cr.registerContentObserver(deviceDemoModeUri, false, deviceDemoModeSettingObserver,
                 UserHandle.USER_SYSTEM);
+        cr.registerContentObserver(deviceProvisionedUri, false, deviceDemoModeSettingObserver,
+                UserHandle.USER_SYSTEM);
+    }
+
+    boolean isDeviceProvisioned() {
+        return Settings.Global.getInt(
+                getContext().getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) != 0;
+    }
+
+    private boolean deleteDemoFolderContents() {
+        File dir = Environment.getDataPreloadsDemoDirectory();
+        Slog.i(TAG, "Deleting contents of " + dir);
+        return FileUtils.deleteContents(dir);
     }
 
     private void registerBroadcastReceiver() {